Content added + script for doing that.

This commit is contained in:
Yann Esposito (Yogsototh) 2010-02-17 13:27:01 +01:00
parent e9014dfbeb
commit 995d7b46f1
125 changed files with 11339 additions and 23 deletions

1
Rules
View file

@ -32,6 +32,7 @@ end
# HTML
compile '/html/*' do
filter :erb
filter :bluecloth
layout 'default'
end
route '/html/*' do

View file

@ -0,0 +1,99 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
title: About
multiTitle:
fr: À propos
en: About
menupriority: 4
-----
## To better know me
![Une photo de moi](/Scratch/img/about/yann1.jpg)
<div class="en">
<desc miscellanious informations>
Name : Yann Esposito ::
Education : Post Ph. D. in Computer Science ::
School : Université de Provence ::
Job : IT at Sophia Antipolis (France) ::
</desc>
</div>
<div class="en">
</div>
<div class="fr">
<desc informations générales>
Nom : Yann Esposito ::
Diplôme : Doctorat d'Informatique ::
École : Université de Provence ::
Emplois : Informaticien à Sophia Antipolis ::
</desc>
</div>
Books I like:
- Goëdel, Escher &amp; Bach *[Hofstadter]*
- On Numbers And Games *[Conway]*
- Baudolino *[Eco]*
Movies I like:
- Eraserhead *[Lynch]*
- Mullholland Drive *[Lynch]*
- Naked Lunch *[Cronenberg]*
- eXistenZ *[Cronenberg]*
[My online bookmarks](http://diigo.com/profile/yogsototh)
newcorps
## In two words
<en>
Im a passionate guy. Passionate about
- Computer Science: [Ive got a post Ph. D. degree in Computer Science](http://yann.esposito.free.fr/recherche.php).
- Programming: [I developed two scientific apps](http://yann.esposito.free.fr/logiciels.php), [two Mac screen savers](/YBlog/Softwares.html),
- Computer Security: [I designed a secure web protocol (similar to TOR)](http://yann.esposito.free.fr/enseignement/rez0.php#projet), [a method to securely remember strong passwords](/YBlog/Computer/Entries/2008/7/30_Easy,_secure_and_portable_password_management_system.html) ([programmed a dashboard widget](/YBlog/YPassword.html) and a shell script to use this method).
</en>
<fr>
Je suis un passioné. Passioné par :
- L'informatique scientifique : [j'ai un doctorat en Informatique](http://yann.esposito.free.fr/recherche.php?lang=fr) ;
- Programmation: j'ai développé [deux applications scientifiques](http://yann.esposito.free.fr/logiciels.php) ainsi que des [éconimiseurs d'écran pour Mac](/YBlog/Softwares.html).
- Sécurité informatique: j'ai modélisé [un protocole sécurisé (similaire à TOR)](http://yann.esposito.free.fr/enseignement/rez0.php#projet), [une méthode pour gérer de façon sécurisé ses mots de passes](/YBlog/Computer/Entries/2008/7/30_Easy,_secure_and_portable_password_management_system.html), un [widget](/YBlog/YPassword.html) et un script shell pour utiliser cette méthode.
</fr>
<en>
But before all, I love to learn. For example, I learned many programming languages: `C`, `C++`, `Objective-C`, `Python`, `Java`, `Perl`, `awk`, `bash`, `zsh`, `LaTeX`, `Metapost`, `camL`... And Ive got the same passion about computer science research, computer security, philosophy and many other things.
</en>
<fr>
Mais avant tout j'adore apprendre. Par exemple, j'ai appris de nombreux langages de programmation:
`C`, `C++`, `Objective-C`, `Python`, `Java`, `Perl`, `awk`, `bash`, `zsh`, `LaTeX`, `Metapost`, `CamL`... Et j'ai la même passion pour la recherche scientifique, la sécurité informatique, la philosophie et encore pas mal d'autres choses.
</fr>
newcorps
## My little story
I had my Ph. D degree in Computer Science in december 2004 at the LIF (Marseille). During the 3 years of my formation, not only I made my research but I also teach computer science and programming to University degree students. I also developed a program to experiment my theoretical results.
Then I had a post Ph. D. Degree position in the Hubert Curien Laboratory at St-Etienne. My mission consisted to develop a scientific application (SEDiL). This application should be used by biologist and should have a simple and nice user interface.
Today I work for AirFrance(c) via Astek. This job need many differents skills, CMS and Web technologies, Perl, JSP, meta-programming...

View file

@ -0,0 +1,504 @@
-----
# Built-in
filters_pre:
- erb
# Custom
title: Curriculum Vitæ
multiTitle:
fr: Curriculum Vitæ
en: Resume
multiSubTitle:
fr: résumé rapide
en: Short Abstract
menupriority: 1
-----
<div style="text-align: center">
<div class="fr">
<a href="/Scratch/files/cv.pdf">
<img class="inside" src="/Scratch/img/about/cv/cv.png" alt="preview cv"/>
&darr; La version pdf
</a>
</div>
<div class="en">
<a href="/Scratch/files/cv_en.pdf">
<img class="inside" src="/Scratch/img/about/cv/cv.png" alt="preview cv"/>
&darr; pdf version
</a>
</div>
</div>
newcorps
<h1>
Professional background
</h1>
<fr>
<desc Expérience professionnelle>
<small>depuis</small> 2007 : Consultant Airfrance, Astek, Sophia Antipolis ::
2006-2007 : Post Doctorat au Laboratoire Hubert Curien, Saint-etienne ::
2004-2006 : ATER, Attaché Temporaire d'Enseignement et de Recherche ::
2001-2004 : Allocataire Moniteur (Étudiant ayant reçu une bourse ministérielle ainsi qu'une bourse permettant d'enseigner en faculté) ::
1999-2000 : Vacataire (enseignant pour DEUG) ::
</desc>
</fr>
<en>
<desc Professionnal background>
from 2007 : Airfrance consultant, Astek, Sophia Antipolis, France ::
2006-2007 : Post PhD in the Laboratory Hubert Curien, Saint-Etienne, France ::
2004-2006 : ATER, (College Degree Teacher) ::
2001-2004 : Allocataire Moniteur (PhD student with a grant + a teach grant) ::
1999-2000 : College degree teaching ::
</desc>
</en>
newcorps
<h1>
Education
</h1>
<fr>
<desc>
2004 : Doctorat en informatique au
<a href="http://www.lif.univ-mrs.fr"><abbr title="Laboratoire d'Informatique Fondamentale">LIF</abbr></a>,
<a href="http://www.up.univ-mrs.fr/"> Université de Provence</a>,
Marseille (France) ::
2001 : DEA d'informatique ::
2000 : Maîtrise d'informatique ::
1999 : Licence d'informatique ::
1998 : DEUG MIAS (Mathématiques) ::
1995 : BAC S option mathématiques ::
</desc>
</fr>
<en>
<desc>
2004 : PhD Degree in computer science in the
<a href="http://www.lif.univ-mrs.fr"><abbr title="Laboratoire d'Informatique Fondamentale">LIF</abbr></a>,
<a href="http://www.up.univ-mrs.fr/"> Université de Provence</a>,
Marseille (France) ::
2001 : DEA in computer science ::
2000 : Maîtrise in computer science ::
1999 : Licence in computer science ::
1998 : DEUG MIAS (Math) ::
1995 : BAC S ::
</desc>
</en>
newcorps
<h1>
Research activities
</h1>
<h4>
Background
</h4>
<en>
<ul>
<li>Machine Learning, </li>
<li>Data Mining, </li>
<li>Grammatical Inference </li>
</ul>
</en>
<fr>
<ul>
<li>Apprentissage automatique ; </li>
<li>Fouille de données ; </li>
<li>Inférence grammaticale </li>
</ul>
</fr>
<h4>
studied objects
</h4>
<en>
<ul>
<li>Markov chains,</li>
<li>Hidden Markov Models, </li>
<li>Multiplicity Automata, </li>
<li>Weighted Transducer, </li>
<li>Tree Weighted Automata, </li>
<li>Tree Edit Distance</li>
</ul>
</en>
<fr>
<ul>
<li>Chaînes de Markov Cachées ; </li>
<li>Automates à multiplicité ; </li>
<li>Transducteurs pondérés ; </li>
<li>Automates d'arbres pondérés ; </li>
<li>Distances d'edition d'arbres</li>
</ul>
</fr>
<h4>
main theoretical results
</h4>
<ul class="long">
<li>
Multiplicity Automata Algorithm which identifie the class of
rational stocastic languages in the limit with probability one,
</li>
<li>
The problem to know whether an MA generates a
probabilistic distribution is undecidable (was left open in
Probabilistic Automata, Azaria Paz, 1977),
</li>
<li>
Algorithm of identification in the limit with
probability one of some subclass of non deterministic <abbr title="Hidden Markov Model">HMM</abbr>
</li>
</ul>
<h2>
Softwares
</h2>
<h4><a href="http://yann.esposito.free.fr/sedil.php">SEDiL</a></h4>
<p>
<a href="http://yann.esposito.free.fr/sedil.php?lang=en">SEDiL</a>:
Software aimed to learn tree edit distances.
Developped in JAVA (11.000 lines with javadoc comments) ;
</p>
<p>
main features:
</p>
<ul class="petit">
<li>
edition operations cost matrix learning,
</li>
<li>
tree or string edit distance computation,
</li>
<li>
tree and strings visualisation,
</li>
<li>
classification using the K nearest
neighbor algorithm,
</li>
<li>
Tree pairs generation,
</li>
</ul>
<h4> <a href="http://yann.esposito.free.fr/dees.php">DEES</a> </h4>
<fr>
<a href="http://yann.esposito.free.fr/dees.php?lang=fr">DEES</a> :
Programme d'inférence d'automates à multiplicité
écrit en C++ (7<small>500</small> lignes, 10<small>000</small> avec les commentaires) ;
</fr>
<en>
<a href="http://yann.esposito.free.fr/dees.php">DEES</a>:
Software of Multiplicity Automata inference
written in C++ (7.500 lines, 10.000 with comments) ;
</en>
<p>
Main features:
</p>
<ul class="petit">
<li>
Multiplicity Automata Inference,
</li>
<li>
Probabilistic Automata Inference
(Hidden Markov Model Inference ; learn Parameters
and <b>Structure</b>),
</li>
<li>
Deterministic Probabilistic Automata Inference
</li>
<li>
Baum Welch Algorithm
(learn parameter of an
<a href="http://en.wikipedia.org/wiki/Hidden_Markov_model">
<abbr title="Hidden Markov Model">HMM</abbr></a> from a sample),
</li>
<li>
<a href="http://www.graphviz.org">GraphViz</a> export,
</li>
<li>
Sample generation from an MA,
</li>
<li> And many others... </li>
</ul>
newcorps
<h1>
Scientific Publications
</h1>
<desc>
International Journal
:
[Fundamenta&nbsp;Informaticæ,&nbsp;2008]
[Pattern&nbsp;Recognition,&nbsp;2004]
::
French Journal
:
[JEDAI&nbsp;2003]
::
International conferences
:
[ECML&nbsp;2008] [ICGI&nbsp;2006] [COLT&nbsp;2006] [COLT&nbsp;2004]
[ICALP&nbsp;2003] [ICGI&nbsp;2002] ::
Conférences nationales : [CAp'06] [CAp'04] [CAp'03] ::
Workshop : [TAGI'05] ::
PhD Thesis
: [Université&nbsp;de&nbsp;Provence&nbsp;2004] ::
</desc>
newcorps
<h1>
Skills
</h1>
<desc>
Computer languages
:
<ul class="strong horizontal">
<li> Perl, </li>
<li> Ruby, </li>
<li> Awk, </li>
<li> Python, </li>
<li> Java, </li>
<li> C++, </li>
<li> C, </li>
<li> Objective-C, </li>
<li> PHP, </li>
<li> scripts shell (zsh et bash), </li>
<li> LaTeX, ConTeXt, Metapost </li>
</ul>
<ul class="horizontal">
<li> CamL </li>
</ul>
::
WEB :
<ul class="horizontal">
<li> HTML, </li>
<li> XHTML, </li>
<li> CSS, </li>
<li> SVG, </li>
<li> PHP, </li>
<li> MySQL, </li>
<li> PostGreSQL </li>
</ul>
::
Computer Networks
:
<ul class="horizontal">
<li> Ethernet, </li>
<li> TCP/IP, </li>
<li> UDP, </li>
<li> DHCP, </li>
<li> DNS, </li>
<li> tcpdump, </li>
<li> ethereal, </li>
<li> VPN </li>
</ul>
::
Security
:
<ul class="horizontal">
<li>
Encryption,
</li>
<li> PGP, GPG, </li>
<li>
Anonymous Networks,
</li>
<li> Network security</li>
</ul>
::
Project Management
:
<ul class="horizontal">
<li> UML, </li>
<li> Merise, </li>
<li> SVN, </li>
<li> CVS </li>
</ul>
::
API
:
<ul class="horizontal">
<li> System V, </li>
<li> POSIX, </li>
<li> STL (C++), </li>
<li> Cocoa (Mac OS X) </li>
</ul>
::
Software
:
<ul class="horizontal">
<li> Entreprise Miner (SAS), </li>
<li> Weka, </li>
<li> Quartz Composer </li>
</ul>
::
Learning Methods
:
<ul class="horizontal small">
<li>
Attribute&nbsp;selection,
</li>
<li>
Naïve&nbsp;Bayes,
</li>
<li>
Decision&nbsp;Tree,
</li>
<li>
K&nbsp;nearest&nbsp;neighboor,
</li>
<li>
Markov&nbsp;Chains (bigrams,&nbsp;trigrams...),
</li>
<li>
Hidden&nbsp;Markov&nbsp;Models (<abbr title="Hidden Markov Model">HMM</abbr>),
</li>
<li>
Neural&nbsp;Network (Multilayer&nbsp;Perceptron),
</li>
<li>
SVM,
</li>
<li>
Boosting
</li>
</ul>
::
</desc>
newcorps
<h1>
Miscellaneous
</h1>
<h4>
Network Project
</h4>
<p>
I have done with
<a href="http://www.lif.univ-mrs.fr/~egodard"> Emmanuel Godard </a>
the conception of an
<a href="http://www.lif.univ-mrs.fr/~esposito/enseignement/rez0.php">
anonymous network protocol (- in french -)</a>.
</p>
<h4>
Mac Softwares
</h4>
<p>
I've done some
<a href="/YBlog/Softwares.html" >Mac sofwares</a>.
Such as screen saver using Quartz Composer, Dashboard widgets and
Objective-C.
</p>
<h4> Web </h4>
<p>
<%= lnkto("You can see details on how I did this website","/blog/nanoc"); %>.
</p>

View file

@ -0,0 +1,38 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
# menu
title: Old
multiTitle:
fr: Autres sites
en: Other stuff
menupriority: 2
-----
<table class="darkimpact">
<tr><td><a href="/Softwares/Welcome.html">&#x27A8; Mac Softwares</a></td></tr>
<tr><td>
<span class="en"><a href="http://yann.esposito.free.fr/recherche.php?css=blue.css&amp;lang=en">&#x27A8; Research</a></span>
<span class="fr"><a href="http://yann.esposito.free.fr/recherche.php?css=blue.css&amp;lang=fr">&#x27A8; Recherche</a></span>
</td></tr>
</table>
## Obsolete
<table class="darkimpact">
<tr><td> <a href="/YBlog">&#x27A8; iWeb</a></td><td><small>&#x271E; 2009</small> </td></tr>
<tr><td> <a href="http://yann.esposito.free.fr">&#x27A8; Student</a></td><td><small>&#x271E; 2007</small> </td></tr>
</table>
newcorps
# Password required
<div class="impact">
<a href="/Perso">&#x27A8; Family &amp; Photos</a></sup>
</div>

View file

@ -0,0 +1,61 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
# menu
title: Technical details
multiTitle:
fr: Détails techniques
en: Technical details
multiSubTitle:
fr: Comment ce site vie.
en: How live this website.
menupriority: 3
-----
This website was completely made from scratch. Most is done using
[Vim](http://www.vim.org) and I generate pages using
[nanoc](http://nanoc.stoneship.org).
<p>
Pictures were done with
<a href="http://inkscape.org">Inkscape</a> and
<a href="http://gimp.org">Gimp</a>.
My website is versionned using the
<a href="http://en.wikipedia.org/wiki/Distributed_Concurrent_Versions_System">
<acronym title="Distributed Concurrent Versions System">DCVS</acronym>
</a>
<a href="http://git-scm.com">Git</a>.
</p>
Blog comments are externalized to <del>[disqus](http://disqus.com)</del> [intense debate](http://intensedebate.com).
All I need is a static web server, no PHP, Java, ASP or CGI.
Main advantages of this method concerns the load
and the security of the server.
<p>
If you didn't understood anything, just remember I used only
<a href="http://en.wikipedia.org/wiki/OpenSource">Opensource</a>
and I mostly all done myself from scratch.
</p>
If you want all the gory details I suggest you to read
my <%= lnkto( "article about nanoc", "/blog/nanoc") %>.

54
content/html/en/blog.html Normal file
View file

@ -0,0 +1,54 @@
-----
filters_pre:
- erb
- bluecloth
- frenchspace
filters_post:
- ytypo
- multilang
- multicorps
- firsthi
# Custom
kind: blog
title: Blog
multiTitle:
fr: Blog
en: Blog
menupriority: 2
-----
<div>
<%= tagCloud %>
</div>
newcorps
## Two word about the content
Here you'll can find mostly technical articles.
Some are just reminder of technical tips.
But some are long and technically detailled articles.
---
I do my best to traduce each page in french and in english.
It not always easy. English is not my natural language.
I make many errors, orthographic, grammatical, typographical&hellip;
<strong> Thanks not to judge me based on these errors! And don't forget content is more important than presentation! </strong>
The first impression I'll let you if we meet in real life should be different from the one I let you based on my website.
I wish you to find something useful or interesting on this website.

View file

@ -0,0 +1,42 @@
-----
# Custom
date: 2008-10-10T16:15:23+02:00
kind: article
title: Nanoc
multiTitle:
fr: nanoc
en: nanoc
multiDescription:
fr: Il ne s'agit pas exactement d'un CMS, mais plutôt d'un *système* de gestion de pages statiques. Voici la présentation de l'outil que j'utilise pour créer ce site.
en: It is not exactly a CMS. But a Framework to generate static web pages. It is a short presentation of the software I use to make this website.
multiSubTitle:
fr: Nanoc pour ce site
en: How I used it for this website
menupriority: 1
-----
What is nanoc?
=============================================
It is not exactly a
<abbr title="Content Management System">CMS</abbr>.
But a Framework to generate static web pages.
You have to program yourself webpages, the code
to generate the menu...
I added feature to make my website multilingual for example
You'll can find many informations on the
[official nanoc website](http://nanoc.stoneship.org).

View file

@ -0,0 +1,138 @@
-----
# Built-in
# Custom
kind: article
title: An ultraviolet test
multiTitle:
en: Ultraviolet
fr: Ultraviolet
multiSubTitle:
fr: les test du plugin ruby
en: ruby plugin tests
-----
<h1>
How to integrate Ultraviolet with nanoc
</h1>
I searched on Internet and I founded some hits, but
which work no more with the last nanoc version.
fr:
J'ai cherché sur Internet et j'ai trouver plusieurs
indications, malheureusement, elles ne sont plus
d'actualité avec la dernière version de nanoc.
:
First, you need to install Ultraviolet:
<div>
<code class="zsh">
#!/usr/bin/zsh
wget http://www.geocities.jp/kosako3/oniguruma/archive/onig-5.9.1.tar.gz
tar zxvf onig-5.9.1.tar.gz
cd onig-5.9.1
./configure
make
sudo make install
sudo gem install ultraviolet
</code>
</div>
newcorps
<en>A ruby code</en><fr>Du code Ruby</fr>
=========================================
<en>A first simple test.</en>
<fr>Voilà le premier exemple simple.</fr>
<div>
<code class="ruby">['1','2','3'].each{ |x| puts 'chiffre '+x }</code>
</div>
<fr>Avec création et téléchargement de fichier.</fr>
<en>With file creation and download.</en>
<div>
<code class="ruby" file="ultraviolet.rb">
class UltraVioletFilter < Nanoc::Filter
identifier :ultraviolet
def run(content)
require 'rio'
require 'rubygems'
require 'uv'
code_rule = %r{(<code class="(.+?)"( file="(.+?)")?>(.+?)<}+%{/code>)}m
content.gsub!(code_rule) do |full|
# original, lang, filename, code = full[0], full[1], full[3], full[4]
original, lang, filename, code = $1, $2, $4, $5
if lang =~ /^(zsh|bash|sh|csh|shell)$/
lang='shell-unix-generic'
end
# Create a plaintext file version for download.
codeprefix=''
codesuffix=''
if filename
webpath = '/Scratch/multi'+@page.path
code_path = [@site.config[:output_dir], webpath, 'code']
url = webpath + 'code/' + filename
if (url == @url)
puts %{erreur de redo : #{url}}
break
end
@url=url
copy_text_to_file(code, filename, code_path)
codeprefix=%{<div class="file"><a href="#{url}"> &#x27A5; #{filename} </a></div><div class="withfile">\n}
codesuffix=%{\n</div>}
end
# Substitute the un-highlighted code with the highlighted code.
codeprefix+Uv.parse(code, "xhtml", lang, false, @site.config[:ultraviolet_theme])+codesuffix
end
content
end
private
def copy_text_to_file(str, fname, dir)
if @page_rep.name == :default then
dest_rio = rio(dir).mkpath
frio = rio(dir, fname).delete
frio << str
puts "\t\twrote file #{dir}/#{fname}"
end
end
end
</code>
</div>
newcorps
<en>A zsh code</en> <fr>Du code zsh</fr>
========================================
<fr>Un exemple en zsh.
J'ai fait en sorte de pouvoir utiliser le tag
<tt>zsh</tt> au lieu du compliqué <tt>shell-unix-generic</tt>
</fr>
<en>A simple zsh example. I made some modification in order to
use the <tt>zsh</tt> tag instead of the too much
complicated <tt>shell-unix-generic</tt></en>
<div>
<code class="zsh">
for fic in **/*(.); do
if [[ ! -x $fic ]]; then
chmod u+x $fic
fi
exec $fic
done
</code>
</div>

View file

@ -0,0 +1,73 @@
-----
# Custom
date: 2009-07-22T16:15:23+02:00
kind: article
title: Better than Grep
multiTitle:
fr: Mieux que grep
en: Better than Grep
multiDescription:
fr: grep avec de la coloration syntaxique sur de multiples fichiers. Pour rechercher une chaine de caractère efficacement dans de nombreux fichiers.
en: grep on multiple files with syntax coloring in one simple command. In order to find efficiently a string within many files.
menupriority: 1
-----
# update
As [Andy Lester](http://www.theworkinggeek.com) told me [`ack`](http://betterthangrep.com) is a simple file you only have to copy in your `~/bin` folder. Now I've got `ack` on my professional server.
Go on [http://betterthangrep.com](http://betterthangrep.com) to download it.
Sincerely, I don't understand `ack` don't become a common command on all UNIX systems. I can no more live without. For me it is as essential as `which` or `find`.
newcorps
Better than grep
=============================================
One of the my main usage of `grep` is
<div>
<code class="zsh">
grep 'pattern' **/*(.)</code>
</div>
Most of time it is enough.
But it is far better with colored output.
`ack-grep` in Ubuntu does that.
As I couldn't install it on my 'Evil Company Server',
I had done one myself in very few lines:
<div>
<code class="zsh" file="ack">
#!/usr/bin/env zsh
(($#<1)) && { print 'usage: ack "regexp"' >&2; exit 1 }
listeFic=( **/*(.) )
autoload zargs
zargs -- $listeFic -- grep $1 | perl -ne 'use Term::ANSIColor;
if (m/([^:]*)(:.*)('$1')(.*)/) {
print color("green").$1;
print color("reset").$2;
print color("black","on_yellow").$3;
print color("reset").$4."\n";
} '
</code>
</div>
For my team and I it is usable enough.
I hope it could help.

View file

@ -0,0 +1,108 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu)
en: Lost Highway demystified (a bit)
multiDescription:
fr: ...Il faut garder à l'esprit qu'il n'existe pas une seule interprétation possible et cohérente du film. Seul David Lynch pourrait donner l'explication complète du film.<br/>Je donne quelques clés aidant à suivre le film sans être complètement perdu.Ces clés devraient vous aider à vous faire votre propre idée du film...
en: ...this movie must be watched knowing you'll cannot resolve the solution. At his best you'll can suggest an interpretation close to the one of David Lynch.<br/>I believe I had found a coherent interpretation which allow to follow the movie without being totally lost. I believed it can give the keys necessary to make its own idea of the movie...
-----
<%= blogimage( 'Lost Highway' , 'intro.jpg' ) %>
Lost Higway is a really good movie. You keep watching it event it seem totally obscure. This is one of the strength of David Lynch.
!!fr!!
La première fois que j'ai vu Lost Highway je me suis senti un peu perdu.
J'en ai alors cherché le sens. Voilà ce que j'ai pu trouver sur Internet :
- Fred passe un pacte avec le diable incarné par l'homme en noir ;
- l'homme mystérieux est une (la) caméra ;
- seule la première histoire est vrai, la suite étant l'imagination de Fred ;
sans compter les multiples avis trouvés sur les forums. Tout cela ne me paraissait pas convaincant.
J'ai alors réussi à trouver deux articles (en anglais) qui proposent de bien meilleures interprétations. Mais aucun des deux ne m'a complètement convaincu :
- le permier est sur [mediacircus](http://www.mediacircus.net/lh.html),
- le second qui développe presque la même interprétation que la première est vraiment très détaillé sur [jasonweb](http://www.jasonsweb.com/LostHighway/main.htm).
Il faut garder à l'esprit qu'il n'existe pas une seule interprétation possible et cohérente du film. Seul David Lynch pourrait donner l'explication complète du film.
Je donne quelques clés aidant à suivre le film **sans être complètement perdu**.
Ces clés devraient vous aider à vous faire votre propre idée du film.
!!!!
!!en!!
The first time I watched Lost Highway, I was a bit lost.
Here some of explanations of Lost Highway I found on the Internet:
- Fred make a pact with the devil incarnated by the *Mysterious Man*,
- *Mysterious Man* is a video camera,
- Just the first part of the story is real. The rest is in the Fred's imagination,
and I don't speak about many point of view found in forums.
I finished to find two good site talking about this movie. But none of them still totally convinced me:
- the first is [mediacircus](http://www.mediacircus.net/lh.html),
- the second which state almost the same interpretation about the movie and explain with even more details is on [jasonweb](http://www.jasonsweb.com/LostHighway/main.htm)
Nonetheless, this movie must be watched knowing you'll cannot resolve the solution. At his best you'll can suggest an interpretation close to the one of David Lynch.
I believe I had found a coherent interpretation which allow to follow the movie **without being totally lost**. I believed it can give the keys necessary to make its own idea of the movie.
!!!!
## The Rorschach test
<%= leftblogimage( 'test de Rorschach','rorschach.gif' ) %>
!!fr!!
À l'instar du protagoniste chacun voit dans ce film ce qu'il a envie d'y voir. Nous pouvons nous y perdre simplement parce que nous pouvons nous perdre dans notre propre esprit. C'est une invitation à la réflexion. Regarder ce film c'est un peu comme passer un test de Rorschach. Qu'y voit-on ? Chacun y met un peu de sa propre personnalité dans l'explication du film.
- Si vous êtes un mystique, vous verrez dans l'homme mystérieux un démon
- si vous êtes plus psychanalytique vous y verrez une partie inconsciente du protagoniste...
En général en essayant d'expliquer ce film, on se perd un peu dans notre pensée. Et souvent on échoue à tout expliquer. Il y a toujours un point qui rend la construction incohérente avec le film. C'est pourquoi rechercher une explication unique est un entreprise vaine.
!!!!
!!en!!
Like the protagonist, everybody see what he want to see in this movie. It is an invitation to think. Watch this movie is a little like watch a Rorschach's test. What do we see in it? Everybody put its own personnality in the interpretation of the movie.
- If you are mystic, you'll see in the mysterious man a devil,
- If you are more psychanalytics, you'll see an inconscient part of the protagonist...
Generally, we stay in this movie and we fail explaining everything. There is almost always a point that don't fit within the interpretation of the movie. This is why trying to find a unique good interpretation of this movie is a mistake.
!!!!
## Interprétation &ne; Explanation
I give an **interpretation** and not an **explanation**. Just to tell my vision of the movie should be very different from yours.
There is certainly many coherent explanations.
I write this post because I believe I had found an interpretation which seems coherent for most of the movie.
<div style="text-align: center">
<span style="font-size: 2em"> <a href="./03_losthighway_1/"><fr>Lire la suite</fr><en>Read more</en></a></span>
</div>

View file

@ -0,0 +1,71 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Les clefs du film
en: Lost Highway demystified (a bit) - Movie's keys
-----
# Movie's keys
<div class="encadre" style="text-align: center">
<strong>
All is in Fred's memory
</strong>
</div>
In a first, it is clear for me, it is not a fantastic movie. If you follow this line, you'll face many problem explaining some scenes.
My hypothesis is the movie describe the Fred's representation of reality.
Each of his tries to escape reality will fail.
Fred had commited an horrible act, a murder, and try to *repair* his memory to accepts it. He'll then create alternative realities.
- In a first time he kills his wife (Renee) because he believes she cheated at him.
- In the second part, he's weaker and will be manipulated by the blond equivalent of Renee to kill Dick Laurent.
- In a third part, he kills Dick Laurent
## Why this interpretation can be valid?
Because of the dialog at the begining of the movie. Cops ask Fred if he's own a video camera:
> - &ndash; Do you own a video camera?
> - &ndash; No, Fred hates them.
> - &ndash; I like to remember things my own way.
> - &ndash; What do you mean by that?
> - &ndash; How I remember them, not necessarily the way they happened.
!!fr!!
Ce que l'on peut traduire approximativement par :
> - &ndash; Avez-vous une caméra ?
> - &ndash; Non, Fred les détestes.
> - &ndash; J'aime me rappeler les choses à ma façon.
> - &ndash; Qu'entendez-vous par là ?
> - &ndash; Je me rapelle des choses pas nécessairement comme elles se sont passées.
!!!!
Then, what we see is not reality but the Fred's perception. Fred is the God of the reality we see. This is why some God/Devil interpretation of the movie works not so bad.

View file

@ -0,0 +1,35 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 2
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Qui est l'homme mystérieux ?
en: Lost Highway demystified (a bit) - Who is the mystery man?
-----
## Who is the mysterious man?
<%= leftblogimage( "l'homme mystérieux" , "mysteryman.jpg" ) %>
Who's this mysterious man? He tells Fred it's him who invited him in his house. He's present at the party and in the house of Fred in the same time. Eyes wide open, looking everything Fred's doing?
It's a key of the movie. In my humble opinion, I believe it represents the bad part of Fred. Certainly jalousy. If I was catholic, I'll said he's Satan. He observe, film but don't act. He helps Fred to kill Dick Laurent.
Fred had let him enter and cannot let him go.
As _Iago_ of Shakespeare is imprisonned by its own jalousy.
The Mysterious Man help Fred doing the acts of violence.
It also force Fred to remember the reality.
When he makes love to his wife (Renee), he sees the face of the Mysterious Man instead of his wife's face. In reality, it's the same person for Fred. It should be her who's the origin of his interior badness.

View file

@ -0,0 +1,36 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 3
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Qui filme et dépose les cassettes ?
en: Lost Highway demystified (a bit) - Who's at the origin of the video tapes?
-----
## Who's at the origin of the video tapes?
Certainly it's the mysterious man (Fred himself) who makes them.
Their reason should be:
!!fr!!
+ Rappeler à Fred la réalité. D'après Fred les cassettes video correspondent à la réalité. Il a beau essayer de se cacher la réalité, les cassettes finissent par aller jusqu'au bout et il se voit en train de tuer Renée.
+ La cassette peut aussi faire référence aux cassettes de films pornographique dans laquelle Renée a peut-être tournée dans la réalité ?
!!!!
!!en!!
+ Remember the reality to Fred. From Fred point-of-view, video tapes are the reality. He tries to forget reality. But, finally, the video tapes go to the end: the murder of his wife.
+ It may also be a reference to pornographic video tapes, made by Renee.
!!!!

View file

@ -0,0 +1,73 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 4
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Que s'est-il vraiment passé ?
en: Lost Highway demystified (a bit) - What really happened?
multiDescription:
-----
## What really happened?
There is many possibilities here. But we have many indices. Here is a supposition.
### #1 Hypothesis
!!fr!!
Je dirais que le protagoniste est un garagiste qui est tombé amoureux d'une actrice porno. Il l'a certainement vu la première fois accompagnant le fameux Dick Laurent. Voyant qu'il ne peut pas l'avoir pour lui, fou de jalousie il tue Dick Laurent dans un motel où celui-ci à couché avec Renée.
On a la liberté de décider s'il a vraiment tué la femme ou pas.
Dans ma première vision du film, j'avais envie de dire qu'il ne la tue pas. Mais qu'une fois le meurtre commis, il va chez elle, sonne pour lui annoncer la mort de Dick Laurent. Il a alors juste le temps de s'enfuir, la police à ses trousses.
!!!!
!!en!!
The protagonist is a garagist fallen in love with a porno actress. He believe the producer is the bad guy who go again his will. Then he kills Dick Laurent.
!!!!
### #2 Hypothesis
He was really married, he had killed his wife. The the remorse let him create an alternate self, which live in a kind of perfect world. But after the time pass, his obsession about the murder came again. And nobody could know if he had killed Andy or not.
## which one then?
The second hypothesis seems better. We can make much more interpretation with it. It explain in most part the strange phone call from Dick Laurent to Pete.
But the first hypothesis remain coherent. And, we should probably make an in depth explanantion using the first hypothesis. And I'm not sure it would be better.
One of the strength of this movie is to understand there is many other coherent hypothesis. It is an expression of the [Rashomon effect](http://en.wikipedia.org/wiki/Rashomon_effect). Many different persons could describe in a coherent manner what they saw. But each description contradicts the others.
newcorps
## Conclusion
There is much to tell about this movie. But I believe I put all essential keys here. It is a proof this movie is not a random one.
I believe it is essential to remember the "test of Rorschach effet" when watching this movie.
I'd like to know or opinion ; is my interpration wrong?

View file

@ -0,0 +1,48 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-15T11:00:00+02:00
title: DRM are EVIL
multiTitle:
fr: Les protections anti-copies sont LE MAL
en: DRM are EVIL
multiDescription:
fr: Les protections nuisent à l'utilisateur qui paye (+1)
en: DRM are bad (+1)
tags:
- drm
- protection
- iTunes
- Apple
-----
# DRM are EVIL (+1)
My wife bought about 500€ (at least) of TV Shows on iTunes. She bought the first season of Battlestar Gallactica in english (she notified the language after the dowload). DRM make it impossible to play it with french sub-titles.
<div class="encadre">
<p style="text-align: center; font-size: 5em"><strong>WTF?</strong></p>
</div>
Result, my wife would never buy any TV show on iTunes. She don't like DVD because it is not as easy to buy and to use than to simply download episodes.
<div class="encadre">
Therefore far less money for you EVIL Copyrighter!!!!!
</div>
My wife won't see these episodes.<br/>
This is a <strong>'LOSE-LOSE'</strong> cooperation.

View file

@ -0,0 +1,53 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-17T14:00:00+02:00
title: Git remote branch creation
multiTitle:
fr: Création de branches avec Git
en: Git branch Creation
multiDescription:
fr: J'utilise Git pour synchroniser des projets personnels. C'est pourquoi quand je crée une branche locale je souhaite quasiment toujours qu'elle soit aussi créée en <em>externe</em> (remote).<br/>Voici le script que j'utilise pour accomplir cette tâche ...
en: I use git to synchronize personnal projects. Therefore, most of time, when I create a local branch I want it to be created remotely.<br/>Here is the script I use to achieve that&hellip;
tags:
- git
- branch
- local
- remote
-----
## easiest remote Git branch creation
I use git simply to synchronize stuff for personnal projects.
Therefore, when I create a local branch I want most of time this
branch to be created remotely.
Here is the script I use to achieve that:
<div>
<code class="zsh" file="git-create-new-branch.sh">
#!/usr/bin/env zsh
if (($#<1)); then
print -- "usage: $0:t branch_name" >&2
exit 1
fi
branch=$1
git br ${branch}
git co ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
</code>
</div>
Of course, I suppose <code>origin</code> is already configured.

View file

@ -0,0 +1,208 @@
-----
# Custom
# isHidden: true
menupriority: 1
kind: article
date: 2009-08-18T14:44:31+02:00
title: Git for self
multiTitle:
fr: Git en solo
en: Git for self
multiDescription:
fr: J'utilise Git pour des projets personnels gérés à partir de plusieurs oridinateurs. Voici comment concilier les avantages de Git avec un workflow proche de celui de SVN.
en: I use Git for personnal projects on many differents computers. Here is how to use almost the SVN workflow with all advantages of Git.
tags:
- git
- svn
- workflow
-----
<%= blogimage("central architecture","central_architecture.png") %>
I use [Git](http://www.git-scm.org/) to manage my personnal projects.
I have a centralized repository which all my computer should synchronize with.
Unfortunately I didn't find clearly what I needed on the official Git documentation.
In two words, if you want to use an SVN workflow with Git (and all its advantages) here is how to proceed.
newcorps
## Initialisation
Suppose I've got a directory on my local computer containing a project I want to manage via Git. Here what to do:
<div>
<code class="zsh">
cd to/project/directory/
git init
git add
git commit
</code>
</div>
Now all files in the <code>to/project/directory/</code> are versionned.
If you want not to follow some just edit the file <code>.gitignore</code>
fr:Maintenant tous les fichiers du répertoire <code>to/project/directory/</code> sont *versionnés*. Si vous voulez ignorer certains fichiers il suffit de modifier le fichier <code>.gitignore</code>.
for example mine is:
<div>
<code class="zsh">
*.swp
.DS_Store
ikog.py.bak
output/Scratch/assets
output/Scratch/en
output/Scratch/fr
output/Scratch/multi
</code>
</div>
Next, you want to put your project on a safe place on the net.
<div>
<code class="zsh">
git clone --bare . protocol://url/of/the/repository
</code>
</div>
Now on any computer you can do:
<div>
<code class="zsh">
git clone protocol://url/of/the/repository local_directory
</code>
</div>
and <code>local_directory</code> will contain an up-to-date project.
<div class="encadre"><em>
You should make this operation also on the computer used to create the repository. Just to verify all will be okay.
</em>
</div>
newcorps
## The workflow
To resume you now have one repository on the Internet, and one or many computer associated with it. Now, what you want is to synchronize everything.
Before begining your work, the first thing to do is to get all modification from the Internet to your local host:
<div>
<code class="zsh">
git pull
</code>
</div>
After that you can do (many times):
<div>
<code class="zsh">
hack, hack, hack...
git add some files
git commit
</code>
</div>
When you want your local modification to be on the Internet just do a simple:
<div>
<code class="zsh">
git push
</code>
</div>
All should be ok.
If you have some trouble with the <code>push</code> and <code>pull</code> verify your <code>.git/config</code> file ; it should contain the following lines:
<div>
<code class="zsh">
...
[remote "origin"]
url = protocol://url/of/the/repository
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
...
</code>
</div>
## Branches Synchronisation
Well, now, all seems ok, but you have to worry about two little things. Git is all about decentralisation and branches. It is very easy to manage one branch, or many branches on the same host. But synchronize branches on many hosts is not a natural operation.
This is why I created two simple scripts to automate this. One for creating a branch locally and remotely. And one to get remotely created branched on your local host.
Then when you want to create a new branch (locally and remotely) ; you simply have to do a:
<div><code class="zsh">git-create-new-branch branch_name</code></div>
and when you are on another computer and want to get locally all the remote branches you execute:
<div><code class="zsh">git-get-remote-branches</code></div>
Here are the code of theese two scripts:
<div>
<code class="zsh" file="git-create-new-branch">
#!/usr/bin/env zsh
if (($#<1)); then
print -- "usage: $0:t branch_name" >&2
exit 1
fi
branch=$1
git br ${branch}
git co ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
</code>
</div>
<div>
<code class="zsh" file="git-get-remote-branches">
#!/usr/bin/env zsh
# recup branches not on local
localbranches=( $(git br | sed 's/\*/ /') )
remoteMissingBranches=( $(git br -r | \
egrep -v "origin/HEAD|(${(j:|:)localbranches})" ) )
for br in $remoteMissingBranches; do
branch=${br#origin/}
print "get remote branch $branch"
git br ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
done
</code>
</div>

View file

@ -0,0 +1,34 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-06T17:59:16+02:00
title: Screensaver compilation option for Snow Leopard<sub>&copy;</sub>
multiTitle:
fr: Screensaver compilation option for Snow Leopard<small>&copy;</small>
en: Screensaver compilation option for Snow Leopard<small>&copy;</small>
multiDescription:
fr: no description.
en: no description.
tags:
- screensaver
- Apple
- mac
- Xcode
-----
# How to recompile your screensaver to be Snow Leopard(c) compatible
I upgraded to Mac OS X 10.6 Snow Leopard(c), and my [YClock](/YBlog/YClock.html) screensaver didn't work on it. After searching on google, the problem seems to be just a recompilation away.
Unfortunately, event recompiling it in 64 bit it didn't work either.
After a bit more research (thanks to [ElectricSheep](http://community.electricsheep.org/node/236) ).
I discovered the good parameters for compilation.
<%= blogimage("XCode configuration","xcodeConfig.png") %>
For now I didn't compiled it to work also on Tiger and Leopard. I don't know XCode enought to know how to make the Garbage collector to be disabled on 32 bits version and enabled on 64 bits version.
It was a bit difficult to discover these informations. Hope this post helped someone.

View file

@ -0,0 +1,92 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-07T20:25:56+02:00
title: Configure ssh to listen the port 443 on Snow Leopard
multiTitle:
fr: ssh to Listen 443 on Snow Leopard
en: ssh to Listen 443 on Snow Leopard
multiDescription:
fr: no description.
en: no description.
tags:
- Apple
- mac
- ssh
- security
-----
# Surf everywhere as if you were at home
In order to bypass *evil* company firewall and to surf safely on unsafe <sc>wifi</sc>. I keep an ssh server listening on the port 443.
Then from my laptop or my local computer I just have to launch the marvelous
<div>
<code class="zsh">
ssh -p 443 -D 9050 username@host
</code>
</div>
and a local <sc>socks</sc> proxy listening on port 9050 is launched. The <sc>socks</sc> proxy will transfer local requests via the ssh tunnel. Therefore I can surf locally as if I was on my own computer. I can put password and card number without fear the local <sc>wifi</sc> network to be *sniffed*. I simply need to configure my web browser to user the <sc>socks</sc> proxy on localhost and port 9050.
I get this information from [this post](http://dltj.org/article/ssh-as-socks-proxy/).
# Ssh and Snow Leopard(c)
Here I don't want to talk about how great <sc>socks</sc> proxy via ssh tunneling is but how to configure my local server.
I have Mac with Snow Leopard(c) at home and it is far from enough to modify the `/etc/sshd.config` file. The system use `launchd` to launch starting daemons.
I posted the question on [Apple Discussions](discussions.apple.com) in this [discussion thread](http://discussions.apple.com/thread.jspa?messageID=10141032). Thanks to all guys who helped me. And the solution is:
Create the file <tt>/Library/LaunchDaemons/ssh-443.plist</tt> containing:
<div>
<code class="xml" file="ssh-443.plist">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>local.sshd</string>
<key>Program</key>
<string>/usr/libexec/sshd-keygen-wrapper</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/sshd</string>
<string>-i</string>
</array>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>https</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>SHAuthorizationRight</key>
<string>system.preferences</string>
</dict>
</plist>
</code>
</div>
It is a copy of `/System/Library/LaunchDaemons/ssh.plist` with some modifications:
- the `SockServiceName` from `ssh` to `https`.
- the `Label` from `com.openssh.sshd` to something not existing as `local.sshd`
Tell me if it was helpfull or if you have any question.

View file

@ -0,0 +1,32 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-11T14:27:09+02:00
title: Why I didn't keep whos.amung.us
multiTitle:
fr: Why I didn't keep whos.amung.us
en: Why I didn't keep whos.amung.us
multiDescription:
fr: no description.
en: no description.
tags:
- analytics
- web
-----
I changed from [whos.amung.us](http://whos.amung.us) to [Google Analytics](http://www.google.com/analytics).
Most of time I prefer not to use the same product as everybody and try some new. But this time I believe whosamung.us had too much ads on the page. I had to put their image on my website and they only give then number of user currently on the website, not the number of visits.
This is why I now use google analytics. The only problem, remains for pages with no javascript support.
Then for now:
<div class="encadre">
Theorem:<br/>
<center>
Google Analytics <big><strong>&gt;</strong></big> Who's Amung Us
<center></div>

View file

@ -0,0 +1,283 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-11T14:35:35+02:00
title: Synchronize Custom WebSite with mobileMe
multiTitle:
fr: Héberger son site personnel sur le site mobileMe
en: Synchronize Custom WebSite with mobileMe
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- mobileme
- WebDav
- synchronisation
- zsh
- script
-----
# Update <small>(2009/10/28)</small>
I [updated my script](/Scratch/multi/blog/2009-10-28-custom-website-synchronisation-with-mobileme--2-) which is now incremental. Since the writing of this article, Apple(c) had made many efforts about the bandwith of its European servers.
newcorps
# WebDav terror
I live in France and iDisk upload is just terrible. Upload speed remind me the old 56k modem. Most operations such as list the content of a directory take at least 30 seconds (for 15 elements). Renaming a directory fail most of time.
Apple(c) use a WebDav server to host files. It works on port 80 (like http). I realized WebDav via https work better (2 to 3 times faster with far less errors). But even https is too slow.
I upload from my Mac and sometimes from an Ubuntu PC (iDisk mounted with webdavfs).
# Synchronize safely the website
Here is the script I use in order to synchronize my website with maximum safety. It try each operations until it works.
The idea are:
- Synchroniser vers un répertoire temporaire sur le serveur distant, puis "swapper" les noms des répertoires. Ainsi le site ne reste indisponible que le temps du "swap" du nom des deux répertoires.
- Réitérer toutes les opérations jusqu'à ce qu'elle aient réussi (par exemple pour le renommage)
For now I use `rsync` which in fact is no more efficient than a simple `cp` with WebDav. And I should use a method to keep track of elements who have changed. before the publication.
In fact when I'm on a Mac, I use [Transmit](http://www.panic.com/transmit) which is very cool and far more efficient than the Finder to synchronize files. After the synchronization, I swap the directories.
My script take a `-s` option in order to make only the swap option. It also take a `-a` in order to put the new `index.html` which should point to the new homepage (not the iWeb one).
In order to keep this script working for you, just modify the username by yours (the value of the `mobileMeUser`).
<div class="fr">
<code class="zsh" file="publish">
#!/usr/bin/env zsh
# Script synchronisant le site sur me.com
# normalement, le site est indisponible le moins de temps possible
# le temps de deux renommages de répertoire
mobileMeUser="yann.esposito"
siteName="siteName"
# Depending of my hostname the
if [[ $(hostname) == 'ubuntu' ]]; then
iDisk='/mnt/iDisk'
else
iDisk="/Volumes/$mobileMeUser"
fi
root=$HOME/Sites/$siteName
destRep=$iDisk/Web/Sites/$siteName
[[ ! -d $root ]] && {
print -- "$root n'existe pas ; vérifiez la conf" >&2;
exit 1
}
[[ ! -d $destRep ]] && {
print -- "$destRep n'existe pas, veuillez remonter le FS" >&2;
exit 1
}
if [[ $1 == '-h' ]]; then
print -- "usage: $0:h [-h|-a|-s]"
print -- " -a sychronise aussi l'index"
print -- " -h affiche l'aide"
print -- " -s swappe simplement les répertoires"
fi
if [[ $1 == '-a' ]]; then
print -- "Synchronisation de l'index (${destRep:h})"
rsync -av $root/index.html ${destRep:h}/index.html
fi
print -- "Root = $root"
print -- "Dest = $destRep"
if [[ ! $1 = '-s' ]]; then
[[ ! -d $destRep.tmp ]] && mkdir $destRep.tmp
print -P -- "%B[Sync => tmp]%b"
result=1
essai=1
while (( $result > 0 )); do
rsync -arv $root/Scratch/ $destRep.tmp
result=$?
if (( $result > 0 )); then
print -P -- "%BEchec du rsync%b (essai n°$essai)" >&2
fi
((essai++))
done
fi
# SWAP
print -P -- "%B[Swap des Répertoires (tmp <=> target)]%b"
essai=1
while [[ -e $destRep.old ]]; do
print -n -- "suppression de $destRep.old"
if ((essai>1)); then
print " (essai n°$essai)"
else
print
fi
((essai++))
\rm -rf $destRep.old
done
print -- " renommage du repertoire sandard vers le .old"
essai=1
while [[ -e $destRep ]]; do
mv $destRep $destRep.old
(($?)) && print -- "Echec du renommage (essai n°$essai)" >&2
((essai++))
done
print -- " renommage du repertoire tmp (nouveau) vers le standard"
print -P -- " %BSite Indisponible%b $(date)"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.tmp $destRep
(($?)) && print -P -- "%B[Site Indisponible]%b(essai n°$essai) Echec du renommage (mv $destRep.tmp $destRep)" >&2
((essai++))
done
print -P -- "\t===\t%BSITE DISPONIBLE%b\t==="
print -- " renommage du repertoire old vers le tmp"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.old $destRep.tmp
(($?)) && print -P -- "Echec du renommage n°$essai" >&2
((essai++))
done
print -P -- " publication terminée"
</code>
</div>
<div class="en">
<code class="zsh" file="publish">
#!/usr/bin/env zsh
# Author: Yann Esposito
# Mail: yann.esposito@gmail.com
# Synchronize with "mobileMe" iDisk account.
mobileMeUser="firstname.lastname"
siteName="siteName"
# Depending of my hostname the
if [[ $(hostname) == 'ubuntu' ]]; then
iDisk='/mnt/iDisk'
else
iDisk="/Volumes/$mobileMeUser"
fi
root=$HOME/Sites/$siteName
destRep=$iDisk/Web/Sites/$siteName
[[ ! -d $root ]] && {
print -- "$root does not exist ; please verify the configuration ($0)" >&2;
exit 1
}
[[ ! -d $destRep ]] && {
print -- "$destRep does not exist, please mount the filesystem" >&2;
exit 1
}
if [[ $1 == '-h' ]]; then
print -- "usage: $0:h [-h|-a|-s]"
print -- " -a sychronize primary index"
print -- " -h show this help"
print -- " -s only swap directories"
fi
if [[ $1 == '-a' ]]; then
print -- "Index synchronisation (${destRep:h})"
rsync -av $root/index.html ${destRep:h}/index.html
fi
print -- "Root = $root"
print -- "Dest = $destRep"
if [[ ! $1 = '-s' ]]; then
[[ ! -d $destRep.tmp ]] && mkdir $destRep.tmp
print -P -- "%B[Sync => tmp]%b"
result=1
essai=1
while (( $result > 0 )); do
rsync -arv $root/Scratch/ $destRep.tmp
result=$?
if (( $result > 0 )); then
print -P -- "%Brsync failed%b (try n°$essai)" >&2
fi
((essai++))
done
fi
# SWAP
print -P -- "%B[Directory Swap (tmp <=> target)]%b"
essai=1
while [[ -e $destRep.old ]]; do
print -n -- "remove $destRep.old"
if ((essai>1)); then
print " (try n°$essai)"
else
print
fi
((essai++))
\rm -rf $destRep.old
done
print -- " renommage du repertoire sandard vers le .old"
essai=1
while [[ -e $destRep ]]; do
mv $destRep $destRep.old
(($?)) && print -- "Failed to rename (try n°$essai)" >&2
((essai++))
done
print -- " renaming folder tmp (new) to the standard one"
print -P -- " %BThe WebSite isn't working%b $(date)"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.tmp $destRep
(($?)) && print -P -- "%B[WebSite not working]%b(try n°$essai) Failed to rename (mv $destRep.tmp $destRep)" >&2
((essai++))
done
print -P -- "\t===\t%BWEBSITE SHOULD WORK NOW%b\t==="
print -- " rename old folder to tmp folder"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.old $destRep.tmp
(($?)) && print -P -- "Failed to rename n°$essai" >&2
((essai++))
done
print -P -- " Publish terminated"
</code>
</div>

View file

@ -0,0 +1,84 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-17T23:27:54+02:00
title: Load Disqus Asynchronously
multiTitle:
fr: Load Disqus Asynchronously
en: Load Disqus Asynchronously
multiDescription:
fr: pas de description.
en: no description.
tags:
- disqus
- web
- javascript
- intense debate
- comments
-----
# Update
In fact this method works for old threads. But it fails to create new post threads. This is why I tried and be conquered by [intensedebate](http://intensedebate.com), as you can see in the bottom of this page.
Remark I didn't have any comment on my blog when I switched. Therefore my lack of influence was a good thing :-).
newcorps
Before begining, I must state that I **love** Disqus.
I know there is a similar blog entry at [Trephine.org](http://trephine.org/t/index.php?title=Site_improvements_-_fighting_with_Disqus). Here I just add a straight and easy way to load disqus asynchronously using jQuery.
I also know there is a jQuery plugin to make just that. Unfortunately I had some issue with CSS.
*Now let's begin.*
newcorps
# Why?
Why should I want to load the disqus javascript asynchronously?
- Efficiency: I don't want my page to wait the complete execution of disqus script to load.
- More independance: when disqus is down, my page is blocked!
newcorps
# How?
I give a solution with jQuery, but I'm certain it will work with many other js library.
### Javascript
replace:
<div>
<code class="javascript">
<script type="text/javascript" src="http://disqus.com/forums/YOUR_DISQUS_ID/embed.js"></script>
</code>
</div>
by
<div>
<code class="javascript">
window.disqus_no_style=true;
$(document).ready(function(){
$.getScript("http://disqus.com/forums/YOUR_DISQUS_ID/embed.js");
});
</code>
</div>
If you forget the `window.disqus_no_style=true;` then your page will be blank. Simply because without this option, the javascript use a `document.write` action after the document was closed, which cause a complete erasing of it.
### CSS
But with this option you still need to provide a CSS. This is why you have to copy the css code from the `embed.js` file and rewrite it in a CSS file. You can [download the CSS](/Scratch/multi/blog/11_Load_Disqus_Asynchronously/code/original_disqus.css) I obtained.
---
Now it's done. I believe all should be fine but I just finished the manip for my own site only 1 hour ago. Therefore there should be some error, tell me if it is the case.

View file

@ -0,0 +1,69 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-28T10:58:20+02:00
title: Disqus versus Intense Debate (Why I switched)
multiTitle:
fr: Disqus contre Intense Debate (pourquois j'ai changé)
en: Disqus versus Intense Debate (Why I switched)
multiDescription:
fr: pas de description.
en: no description.
tags:
- disqus
- intense debate
- web
- blog
-----
# [Disqus](http://disqus.com/) *vs.* [Intense Debate](http://intensedebate.com/)
I made a blog entry about how I tried to integrate [Disqus](http://disqus.com). I had to wait Disqus comment to be displayed before loading correctly my page. This is why I tried to include it in a "non-blocking" way. Unfortunately, I had [difficulties to make it works correctly](/Scratch/multi/blog/11_Load_Disqus_Asynchronously/).
Furthermore, it was not trivial to make comment to be shared between multiple version of the same page (each page has three differents representations, one for each language and one more for the multi-language version).
I am a bit sad to quit [Disqus](http://disqus.com) because I must confess [giannii](http://giannii.com) had helped me has efficiently as he could. But the problem I had with disqus are inherent to some design choice not simply technical ones.
During the time I tried to integrate [Disqus](http://disqus.com/) I never tried [Intense Debate](http://intensedebate.com). Now that I have tried, i must confess it does exactly what I needed.
In order to make it fully asynchronous, you've just to download their common js and replace the following line:
<div>
<code class="javascript">
document.getElementsByTagName("head")[0].appendChild(commentScript);
</code>
</div>
by:
<div>
<code class="javascript">
$(document).ready( function() {
document.getElementsByTagName("head")[0].appendChild(commentScript);
});
</code>
</div>
## And the Winner is: [Intense Debate](http://intensedebate.com/)
To conclude, main advantages (for me) of [Intense Debate](http://intensedebate.com/) over [Disqus](http://disqus.com/):
- Load Asynchronously ; don't block my website
- Add for free buttons like "share to any" and load them **asynchronously**.
Voilà.

View file

@ -0,0 +1,266 @@
-----
filters_pre:
- erb
- bluecloth
- frenchspace
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-23T13:18:26+02:00
title: jQuery Tag Cloud
multiTitle:
fr: jQuery Tag Cloud
en: Simple jQuery Tag Cloud
multiDescription:
fr: pas de description.
en: no description.
tags:
- jquery
- javascript
- web
- ruby
-----
Here is how I done the tag cloud of my blog. It is done mostly in jQuery.
All my site is static and pages are generated with [nanoc](nanoc.stoneship.org).
It is (in my humble opinion) the modern geek way to make a website.
This is why I'll give only a Ruby Generator, not a full javascript generator.
But you can easily translate from Ruby to Javascript.
Here is what you should obtain:
newcorps
<div>
<%= tagCloud %>
</div>
newcorps
# jQuery
Here is the simple jQuery code:
<div>
<code class="javascript">
$(document).ready( function(){$('.list').hide();} );
function tagSelected(id) {
$('.list').hide();
$('#'+id).fadeIn();
$('.tag.selected').removeClass('selected');
$('#tag_'+id).addClass('selected');
}
</code>
</div>
This code will hide all the div containing links to articles containing the tag. And create a function do show the div containing the tag.
For each tag I create a span element:
<div>
<code class="html">
<span style="font-size: 1.0em;"
class="tag"
onClick="tagSelected('[TAG]')"
id="tag_[TAG]">
[TAG]
</span>
</code>
</div>
and a div containing links associtated to this tag:
<div>
<code class="html">
<div id="[TAG]">
<h4>[TAG]</h4>
<ul>
<li> LINK 1 </li>
<li> LINK 2 </li>
</ul>
</div>
</code>
</div>
newcorps
# nanoc
Here is how I generate this using nanoc 2.
If you want to make it fully jQuery one, it shouldn't be
too difficult, to use my ruby code and translate it into javascript.
In a first time `tags` correpond of the list of all tags.
<div>
<code class="ruby">
def tags
return @page.tags.join(', ')
end
</code>
</div>
A function to create a data structure associating to each
tag its occurence.
<div>
<code class="ruby">
# generate an hash tag => number of occurence of tag
def tagNumber
tags={}
@pages.each do |p|
if p.tags.nil?
next
end
p.tags.each do |t|
if tags[t]
tags[t]+=1
else
tags[t]=1
end
end
end
return tags
end
</code>
</div>
I also need a data structure who associate to each
tag a list of pages (at least url and title).
<div>
<code class="ruby">
# generate an hash tag => [ page1, page2 ... ]
def tagRefs
tagLinks={}
@pages.each do |p|
if p.tags.nil?
next
end
p.tags.each do |t|
if tagLinks[t].nil?
tagLinks[t]=[ p ]
else
tagLinks[t] <<= p
end
end
end
return tagLinks
end
</code>
</div>
Calculate the real size of each tag to be displayed.
I choosen not to use the full range of size for all the tag. Because if no
tag has more than `n` (here 10) occurences, then it doesn't deserve to be
of the maximal size.
<div>
<code class="ruby">
def tagRealSize
tags=tagNumber
max=tags.values.max
min=tags.values.min
# size in CSS em.
minSize=1.0
maxSize=2.5
tagSize={}
tags.each do |t,n|
if ( max == min )
tagSize[t]=minSize
else
# normalized value between 0 and 1
# if not tag appear more than 10 times,
# then it cannot have the maximal size
tagSize[t]=[ ( n - min + 0.0 ) / ( max - min ) ,
(n - min) / 10.0 ].min
# from normalized size to real size
tagSize[t]=( tagSize[t] ) * (maxSize - minSize) + minSize
end
end
return tagSize
end
</code>
</div>
Finaly a function to generate the XHTML/jQuery code
<div>
<code class="ruby">
# generate an XHTML/jQuery code for tag cloud
def tagCloud
tagLinks=tagRefs
tagSize=tagRealSize
# begin to write the code
tagCloud=%{<script type="text/javascript">
$(document).ready( function(){$('.list').hide();} );
function tagSelected(id) {
$('.list').hide();
$('#'+id).fadeIn();
$('.tag.selected').removeClass('selected');
$('#tag_'+id).addClass('selected');
}
</script><div id="tagcloud">}
# Creation of the tags <span>
tagSize.sort{|a,b| a[0].downcase <=> b[0].downcase}.each do |t,s|
tag_in_id=t.gsub(/\W/,'_')
# HTML protected version of the tag
# for example, replace ' ' by '&nbsp;'
protected=t.gsub(/&/,'&amp;').gsub(/ /,'&nbsp;').gsub(/</,'&lt;').gsub(/>/,'&gt;')
tagCloud <<= %{
<span style="font-size: #{s}em;"
class="tag"
onClick="tagSelected('#{tag_in_id}')"
id="tag_#{tag_in_id}">
#{protected}
</span> }
end
tagCloud <<= %{</div><div id="hiddenDivs" >}
# Creation of the divs containing links associated to a tag.
tagLinks.each do |t,l|
tag_in_id=t.gsub(/\W/,'_')
tagCloud <<= %{
<div id="#{tag_in_id}" class="list">
<h4>#{t}</h4><ul>}
# generate the link list
l.each do |p|
tagCloud <<= %{<li><a href="#{p.path}">#{p.title}</a></li>}
end
tagCloud <<= %{</ul></div>}
end
tagCloud <<= %{</div>}
return tagCloud # yeah I know it is not necessary
end
</code>
</div>
You can [download the complete file](/Scratch/multi/blog/2009-09-jQuery-Tag-Cloud/code/tag.rb) to put in your 'lib' directory. **Beware, it is a nanoc 2 version, you'll have to make some small changes like replace `@pages` by `@items` to be nanoc3 compatible.**
Of course to be nice you need the associated CSS
<div>
<code class="css">
// Change the color when mouse over
.tag:hover {
color: #cc0000; }
// Change the color when tag selected
.tag.selected {
color: #6c0000; }
// a bit of space and pointer cursor
.tag {
cursor: pointer;
margin-left: .5em;
margin-right: .5em; }
</code>
</div>
That's all folks.

View file

@ -0,0 +1,101 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-22T22:13:25+02:00
title: replace all except some part
multiTitle:
fr: replace all except some part
en: replace all except some part
multiDescription:
fr: pas de description.
en: no description.
tags:
- ruby
- regexp
- regular expression
-----
My problem is simple:
I want to filter a text except some part of it. I can match easily the part I don't want to be filtered. For example
<div>
<code class="html">
...
text
...
BEGIN not to filter
...
text
...
END not to filter
...
text
...
</code>
</div>
I searched a better way to do that, but the best I can do is using `split` and `scan`.
<div>
<code class="ruby">
def allExceptCode( f, content )
regexp=/<code[^>]*>.*?<\/code>/m
tmp=""
mem=[]
content.scan(regexp).each do |c|
mem <<= c
end
i=0
content.split(regexp).each do |x|
tmp <<= send(f,x)
if not mem[i].nil?
tmp <<= mem[i]
i+=1
end
end
tmp
end
</code>
</div>
An usage is:
<div>
<code class="ruby">
def filter(content)
content.gsub(/e/,'X')
end
...
allExceptCode(:filter, content)
...
</code>
</div>
A better syntax would be:
<div>
<code class="ruby">
# !!!!!!!!!! THIS SYNTAX DOES NOT WORK !!!!!!! #
def allExceptCode( f, content )
regexp=/<code[^>]*>.*?<\/code>/m
tmp=""
content.split(regexp).each do |x|
separator=$&
tmp <<= send(f,x)
if not separator.nil?
tmp <<= separator
end
end
tmp
end
</code>
</div>
I would expect the split make a search on a regular expression and then give the matched expression into the `$&` variable. But it is not the case.
If someone know a nicer way to do that I will be happy to know how.

View file

@ -0,0 +1,293 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-28T11:03:30+02:00
title: custom website synchronisation with mobileme (2)
multiTitle:
en: custom website synchronisation with mobileme (2)
fr: Synchronisation avec mobileme (2)
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- mobileme
- WebDav
- synchronisation
- zsh
- script
-----
I already talked about how [I synchronized my website with mobileme](/Scratch/multi/blog/10_Synchronize_Custom_WebSite_with_mobileMe). I ameliorated this script in order to make it incremental.
Here is my new script, it first create a map which associate to each file its hash. After that it compare this file to the remote one. Then for each different file, update the content.
Even with this script I also have some problem. Mostly due to 'webdav' issues. For example, renaming a folder work really badly (on Linux at least). I use webdavfs. For example:
<div><code class="zsh">
mv folder folder2
</code></div>
It returns OK and I've got:
<div><code class="zsh">
$ ls
folder folder2
</code></div>
Booh....
In order to handle most webdav issues I use a *framework* in zsh. It handle almost all except the correct renaming of folder. Working on it... Anyway here is the code I use.
<div><code class="zsh" file="webdav-framework">
#!/usr/bin/env zsh
function samelineprint {
print -n -P -- "\r$*"
}
# avec 1 essai par seconde: 300 = 5 minutes
maxessais=300
# try to create a directory until success
function trymkdir {
target="$1"
print -- mkdir -p $target
local essai=1
while ! mkdir -p $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to copy until success
function trycp {
element="$1"
target="$2"
if [[ ! -d ${target:h} ]]; then
trymkdir ${target:h}
fi
local essai=1
print -- cp $element $target
while ! \cp $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to remove until success
function tryrm {
target="$1"
local essai=1
local options=''
[[ -d $target ]] && options='-rf'
print -- rm $options $target
while ! rm $options $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
essai=1
while [[ -e $element ]]; do
samelineprint "rm reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to rename until success
function tryrename {
element="$1"
target="$2"
local essai=1
while [[ -e $target ]]; do
samelineprint "Echec n°$essai le fichier $target existe déjà"
((essai++))
((essai>maxessais)) && exit 5
sleep 1
done
print -- mv $element $target
while ! mv $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 4
done
essai=1
while [[ -e $element ]]; do
samelineprint "mv reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to move until success
function trymv {
element="$1"
target="$2"
local essai=1
print -- mv $element $target
while ! mv $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
essai=1
while [[ -e $element ]]; do
samelineprint "mv reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
</code></div>
And here is the code on how I synchronize my website. There is a little cryptic code. It correspond a problem caused by the bluecloth filter which is a markdown program made in ruby. Each time my email is written it is transformed differently. This is why I remove this part from the content of each html file. Without it, all my files containing email are different at each regeneration of my website.
<div><code class="zsh" file="publish">
#!/usr/bin/env zsh
# Script synchronisant le site sur me.com
# normalement, le site est indisponible le moins de temps possible
# le temps de deux renommages de répertoire
# get configuration
# mostly directories
source $0:h/config
# get trycp function (copy until success)
source $0:h/webdav-framework
if [[ $1 == '-h' ]]; then
print -- "usage : $0:h [-h|-s|-d]"
print -- " -a sychronise aussi l'index"
print -- " -h affiche l'aide"
print -- " -d modification directe (pas de swap)"
print -- " -s swappe simplement les répertoires"
fi
# publication incrementale
function incrementalPublish {
local ydestRep=$destRep$suffix
localRef="$srcRep/map.yrf"
print -- "Creation du fichier de references"
create-reference-file.sh > $localRef
remoteRef="/tmp/remoteSiteMapRef.$$.yrf"
if [[ ! -e "$ydestRep/map.yrf" ]]; then
# pas de fichier de reference sur la cible
print -- "pas de fichier de reference sur la cible, passage en mode rsync"
rsyncPublish
swap
else
trycp "$ydestRep/map.yrf" "$remoteRef"
typeset -U filesToUpdate
filesToUpdate=( $(diff $localRef $remoteRef | awk '/^[<>]/ {print $2}' ) )
if ((${#filesToUpdate} == 1)); then
print -- "Seul le fichier ${filesToUpdate} sera téléversé"
elif ((${#filesToUpdate}<10)); then
print -- "${#filesToUpdate} fichiers seront téléversés :"
print -- "${filesToUpdate}"
else
print -- "${#filesToUpdate} fichiers seront téléversés"
fi
# copy all file with some differences
# except the map in case of error
for element in $filesToUpdate; do
if [[ $element == "/map.yrf" ]]; then
continue
fi
if [[ -e $srcRep$element ]]; then
trycp $srcRep$element $ydestRep$element
else
tryrm $ydestRep$element
fi
done
# if all went fine, copy the map file
trycp $srcRep/map.yrf $ydestRep/map.yrf
# remove the temporary file
\rm $remoteRef
# if we have used the tmp directory we swap
if [[ "$suffix" != "" ]]; then
swap
fi
fi
}
# publication via rsync
function rsyncPublish {
result=1
essai=1
while (( $result > 0 )); do
print -- rsync -arv $srcRep/ $destRep.tmp
if ((!testmode)); then
rsync -arv $srcRep/ $destRep.tmp
fi
result=$?
if (( $result > 0 )); then
print -P -- "%BEchec du rsync%b (essai n°$essai)" >&2
fi
((essai++))
done
}
# swap
function swap {
print -P -- "%B[Directory Swap (tmp <=> target)]%b"
[[ -e $destRep.old ]] && tryrm $destRep.old
print -- " renommage du repertoire sandard vers le .old"
tryrename $destRep $destRep.old
print -- " renommage du repertoire tmp (nouveau) vers le standard"
print -P -- "%B[Site Indisponible]%b $(date)"
tryrename $destRep.tmp $destRep
print -P -- "%B[Site Disponible]%b $(date)"
print -- " renommage du repertoire old vers le tmp"
tryrename $destRep.old $destRep.tmp
print -P -- " publication terminée"
}
print -- "Root = $webroot"
print -- "Dest = $destRep"
if [[ "$1" = "-s" ]]; then
swap
else
print -P "Copie de l'init"
\cp -f $webroot/Scratch/multi/index.html $webroot/index.html
if [[ "$1" = "-d" ]]; then
suffix=""
else
suffix=".tmp"
fi
print -P -- "%BSync%b[${Root:t} => ${destRep:t}$suffix]"
incrementalPublish
fi
</code></div>
This is my way to replace `rsync` with filesystem not handling it.
Hope it is usefull. I'll be happy to hear a way to handle the webdav rename folder problem. This is really annoying.

View file

@ -0,0 +1,56 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-30T22:34:46+02:00
title: How to handle evil IE
multiTitle:
en: How to handle evil IE with jQuery
fr: Une CSS pour IE seulement
multiDescription:
fr: Pour les développeur de site web Internet Explorer est un cauchemar. C'est pourquoi j'utilise un style complètement différent pour ce navigateur. Avec la librairie jQuery.
en: For developer IE is a nightmare. This is why, I use a method to disable my standard CSS and enable a IE only CSS. I use jQuery to accomplish that.
tags:
- web
- webdesign
- jQuery
-----
For developer IE is a nightmare. This is why, I use a method to disable my standard CSS and enable a IE only CSS. I use jQuery to accomplish that.
<div><code class="javascript">
$(document).ready( function() {
if ($.browser["msie"]) {
// include the ie.js file
$('head').append('<script type="text/javascript" src="/js/ie.js"></scr' + 'ipt>');
}
});
</code></div>
<div><code class="javascript" file="ie.js">
// Remove all CSS I don't want to use on IE
$('link[rel=stylesheet]').each(function(i)
{
if (this.getAttribute('href') == '/css/layout.css')
this.disabled = true;
if (this.getAttribute('href') == '/css/shadows.css')
this.disabled = true;
if (this.getAttribute('href') == '/css/gen.css')
this.disabled = true;
}) ;
// Append the CSS for IE only
$('head').append('<link rel="stylesheet" type="text/css" href="/css/ie.css"/>');
// I also add a message on top of the page
$('body').prepend('<div id="iemessage"><p><span class="fr"><em>Avec <a href="http://www.firefox.com"> Firefox </a> et <a href="http://www.apple.com/safari">Safari</a> cette page est bien plus jolie !</em></span><span class="en"><em>This page is far nicer with <a href="http://www.firefox.com"> Firefox </a> and <a href="http://www.apple.com/safari">Safari</a>!</em></span></p>.</div>');
</code></div>
That's it.

View file

@ -0,0 +1,97 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-22T20:45:18+02:00
title: Focus vs Minimalism
multiTitle:
fr: <em>Focus</em> &gt; Minimalisme
en: Focus &gt; Minimalism
multiSubTitle:
fr: Cacher la navigation pour une meilleure concentration
en: Hide navigation for better focus
multiDescription:
fr: Je crois que le but du minimalisme est de facilité le <em><strong>Focus</strong></em> c'est-à-dire la concentration sur le contenu. Je crois que le minimalisme doit être un moyen et pas une fin.
en: I believe the goal researched by minimalism is <strong>Focus</strong>. But I don't believe minimalism should be the goal. Focus should be the goal, and I believe minimalism isn't necessary to reach it.
tags:
- jquery
- design
- web
-----
en: I believe the goal researched by minimalism is <strong>Focus</strong>. But I don't believe minimalism should be the goal. Focus should be the goal, and I believe minimalism isn't necessary to reach it.
This is why my design is not minimalist, but I decided to remove most of the navigation stuff of all pages of my website. May be I'll prefer to hide the menu only when you are on blog article. For now, I hide the menu everywhere on the website.
newcorps
## technical details
For those who want the technical details behind the show/hide menu, here is the simple jQuery code.
The HTML:
<div>
<code class="html">
<div id="menuButton"></div>
<div id="entete">#content of the menu</div>
</code>
</div>
The CSS:
<div><code class="css">
#menuButton {
font-size: 2em;
height: 2em;
line-height: 1.8em;
width: 2em;
position: fixed;
left: 0;
top: 0;
z-index: 9001 }
#menuButton:hover {
cursor: pointer; }
#entete {
top: 5em;
left: 0;
position: fixed;
width: 10em;
z-index: 9000; }
</code>
</div>
The javascript code (using jQuery)
<div>
<code class="javascript">
function hideMenu() {
$('#entete').animate({left:"-10em"}, 500 );
$('#menuButton').html('&rarr;');
}
function showMenu() {
$('#entete').animate({left:"0em"}, 500 );
$('#menuButton').html('&larr;');
}
function toggleMenu() {
if ( $('#entete').css('left')=='-10em' ) {
showMenu();
} else {
hideMenu();
}
}
</code>
</div>
And the result is shown in the top left corner of this website.

View file

@ -0,0 +1,111 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-03T14:34:11+02:00
title: How to preload your site with style
multiTitle:
fr: La classe pour charger une page web
en: How to preload your site with style
multiDescription:
fr: pas de description.
en: no description.
tags:
- web
- jquery
- webdesign
-----
## Example
Here is a live example of what appear while loading my pages.
<div id="demo" style="width:45%; position: relative; height: 8em; background-image: url('/Scratch/css/img/red.jpg'); background-position: 50% 50%; color: #fff; text-align: center; padding-top: 1em; margin-left: auto; margin-right: auto; border: solid 10px rgba(255,255,255,0.7); -webkit-border-radius: 1em; -moz-border-radius: 1em; border-radius: 1em; cursor: pointer; ">
<p><en>Hello! I've finished loading!</en><fr>Voilà ! Je suis chargée !</fr></p>
<p><en>Click me to see me disapear again.</en><fr>Cliquez-moi dessus pour recommencer.</fr></p>
<div id="todisapear" style="color: #000; position:absolute;top:0;left:0;text-align: center; padding-top: 1em; width: 100%; background-color: #eee; height: 8em;">
Loading...
<img style="border: none; background-color: none; background: none" src="/Scratch/img/loading.gif" alt="loading logo"/>
</div>
<script>
function Rabbit(){
$('#todisapear')
.show()
.animate({opacity: 1.0},3000)
.fadeOut();
}
$(document).ready(function(){
$('#todisapear').animate({opacity: 1.0},3000).fadeOut();
$('#demo').click(Rabbit);
});
</script>
</div>
I first tried to integrate [queryLoader](http://www.gayadesign.com/diy/queryloader-preload-your-website-in-style/), but it didn't fill my needs.
The plugin add a black div to hide all the content. But as the script had to be launched at the end of the source code my website show for a small time.
In order to hide this small artefact, here is how I do that.
## Code
In a first time, I added at the top of the body the div hiding all the content.
<div>
<code class="html">
...
<body>
<div id="blackpage">
content to display during the loading.
</div>
...
</code>
</div>
and here is the associated CSS to `#blackpage`:
<div>
<code class="css">
#blackpage
top: 0
left: 0
width: 100%
height: 100%
margin-left: 0
margin-right: 0
margin-top: 0
margin-bottom: 0
position: absolute
text-align: center
color: #666
padding-top: 10em
background-color: #eee
z-index: 9000
</code>
</div>
and the associated jQuery code:
<div>
<code class="javascript">
$(document).ready(function(){
$('#blackpage').fadeOut();
});
</code>
</div>
Yes, it is as simple as that. And, putting the `#blackpage` div at the top of my page, I ensure to hide anything while loading.
I hope it had helped you!

View file

@ -0,0 +1,106 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-26T21:56:09+02:00
title: Wait to hide a menu in jQuery
multiTitle:
fr: Un menu qui attends avant de se cacher
en: Menu waiting to hide himself
multiDescription:
fr: pas de description.
en: no description.
tags:
- jQuery
- web
- javascript
- design
-----
I discussed [earlier why I prefer to hide my navigation menu](/Scratch/multi/blog/2009-10-Focus-vs-Minimalism). I finally decided to hide it only after a short time. Just the time needed for a user to see it. But how make it disappear only when it is not used for some time?
Here is how to accomplish that easily.
HTML:
<div>
<code class="html">
<div id="menuButton"></div>
<div id="entete">
<ul>
<li> menu item 1 </li>
...
<li> menu item n </li>
</ul>
</div>
</code>
</div>
CSS:
<div><code class="css">
#entete {
top: 1em;
left: 0;
position: fixed;
width: 10em;
z-index: 2000; }
#entete {
top: 1em;
height: 22em;
left: 0;
position: fixed;
width: 10em; }
</code></div>
Javascript:
<div><code class="javascript">
var last=0;
// will hide the menu in 5 seconds
// if the variable 'last' has not changed its value
function autoHideMenu(value) {
setTimeout(function(){
if ( last == value ) { hideMenu(); }
},5000);
}
$(document).ready( function() {
// show the menu when the mouse is on
// the good area
$('#menuButton').hover(showMenu);
// If the mouse is on the menu change the
// value of 'last'
// try to hide the menu when the mouse
// go out off the menu.
$('#entete').hover(
function(){last+=1;},
function(){autoHideMenu(last);} );
autoHideMenu(0);
});
// show / hide menu functions details
// move to the left
function hideMenu() {
$('#entete').animate({left:"-10em"}, 500 );
}
// move to right and will try to hide in 5 sec.
function showMenu() {
$('#entete').animate({left:"0em"}, 500 );
last+=1;
autoHideMenu(last);
}
</code></div>
Simple and lightweight. No timer (almost), no memory leak, no Date...

View file

@ -0,0 +1,36 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-23T10:53:16+02:00
title: launch daemon from command line
multiTitle:
fr: lancer un démon en ligne de commande
en: launch daemon from command line
multiDescription:
fr: Pour lancer une commande qui continue de tourner après la fermeture du terminal il suffit de lancer la commande <code>nohup cmd &amp;</code>
en: To launch a command which will continu to run after the terminal is closed you only have to use <code>nohup cmd &amp;</code>
tags:
- zsh
- shell
- script
- tip
-----
Here is a tip, I don't know why, but I almost always forgot how to do that.
When you want to launch a command and this command should not be killed after you close your terminal. Here is how to accomplish that from command line:
<div><code class="zsh">
nohup cmd &
</code>
<small>where <code>cmd</code> is your command.</small>
</div>
I let this command here for me and I wish it could also help someone.

View file

@ -0,0 +1,291 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-13T13:10:09+02:00
title: untaught Git usage
multiTitle:
fr: Usages non dits de Git
en: Untaught Git usage
multiDescription:
fr: Je décris pourquoi j'ai eu tant de mal à me faire à Git. Il y a en effet une partie "non dite" qui m'a bloqué pendant un bon moment. Jusqu'à ce que je découvre le bon document.<br/>Le fait est que les *branches légères* ne sont pas destinée à être des branches isolées. Ainsi, il y a un <em>"workflow standard"</em> qui s'il n'est pas suivi rend l'utilisation de Git inappropriée.
en: I explain why I had so much difficulties to use Git. There is an "untaught rule" that make hard to work without. Until I read the good document.<br/> "Cheap branches" aren't designed to be totally isolated branches but rather should follow a "Master Branch". There is a <em>Standard Workflow</em> to follow. If you don't follow it, you prepare yourself with some hard time with Git.</em>
tags:
- git
- dcvs
- programming
-----
<en>
<small> <em>I explain why I had so much difficulties to use Git. There is an "untaught rule" that make hard to work without. Until I read the good document. </em></small>
</en>
<fr>
<small> <em>Je décris pourquoi j'ai eu tant de mal à me faire à Git. Il y a en effet une partie "non dite" qui m'a bloqué pendant un bon moment. Jusqu'à ce que je découvre le bon document. </em></small>
</fr>
<en>
<small> <em> "Cheap branches" aren't designed to be totally isolated branches but rather should follow a "Master Branch". There is a </em>Standard Workflow<em> to follow. If you don't follow it, you prepare yourself with some hard time with Git.</em> </small>
</en>
<fr>
<small> <em> Le fait est que les *branches légères* ne sont pas destinée à être des branches isolées. Ainsi, il y a un </em>"workflow standard"<em> qui s'il n'est pas suivi rend l'utilisation de Git inappropriée. </em> </small>
</fr>
newcorps
# My way to decentralisation
### From SVN to Bazaar
I was a huge user of [subversion (svn)](http://subversion.tigris.org). Until the day I saw this [video of Linus Torvald](http://www.youtube.com/watch?v=4XpnKHJAok8). Where he explain Git and all advantages of *Decentralized Concurrent Versioning System*(<abbr title="Decentralized Concurrent Versioning System">DCVS</abbr>)
I must say I was completely convinced. And the more you learn about <abbr title="Decentralized Concurrent Versioning System">DCVS</abbr> the more you see good reason to use them.
I then needed a versioning system for my team. As they were not used to open source versioning system except those heavy, with a GUI and with and administrator<sup><a href="#note1">&dagger;</a></sup>
After some web searches, I founded three main choices:
- [Git](http://git-scm.com)
- [Bazaar](http://bazaar-vcs.org)
- [Mercurial](http://selenic.com/mercurial)
After trying each other I chosen Bazaar. It has the simplest User Interface<sup><a href="#note2">&#42;</a></sup>. My choice was done.
### From Bazaar to Git
It was really natural to learn when coming from *subversion*. The `pull` command corresponding to `update`, `push` command to `commit`. Commands like `commit` and `update` are still there if you want to use an SVN *workflow*.
After some times, reading on many blogs, I realize Git is far more popular and by influent people.
I then decide to use Git in particular to *version* this current website.
But after trying it, I found it difficult and couter intuitive (I'll speak a work about it later).
After calling for some help, when I say Bazaar is much simpler to learn, some people answer me that Git:
> &mdash; *SO-MUCH-EASY my 12 year old daughter uses it to version its school documents. She has no difficulties at all, creating branches, blah, blah, blah...*
If a 12 years old girl has no problem with Git and I (with my Computer Science Ph.D.) have difficulties to uses it like I want, it is frustrating and humiliating. But what makes Git natural for some people and confusing for me?
I finally understood why reading a document I didn't read before. It was the *untaught* part of the conception. The part every developer found so *natural* it is not necessary to say a word about it. But it was not *natural* for me.
<small><a name="note1">&dagger;</a> - I speak about *ClearCase(c)*. I know there exists command line tools. But it was not the way my team used it.</small>
<small><a name="note2">&#42;</a> - I never really given its chance to Mercurial. The terminology they chosen was too far from the svn one. And I was used to it.</small>
newcorps
When you see explanation about *branches* and <abbr title="Decentralized Concurrent Versioning System">DCVS</abbr> we imagine each branch is totally uncorrelated to each other, except when *merging*. Everything is magic. This is the "*Parallel World*" explanation. This way of seeing is explained more in depth in the [real good article about branches](http://betterexplained.com/articles/a-visual-guide-to-version-control/) on betterexplained.
Git was designed to manage the Linux Kernel. Git was designed using the concept of *Patch* instead of *Parallel Worlds*.
From one site *Parallel World* and *Patches* from the other. There is many equivalent notions in the two point of vue, but also some differences.
* Bazaar seems base on the *Parallel World* vision which implies *Patches*
* en:While Git seem base on the *Patch* model which will implie the creation of *Parallel Worlds*.
I will not argument about which is the best. Just tell my vision of DCVS come from the *Parallel World* vision and Git was designed the other way<sup><a href="#note3">&Dagger;</a></sup>.
## From Theory to Real Life Usage
I believe I understood conceptual mechanism under Git. But I had some difficulties with real usage. The worst point, the one I didn't get before long was because I didn't get really well the notion of *Cheap Branching*.
What is a *Cheap Branch*? If like me you come from Bazaar, it is a totally new notion. It is in fact the ability to create a branches all of them using the same directory.
You just have to launch a Git command and the local directory reflect the state of the branch you selected.
In theory, *Cheap Branches* are exactly like Bazaar branches. The word used is *Branch* and not *Cheap Branch*. But there is a slight difference between them. A slight difference between a *Cloned Branch* and a *Cheap Branch*.
A "Standard branch" is what is theoretically a kind of new *Parallel World*.
But *Cheap branch* was designed to be future *Patch* for the main branch of the directory/Cloned branch.
Of course, I know anybody can state you can totally use *Cheap branches* as *Cloned branches*. But they weren't designed for that. On daily usage, it is a bit uneasy to use it like this.
Here how Git *cheap branches* should be used (for more details see [Git for Designers](http://hoth.entp.com/output/git_for_designers.html)):
* get or creation of a main repositoy **<sc>The Great Repository</sc>**
* creation of a *Cheap branch* containing differences which **have** to be patched somewhere in the future into **<sc>The Great Repository</sc>**
Here's how you should **not** use Git:
* Get or creation of a repository
* Create a *cheap branch* which will never push it's modification to the main repository.
This simple minor difference of point of view confused me a lot.
### Real Life Usage
Now I have understood all that. I understand why Git has some many people claiming it is the best DCVS.
Cheap branching notion is essential in Git and is a really useful feature. Particularly for this website. But, there are not exactly, completely parallel line of development. Because they are designed to path the main branch. Of course, it is not an obligation, but there are slight messages which tell you this should be used like that.
If I want to separate in a better way some branches I just have to *Clone* them.
And I return exactly in branches Bazaar provided me.
### Examples
For now, I prefer (from far) Bazaar terminology. They are cleaner and more understandable.
<div><code class="zsh">bzr revert</code></div>
Is clearer than
<div><code class="zsh">git reset --hard HEAD</code></div>
We can tell the same thing about
<div><code class="zsh">bzr revert -r -3</code></div>
which seems preferable to
<div><code class="zsh">git reset --hard HEAD~3</code></div>
Until now, it is not big business. But now, things will go worse.
If we want to revert time on all the tree we use the keyword `reset`.
<center>OK</center>
Now, if I want to revert time on on file. We should naturally imagine the command will be:
<div><code class="zsh">git reset --hard FILE</code></div>
<center>**OF COURSE NOT!**</center>
The solution is:
<div><code class="zsh">git checkout FILE</code></div>
What? **`checkout`** !? Well, ok. I accept. why not?
With Bazaar it is:
<div><code class="zsh">git revert FILE</code></div>
What I personally found far more natural.
But the command to change the current *cheap branch* is really hard to be accepted (from the User Interface point of view).
With Bazaar it is:
<div><code class="zsh">cd ../branch</code></div>
Well yes. With Bazaar you have to change your directory to change your branch. It needs more disk resources but it is really clear. Which is my current branch, is just a `pwd` away. For Git here is the command:
<div><code class="zsh">git checkout branch</code></div>
**WTF?** I believed `checkout` was the key to get a file in some state (not the entire tree).
Then `checkout` is the same keyword used to get back in time on a file (BUT NOT ON ALL THE TREE where you have to use `reset --hard`) and to **change current branch**!
It is totally unnatural. Even if it is theoretically totally justified like you can see in the really good article [Git for Computer Scientist](http://eagain.net/articles/git-for-computer-scientists/). From the user point of vue, it is difficult to do worse than that. It is like somebody made it on purpose to make it the hardest possible to learn and understand.
> - &mdash; Try to find the good keyword for this operation
> - &mdash; Wrong! Try again!
> - &mdash; False, it is not yet right!
That were the Git bad side. But It has many advantages. Once you've understood the *cheap branching* paradigm. All became clearer for me after. Even if there is also some difficulties with the edit of the `.git/config` files (not user friendly at all).
<small><a name="note3">&Dagger;</a> I must precise that I worked a lot with multi-modal logic and particularly about "Temporal Logics" (linear or not). This is why I was more inclined to see things this way. "Ah ! Just to remember my firsts love with computer science !"</small>
newcorps
# Conclusion
### DCVS vs. CVS ?
Was it a good idea to change to a *decentralised* versionning system? Clearly yes. Decentralisation give far much great possibilities.
Such as working on a fix on a totally isolated branches.
### Is Git better than Bazaar?
Speaking about *features* I'll tell Git is the best.
But Git was too much in my way. Is was exactly what I didn't want for my first DCVS.
I shouldn't have had those difficulties about understanding *cheap branching which must be a patch*. In reality, Git make a difference between the Tree and the Branch. Which is obviously not the case for Bazaar. Conceptually, bazaar is simpler to understand.
### Finally
In conclusion, I use Git more often than Bazaar and I must say, that I have some preferences for Git. However, Git lack hardly clear commands name like `revert`.
For now I don't made alias to correct that. But may be one day I should do that.

View file

@ -0,0 +1,76 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-11-12T11:39:54+02:00
title: Git for n00b
multiTitle:
en: Git for n00b
fr: Git pour les 'n00b'
multiDescription:
fr: Voici un tutoriel <a href="http://git-scm.org">Git</a> détaillé pour ceux qui en connaissent très peu sur les systèmes de versions. Vous comprendrez l'utilité de tels systèmes et surtout comment on se sert des systèmes de versions modernes, le tout en restant le plus pragmatique possible.
en: A detailed tutorial of <a href="http://git-scm.org">Git</a> for people knowing very few about versions systems. You'll understand utility of such program and how we use modern version control system. I try to stay as pragmatic as possible.
tags:
- git
-----
begindiv(intro)
A detailed tutorial of <a href="http://git-scm.org">Git</a> for people knowing very few about versions systems. You'll understand utility of such program and how we use modern version control system. I try to stay as pragmatic as possible.
enddiv
newcorps
# Begin with conclusion
Here is the list of sufficient and necessary command to use [Git][git]. There is very few. It is normal not to understand immediately but it is to gives you an idea. Even if this article is long, 95% of [Git][git] usage is in these 7 commands:
Get a project from the web:
<div><code class="zsh">
git clone ssh://server/path/to/project
</code></div>
Everyday [Git][git] usage:
<div><code class="zsh">
# get modifications from other
git pull
# read what was done
git log
# Make local changes to files
hack, hack, hack...
# list the modified files
git status
# show what I've done
git diff
# tell git to version a new file
git add new/file
# commit its own modifications
# to its local branch
git commit -a -m "Fix bug #321"
# send local modifications to other
git push
</code></div>
This article is written for people knowing very few about versionning systems. It is also written for those who had didn't followed progress since CVS or subversion (SVN). This is why, in a first time I'll explain quickly which are the goal of such systems. Secondly, I'll explain how to install and configure [Git][git]. Then, I give the command for each feature a <abbr title="Decentralized Concurent Versions System">DCVS</abbr> must have.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,255 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-11-12T11:39:54+02:00
title: Git for n00b
multiTitle:
fr: Git pour quoi faire ?
en: Git for what?
-----
# en:[Git][git] for what?
begindiv(intro)
If you just want to use [Git][git] **immediately**, just read dark part. You read this part later to understand correctly foundations of version systems and not doing strange things.
enddiv
[Git][git] is a <abbr title="Decentralized Concurent Versions System">DCVS</abbr>, which means a Decentralized Concurrent Versions System. Let's analyze each part of this long term:
### Versions System
Firstly, versions system manage files.
When somebody work with files without a versions system, the following happens frequently:
When you modify a somehow critical file you don't want to loose. You copy naturally this file with another name. For example:
<div><code class="zsh">$ cp fichier_important.c fichier_important.c.bak</code></div>
In consequence of what, the new file, play the role of *backup*. If you break everything, you can always return in the last state by overwriting your modifications.
Of course, this method is not very professional and is a bit limited. If you make many modifications, you'll end with many files with strange names like:
<div>
<code class="zsh">
fichier_important.c.bak
fichier_important.c.old
fichier_important.c.Bakcup
fichier_important.c.BAK.2009-11-14
fichier_important.c.2009.11.14
fichier_important.c.12112009
old.fichier_important.c
</code>
</div>
If you want to make it works correctly, you'll have to use naming convention. Files take many place even if you modify most of time only some lines.
*Fortunately, versions system are here to help.*
You only have to signal you want a new version of a file and the versions system will do the job for you. It will record the backup where it could be easily recovered. Generally, systems version do it better than you, making the backup only of the modified lines and not the total file.
Once upon a time versions were managed for each file separately. I think about CVS. Then it naturally appears projects are a coherent set of files. Recover each file separately was a tedious work. This is why versions number passed from files to the entire project.
It is therefore possible to say, "I want to get back three days earlier".
begindiv(black)
*What gives versions system?* (I didn't mention everything at all)
<fr>
- backup automatique de tous les fichiers: *Revenir dans le temps.* ;
- donne la possibilité de voir les différences entre chaque version et les différences entre la version en cours et les modifications locales ;
- permet de poser un *tag* sur certaines versions et ainsi pouvoir s'y référer facilement ;
- permet d'avoir un historique des modifications. Car en général il est demandé aux utilisateur d'ajouter un petit commentaire à chaque nouvelle version.
</fr>
<en>
- automatic backups: *back in time*,
- gives the ability to see differences between each version,
- put a *tag* on some version to be able to refer to them easily,
- gives the ability to see an historic of all modifications. Generally the user must add a comment for each new version.
</en>
enddiv
### en:concurrent:
Version Systems are already useful to manage its own projects. They help to organize and resolve partially backup problems. I say partially because you have to backup your repository on a decent file system. But versions system are really interesting is on projects done by many people.
Let's begin by an example, a two person project ; Alex and Beatrice. On a file containing a *Lovecraft*'s gods list:
<div style="width: 10em; margin-left: auto; margin-right: auto">
<code class="zsh">
Cthulhu
Shubniggurath
Yogsototh
</code></div>
Say Alex is home and modify the file:
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
Shubniggurath
<span class="StringConstant"><strong>Soggoth</strong></span>
Yogsototh
</pre>
</div>
after that he send the file on the project server. Then on the server there is the Alex file:
A bit later, Beatrice who had not get the Alex file on the server make the modification:
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
<span class="Constant"><strong>Dagon</strong></span>
Shubniggurath
Yogsototh
</pre>
</div>
Beatrice send her file on the server
Alex modification is *lost*. One more time, versions system are here to help.
A version system would had *merge* the two files at the time Beatrice send the file on the server. And like by magic, on the server the file would be:
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
<span class="Constant"><strong>Dagon</strong></span>
Shubniggurath
<span class="StringConstant"><strong>Soggoth</strong></span>
Yogsototh
</pre>
</div>
In real life, at the moment Beatrice want to send her modifications, the versions system alert her a modification had occurred on the server. Then she uses a command which pull the modification from the server to her local computer. And this command update her file. After that, Beatrice send again the new file on the server.
begindiv(black)
**In what Concurrent Versions System help?**
<fr>
- récupérer sans problème les modifications des autres ;
- envoyer sans problème ses modifications aux autres ;
- permet de gérer les conflits. Je n'en ai pas parlé, mais quand un conflit arrive (ça peut arriver si deux personnes modifient la même ligne avec deux contenus différents), les <abbr title="Systèmes de versions concurrentes">SVC</abbr> proposent leur aide pour les résoudre. J'en dirai un mot plus loin.
- permet de savoir qui a fait quoi et quand
</fr>
<en>
- get without any problem others modifications,
- send without any problem its own modifications to others,
- manage conflicts. I didn't speak about it, but sometimes a conflict can occur (when two different people modify the same line on a file for example). SVC help to resolve such problem. More on that later,
- help to know who done what and when.
</en>
enddiv
### decentralized
This word became popular only recently about CVS. And it mainly means two things:
First, until really recently (SVN), you'll have to be connected to the distant server to get informations about a project. Like get the history. New decentralized systems work with a local *REPOSITORY* (directory containing backups and many informations linked to the versions system functionalities). Hence, one can view the history of a project without the need of being connected.
All instances of a project can live *independently*.
To be more precise, DCVS are base on the *branch* notion.
Practically, it has great importance. It means, everybody work separately, and the system help to glue all their work.
It is even more than just that. It help to code independently each feature and bug fixes. Under other system it was far more difficult.
Typical example:
> I develop my project. I'm ameliorating something. An urgent bug is reported.
>
> With a DCVS I can easily, get back to the version with the bug. Fix it. Send the fix. Get back to my feature work. And even, use the fix for the new version with my new feature.
>
> In a not decentralized version system, doing such a thing is possible but not natural. Decentralization means it become natural to use a branch for each separable work.
begindiv(black)
**Advantages given by DCVS: **
- Ability to work offline,
- Ability to create many *atomic* patches,
- Help the maintenance of many different versions of the same application.
enddiv
## To resume
Let's resume what we can easily do with DCVS:
**Versions Systems**
- back in time,
- list differences between versions,
- name some versions to refer to them easily
- show history of modifications
**Concurrent**
- get others modifications,
- send its modifications to others,
- know who done what and when,
- conflicts management.
**Decentralized**
- Easily manipulate branches
Now let's see how to obtain all these things easily with [Git][git].
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,138 @@
-----
# Custom
isHidden: false
menupriority: 3
kind: article
date: 2009-11-12T11:39:54+02:00
title: The Adventure Begins
multiTitle:
fr: Utiliser Git simplement et rapidement
en: Use Git with very few commands
-----
# Here we go!
Here is one from many way to use [Git][git]. This method is sufficient to work on a project. Not there is many other *workflows*.
## Basic usage
Work with [Git][git] immediately:
<fr>
+ récupérer les modifications des autres <span class="black">`git pull`</span>
+ voir les détails de ces modifications <span class="black">`git log`</span>
+ Plusieurs fois:
+ *Faire une modification atomique*
+ verifier le details de ses modifications <span class="black">`git status`</span> et <span class="black">`git diff`</span>
+ indiquer si nécessaire que de nouveaux fichiers doivent être *versionnés* <span class="black">`git add [file]`</span>
+ enregistrer ses modifications <br/><span class="black">`git commit -a -m "message"`</span>
+ envoyer ses modifications aux autres <span class="black">`git push`</span> (refaire un `git pull` si le push renvoie une erreur).
</fr>
<en>
+ Get modification done by others <span class="black">`git pull`</span>,
+ See details of these modifications <span class="black">`git log`</span>,
+ Many times:
+ *Make an atomic modification*
+ Verify details of this modification: <span class="black">`git status`</span> and <span class="black">`git diff`</span>,
+ Add some file to be versionned if necessary:<br/><span class="black">`git add [file]`</span>,
+ Save you modifications <br/><span class="black">`git commit -a -m "message"`</span>,
+ Send your modifications to others: <span class="black">`git push`</span> (redo a `git pull` if push return an error).
</en>
With these few commands you can use [Git][git]. Even if it is sufficient, you need to know one more thing before really begin ; How to manage *conflicts*.
### Conflicts management
Conflicts can arise when you change the same line of code on the same file from another branch you're merging. It can seems a bit intimidating, but with [Git][git] this kind of thing is really simple to handle.
#### example
You start from the following file
<div style="width: 18em; margin-left: auto; margin-right: auto">
<code class="zsh">
Zoot
</code>
</div>
and you modify one line
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot <span class="Constant"><strong>the pure</strong></span>
</pre>
</div>
except during this time, another user had also modified the same line and had done a `push`.
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot<span class="StringConstant"><strong>, just Zoot</strong></span>
</pre>
</div>
Now when you do a:
<div>
<code class="zsh">
$ git pull
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/e640846/tmp/conflictTest
d3ea395..2dc7ffb master -> origin/master
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Automatic merge failed; fix conflicts and then commit the result.
</code>
</div>
Our file `foo` now contains:
<div>
<pre class="twilight">
<<<<<<< HEAD:foo
Zoot <span class="Constant"><strong>the pure</strong></span>
=======
<span>Zoot<span class="StringConstant"><strong>, just Zoot</strong></span></span>
>>>>>>> 2dc7ffb0f186a407a1814d1a62684342cd54e7d6:foo
</pre>
</div>
#### Conflict resolution
To resolve the conflict you only have to edit the file for example, writing:
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot <span class="Constant"><strong>the not so pure</strong></span>
</pre>
</div>
and to commit
<div>
<code class="zsh">
git commit -a -m "conflict resolved"
</code>
</div>
Now you're ready to use [Git][git].
[Git][git] provide many other functionnalities. Now we'll see some [Git][git] usages older CVS couldn't handle.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,162 @@
-----
# Custom
isHidden: false
menupriority: 30
kind: article
date: 2009-11-12T11:39:54+02:00
title: The Adventure Begins
multiTitle:
fr: Liste de commandes
en: Command List
tags:
- git
-----
# Command List
## Command for each functionality
In the first part, we saw the list of resolved problem by [Git][git]. To resume [Git][git] should do:
<fr>
- récupérer les modifications des autres ;
- envoyer ses modifications aux autres ;
- revenir dans le temps ;
- lister les différences entre chaque version ;
- nommer certaines versions pour s'y référer facilement ;
- afficher l'historique des modifications ;
- savoir qui a fait quoi et quand ;
- gérer des conflits ;
- manipuler facilement des branches.
</fr>
<en>
- get others modifications,
- send modifications to others,
- get back in time,
- list differences between each version,
- name some versions in order to refer easily to them,
- write an historic of modifications,
- know who did what and when,
- manage conflicts,
- easily manage branches.
</en>
### get others modifications
<div><code class="zsh">
$ git pull
</code></div>
### send modifications to others
<div><code class="zsh">
$ git push
</code></div>
or more generally
<div><code class="zsh">
$ git pull
$ git push
</code></div>
### get back in time
#### For all tree
<div><code class="zsh">
$ git checkout
</code></div>
<div><code class="zsh">
$ git revert
</code></div>
revert three version before (see my `.gitconfig` file).
<div><code class="zsh">
$ git uncommit 3
</code></div>
Undo the las merge (if something goes wrong)
<div><code class="zsh">
$ git revertbeforemerge
</code></div>
#### For one file
<div><code class="zsh">
$ git checkout file
$ git checkout VersionHash file
$ git checkout HEAD~3 file
</code></div>
### list differences between each version
list files being modified
<div><code class="zsh">
$ git status
</code></div>
fr:différences entre les fichier de la dernière version et les fichiers locaux.
<div><code class="zsh">
$ git diff
</code></div>
liste les différences entre les fichier d'une certaine version et les fichiers locaux.
<div><code class="zsh">
$ git diff VersionHash fichier
</code></div>
### name some version to refer to them in the future
<div><code class="zsh">
$ git tag 'toto'
</code></div>
### show historic of modifications
<div><code class="zsh">
$ git log
$ git lg
$ git logfull
</code></div>
### en:know who did what and when::
<div><code class="zsh">
$ git blame fichier
</code></div>
### handle conflicts
<div><code class="zsh">
$ git conflict
</code></div>
### manage branches
To create a branch:
<div><code class="zsh">
$ git branch branch_name
</code></div>
To change the current branch:
<div><code class="zsh">
$ git checkout branch_name
</code></div>
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,48 @@
-----
# Custom
isHidden: false
menupriority: 10
kind: article
date: 2009-11-12T11:39:54+02:00
title: Understanding
multiTitle:
fr: Comprendre
en: Understanding
tags:
- git
-----
# Why Git is cool?
Because with [Git][git] you can work on many part of some project totally independently. This is the true efficiency of decentralisation.
Each branch use the same directory. Then you can easily change your branch. You can also change branch when some files are modified. You can then dispatch your work on many different branches and merge them on one master branch at will.
Using the `git rebase` you can decide which modifications should be forget or merged into only one modification.
What does it mean for real usage? You can focus on coding. For example, you can code, a fix for bug b01 and for bug b02 and code a feature f03. Once finished you can create a branch by bug and by feature. And finally you can merge these modifications on a main branch.
All was done to code and decide how to organize your versions after. In other VCS it is not as natural as in [Git][git].
With [Git][git] you can depend of many different sources. Then, there is not necessarily a 'master' repository where everybody puts its modifications.
What changes the most with [Git][git] when you come from SVN, it's the idea of a centralized project on one server. With [Git][git] many people could work on the same project but not necessarily on the same *repository* as main reference. One can easily fix a bug and send a patch to many different versions of a project.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,165 @@
-----
# Custom
isHidden: false
menupriority: 2
kind: article
date: 2009-11-12T11:39:54+02:00
title: Configure before Use
multiTitle:
fr: Avant l'utilisation, la configuration
en: Configure before use
-----
# Before usage, configuration
## install
Under Linux Ubuntu or Debian:
<div><code class="zsh">$ sudo apt-get install git</code></div>
Under Mac OS X:
* install [MacPorts](http://macports.org/install.php)
* install [Git][git]
<div><code class="zsh">
$ sudo port selfupdate
$ sudo port install git-core
</code></div>
## Global configuration
Save the following file as your `~/.gitconfig`.
<div><code class="zsh" file="gitconfig">
[color]
branch = auto
diff = auto
status = auto
[alias]
st = status
co = checkout
br = branch
lg = log --pretty=oneline --graph
logfull = log --pretty=fuller --graph --stat -p
undo = checkout
unstage = reset HEAD
# there should be an article on what this command do
uncommit = !zsh -c '"if (($0)); then nb=$(( $0 - 1 )); else nb=0; fi; i=0; while ((i<=nb)); do git revert -n --no-edit HEAD~$i; ((i++)); done; git commit -m \"revert to $0 version(s) back\""'
undomerge = reset --hard ORIG_HEAD
conflict = !gitk --left-right HEAD...MERGE_HEAD
# under Mac OS X, you should use gitx instead
# conflict = !gitx --left-right HEAD...MERGE_HEAD
[branch]
autosetupmerge = true
</code></div>
You can achieve the same result using for each entry the command: `git config --global`. Next, configure your name and your email. For example, if your name is John Doe and your email is `john.doe@email.com`. Launch the following commands:
<div><code class="zsh">
$ git config --global user.name John Doe
$ git config --global user.email john.doe@email.com
</code></div>
Here it is. Base configuration is over. The file containing alias will help to type shorter commands.
## Get a project
If a project is already versionned with [Git][git] you should have an `URL` of the sources. Then use the following command:
<div><code class="zsh">
$ cd ~/Projets
$ git clone git://main.server/path/to/file
</code></div>
If there is no git server but you've got an `ssh` access. Just replace the `git://host` by `ssh://user@host`. In order not to type your password each time, use:
<div><code class="zsh">
$ ssh-keygen -t rsa
</code></div>
Reply to question and **do not enter* a password. Then copy your keys to the distant server. This is not the safest way to do this. The safest being, using `ssh-agent`.
<div><code class="zsh">
me@locahost$ scp ~/.ssh/id_rsa.pub me@main.server:
me@locahost$ ssh me@main.server
password:
me@main.server$ cat id_rsa.pub >> ~/.ssh/authorized_keys
me@main.server$ rm id_rsa.pub
me@main.server$ logout
</code></div>
Now you don't need to write your password to access the `main.server`.
## Creating a new project
Suppose you already have a project with files. Then it is really easy to version it.
<div><code class="zsh">
$ cd /path/to/project
$ git init
$ git add .
$ git commit -m "Initial commit"
</code></div>
Let do a small remark. If you don't want to *version* every file. Typically intermediate compilation file, swap files... Then you need to exclude them. Just before launching the `git add .` command. You need to create a `.gitignore` file in the root directory of your project. This file will contain all exclude *pattern*. For example:
<div><code class="zsh">
*.o
*.bak
*.swp
*~
</code></div>
Now, if you want to create a repository on a distant server, it *must* not be in `bare` mode. The repository will contain only versionning informations, but not the files of the project. To achieve that:
<div><code class="zsh">
$ cd /path/to/local/project
$ git clone --bare . ssh://server/path/to/project
</code></div>
Others will be able to get your modifications.
<div><code class="zsh">
git clone ssh://server/path/to/project
</code></div>
## Abstract of the second step
You now have a local directory on your computer. It is versionned and you can say it is, because there is a `.git` directory at the root (and the root only) of your project. This directory contain all necessary informations for [Git][git] to version your project.
Now you only need to know how to use it.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,31 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-12-06T11:35:34+02:00
title: iphone call filter
multiTitle:
fr: Filtrage d'appel avec l'iPhone
en: iPhone call filter
multiDescription:
fr: Il est vraiment incroyable qu'une telle chose ne soit pas disponible.
en: I can't believe such a lack.
tags:
- iPhone
- Apple
- filter
- blacklist
-----
It is unbelievable you cannot filter your call with an iPhone! The only reason I see for that is a negotiation with phone operator to force users to get phone advertising. It is simple unacceptable.
I'm a λ iPhone's user. The only way to filter your call and to manage blacklist is to *jailbreak* your iPhone. And I don't want to do that. Then, if like me you find it unacceptable, just write a line to Apple: [http://www.apple.com/feedback/iphone.html](http://www.apple.com/feedback/iphone.html)

View file

@ -0,0 +1,214 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-12-14T10:46:36+02:00
title: Git vs. Bzr
multiTitle:
fr: Git ou Bazaar ?
en: Git vs. Bzr
multiSubTitle:
fr: Pourquoi je suis passé de Bazaar à Git
en: Why I switched from bazaar to git
multiDescription:
fr: pas de description.
en: no description.
tags:
- git
- bzr
- DCVS
- Bazaar
-----
begindiv(intro)
Why even if I believe `git` has many bad point I believe it is the best DCVS around to work with. This is why I first tell why I prefer [Bazaar](http://bazaar-vcs.org) over [Git](http://git-scm.org). Secondly I'll talk about the only advantage of git against Bazaar which lead me to prefer it.
enddiv
## The DCVS discovery
Before beginning this article, you should know I come from *subversion*. I find subversion to be a really good CVS. But I was converted to the decentralized ones.
There is two way of perceive version control system. Either you think in term of branches (see the really good article on [betterexplained](http://betterexplained.com/articles/a-visual-guide-to-version-control/)) or think in term of patches. Another way to say that, is weather you concentrate on vertices or on transitions of the graph of possible states of your project.
This is the second approach who was behind `git` and this is the first behind Bazaar. `git` was created by Linus Torvald in order to close some gap in the version system used to develop the Linux kernel. And patches is a term which is more present than 'state' in the development community.
I first was convinced by Bazaar. Why? Argument in favor of Bazaar were: user friendly, terminology close to the subversion one. And I tried a bit the two, and it was clearly more natural for me to use Bazaar. But after seeing so many people using `git` I decided to give it a serious try.
And it was so fastidious! The `git` terminology was *horrible*! And it is nothing to say it.
## Where Bazaar is better than `git`
The first example, `checkout` is used to make only one thing from the technical point of vue. But from the user perspective, you make many *different* things with this word. Example:
<div><code class="zsh">
git checkout pipo
</code></div>
undo the current modification of the file `pipo`
<div><code class="zsh">
git checkout pipo
</code></div>
change the current branch to the branch `pipo`
And, like me, you remark, it is exactly the same command to make two completely different things. What occur when you have a `pipo` branch and a `pipo` file? By default, it change the current branch. In order to leave the ambiguity you have to use the following syntax:
<div><code class="zsh">
git checkout ./pipo
</code></div>
Yes, hum...
It works, but it is clearly not really user friendly. Furthermore, checkout had a complete different signification in older CSV like `cvs` et `svn`. `checkout` was used to get a distant project locally.
Bazaar terminology is far more natural, because there is no command to change the current branch as there is only one branch per directory. Changing a branch in Bazaar is changing the current directory. I also believe it is the biggest problem of Bazaar, I'll tell you why. And to undo things in Bazaar:
<div><code class="zsh">
bzr revert pipo
</code></div>
Furthermore, most Bazaar command take a revision number in parameter. For example, to get back 3 versions earlier, it is enough to write:
<div><code class="zsh">
bzr revert -r -3 pipo
</code></div>
The `git` equivalent is far more cryptic:
<div><code class="zsh">
bzr checkout HEAD~3 pipo
</code></div>
One more time, Bazaar is far more readable.
Back in time for all the project:
with Bazaar:
<div><code class="zsh">
bzr revert -r -3 pipo
</code></div>
and with `git`? `git checkout`? Of course not! It would be too simple. What we find in the documentation (`man`) and everywhere on the net:
<div><code class="zsh">
git reset --hard HEAD~3
</code></div>
Except that this command is horrible. It forget revisions! Then you must use it with prudence. And you cannot tell other people working on the project you discard some changes. If someone had pulled the *bad* version, you are *doomed*. This is why you can also use:
<div><code class="zsh">
git checkout HEAD~3 -- . && git commit -m 'back in time'
</code></div>
Just to keep a backup branch. Without it we can definitively loose the current version HEAD. But some error may rest when there were some addition and deletion of files. *The unique way to be really clean without any risk is to use the following command:*
<div><code class="zsh">
for i in $(seq 0 2); do
git revert -n --no-edit head~$i;
done
git commit -m "reverted 3 versions back"
</code></div>
And with this command this is the only good way to undo things in a project and tell other contributor you reverted something. You simply revert version in backward order.
The rule is simple: *NEVER use the `git reset` command on a version somebody else could have `fetched`*
It was said. Discover the best method took me some time. I'd made many different tries. The safer and best way of reverting back your tree is to use this method. If you want to make it automatic just had the following alias in your `~/.gitconfig`. Of course this alias will work only on environment having `zsh` installed. Which is the cas for most UNIX (Ubuntu, Mac OS X...).
<div><code class="zsh" file="gitconfig">
[alias]
uncommit = !zsh -c '"if (($0)); then nb=$(( $0 - 1 )); else nb=0; fi; i=0; while ((i<=nb)); do git revert -n --no-edit HEAD~$i; ((i++)); done; git commit -m \"revert to $0 version(s) back\""'
</code></div>
# What make `git` by far the best DCVS today
After talking about the negatives points of `git`, now it's time to speak about the very positive feature that make `git` the best DCVS in my humble opinion.
## Cheap branching
You always work into the same main directory. For example, you can work on two fix in the same time. Say `fix1` require you to work on `file1` and `fix2` to work on `file2`. You can work in any order on `file1` and `file2` in the `master` branch. And then go to branch `fix1`, commit `file1` into it. Then go to branch `fix2` and commit `file2` into it. And finally merge the two branches `fix1` and `fix2` into `master`.
<div><code class="zsh">
> vim file1
> vim file2
> git br fix1
> git add file1
> git commit -m 'fix1'
> git br fix2
> git add file2
> git commit -m 'fix2'
> git commit master
> git merge fix1
> git merge fix2
</code></div>
And this is great not to worry about working in the *good* branch and coding in the same time. You just worry about your code and then about the versionning system.
And I use this possibilities *a lot*. Working with bazaar, I often made the error to begin a change in the bad branch. then I have to copy my modifications, then revert. In short it was tiedous.
This is why I prefer using `git` on an every day usage. If Bazaar implement the same way of cheap branching than git. I should switch again.

View file

@ -0,0 +1,27 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2010-01-04T12:31:47+02:00
title: Change default shell on Mac OS X
multiTitle:
fr: Changer le shell par défaut sous Mac OS X
en: Change default shell on Mac OS X
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- Mac
- OS X
-----
I just found a way to change the default shell on Mac OS X. This note is mostly for me, but somebody else should find it useful. Just launch the following command:
<div><code class="zsh">
> chsh
</code></div>

View file

@ -0,0 +1,84 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2010-01-12T16:36:40+02:00
title: antialias font in Firefox under Ubuntu
multiTitle:
fr:
en: antialias font in Firefox under Ubuntu
multiDescription:
fr: Voici comment faire pour ne plus utiliser les fontes Microsoft© sous Linux Ubuntu pour avoir de belles fontes adoucies (anti aliased) qui ne font pas mal aux yeux sous Firefox.
en: How to stop using bad Microsoft© font under Ubuntu Linux in order to user nice anti aliased font under Firefox.
tags:
- Linux
- Ubuntu
- Fonts
-----
How to stop using bad Microsoft© font under Ubuntu Linux in order to user nice anti aliased font under Firefox.
Just modify the <code>/etc/fonts/local.conf</code> with the following code:
<div>
<code class="xml">
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Miscellaneous settings -->
<include ignore_missing="yes">misc.conf</include>
<!-- Define alias -->
<include ignore_missing="yes">alias.conf</include>
<!-- Rules for Microsoft fonts -->
<include ignore_missing="yes">msfonts-rules.conf</include>
<match target="pattern" name="family" >
<test name="family" qual="any" >
<string>Tahoma</string>
</test>
<edit mode="assign" name="family" >
<string>Verdana</string>
</edit>
</match>
<selectfont>
<acceptfont>
<pattern>
<patelt name="family"> <string>Lucida Grande</string> </patelt>
</pattern>
</acceptfont>
</selectfont>
<match target="pattern" name="family" >
<test name="family" qual="any" >
<string>Georgia</string>
</test>
<edit mode="assign" name="family" >
<string>Georgia</string>
</edit>
</match>
<selectfont>
<acceptfont>
<pattern>
<patelt name="family"> <string>Century Schoolbook L</string> </patelt>
</pattern>
</acceptfont>
</selectfont>
</fontconfig>
</code>
</div>

View file

@ -0,0 +1,85 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2010-02-15T11:16:12+02:00
title: All but something regexp
multiTitle:
fr: Expression Régulière pour "Tout sauf un mot"
en: All but a word regexp
multiDescription:
fr: pas de description.
en: no description.
tags:
- regexp
-----
Sometimes you can not simply write:
<div><code class="ruby">
if str.match(regexp) and
not str.match(other_regexp)
do_something
</code></div>
and you have to make this behaviour with only one regular expression. The problem is the complementary of regular languages is not regular. Then, for some expression it is absolutely not impossible.
But sometimes with some simple regular expression it should be possible<sup><a href="#note1">&dagger;</a></sup>. Say you want to match everything containing the some word say `bull` but don't want to match `bullshit`. Here is a nice way to do that:
<div><code class="ruby">
# match all string containing 'bull' (bullshit comprised)
/bull/
# match all string containing 'bull' except 'bullshit'
/bull([^s]|$)|
bulls([^h]|$)|
bullsh([^i]|$)|
bullshi([^t]|$)/
# another way to write it would be
/bull([^s]|$|s([^h]|$)|sh([^i]|$)|shi([^t]|$))/
</code></div>
Let look closer. In the first line the expression is:
`bull([^s]|$)`, why does the `$` is needed?
Because, without it the word `bull` would be no more matched. This expression means:
> The string finish by `bull`
> or,
> contains `bull` followed by a letter different from `s`.
And this is it. I hope it could help you.
Notice this method is not always the best. For example try to write a regular expression equivalent to the following conditional expression:
<div><code class="ruby">
# Begin with 'a': ^a
# End with 'a': c$
# Contain 'b': .*b.*
if str.match(/^a.*b.*c$/) and not str.match(/^axbxc$/)
do_something
end
</code></div>
A nice solution is:
<div><code class="ruby">
/abc| # length 3
a.bc| # length 4
ab.c|
a[^x]b[^x]c| # length 5
a...*b.*c| # length >5
a.*b...*c/
</code></div>
This solution uses the maximal length of the string not to be matched.
There certainly exists many other methods. But the important lesson is
it is not straightforward to exclude something of a regular expression.
---
<small><a name="note1">&dagger;</a>
It can be proved that any regular set minus a finite set is also regular.
</small>

View file

@ -0,0 +1,93 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2010-02-16T10:33:21+02:00
title: All but something regexp (2)
multiTitle:
fr: All but something regexp (2)
en: All but something regexp (2)
multiDescription:
fr: pas de description.
en: no description.
tags:
- regexp
- regular expression
-----
In my [previous post](previouspost) I had given some trick to match all except something. On the same idea, the trick to match the smallest possible string. Say you want to match the string between 'a' and 'b', for example, you want to match:
`a.....<b>a......b</b>....a....<b>a....b</b>....`
Here are two common error and a solution:
<table>
<hr>
<td> Regexp </td>
<td> Match </td>
</hr>
<tr>
<td> `a.*b` </td>
<td> `<b>a.....a......b....a....a....b</b>....` </td>
</tr>
<tr>
<td> `a.*?b` </td>
<td> `a.....<b>a......b</b>....a....<b>a....b</b>....` </td>
</tr>
<tr>
<td> `a[^a]*b` </td>
<td> `a.....<b>a......b</b>....a....<b>a....b</b>....` </td>
</tr>
</table>
The first error is to use the *evil* `.*`. Because you will match from the first to the last. The next natural way, is to change the *greediness*. But it is not enough as you will match from the first `a` to the first `b`. Then a simple constatation is that our matching string shouldn't contain any `a`. Which lead to the last elegant solution.
Until now, that was, easy. Now, how do you manage when instead of `a` you have a string?
Say you want to match:
`&lt;li&gt;...&lt;li&gt;`
This is a bit difficult. You need to match
`&lt;li&gt;[anything not containing &lt;li&gt;]&lt;/li&gt;`
The first method would be to use the same reasoning as in my [previous post](previouspost). Here is a first try:
<pre>
&lt;li&gt;([^&lt;]|&lt;[^l]|&lt;l[^i]|&lt;li[^&gt;])*&lt;/li&gt;
</pre>
But what about the following string: `&lt;li&gt;...&lt;li&lt;/li&gt;`.
That string should not match. This is why if we really want to match it correctly<sup><a href="#note1">&dagger;</a></sup> we need to add:
<pre>
&lt;li&gt;([^&lt;]|&lt;[^l]|&lt;l[^i]|&lt;li[^&gt;])*(|&lt;|&lt;l|&lt;li)&lt;/li&gt;
</pre>
Yes a bit complicated. But what if the string I wanted to match was even longer?
Here is the algorithm way to handle this easily. You reduce the problem to the first one letter matching:
<div><code class="perl">
# transform a simple randomly choosen character
# to an unique ID
# (you should verify the identifier is REALLY unique)
# beware the unique ID must not contain the
# choosen character
s/X/_unique_id_for_capitalized_x_/g
# transform the long string in this simple character
s/<li>/X/g
# use the first method
s/X([^X]*)<\/li>//g
# retransform the choosen character back
s/_unique_id_for_capitalized_x_/X/g
</code></div>
And it works in only 4 lines for any beginning string. This solution should look less *I AM THE GREAT REGEXP M45T3R, URAN00B*, but is more convenient in my humble opinion. Further more, using this last solution prove you master regexp, because you know it is difficult to manage such problems with only a regexp.
---
<small><a name="note1"><sup>&dagger;</sup></a> I know I used an HTML syntax example, but in my real life usage, I needed to match between `` and ``. And sometimes the string could finish with `e::`.</small>
[previouspost]: /Scratch/multi/blog/2010-02-16-All-but-something-regexp--2- "All but something regexp"

View file

@ -0,0 +1,14 @@
-----
# Built-in
filename: feed
extension: xml
layout: feed
# Custom
isHidden: true
reps:
francais:
language: fr
anglais:
language: en
-----

View file

@ -0,0 +1,37 @@
-----
# Built-in
filters_pre:
- erb
- "bluecloth"
# Custom
# l'article n'est pas encore prêt
isHidden: true
kind: article
date: 2009-07-06T16:15:23+02:00
title: MVC explained
multiTitle:
fr: Les raisons du MVC
en: Why MVC?
multiDescription:
fr: Une explication en anglais des raisons pour lesquelles l'architecture MVC a naturellement émergée. Avec la création d'un projet, du début à la fin.
en: Why MVC naturally emerged? To show that we will create a project from the beginning to the end and we'll show how natural it becomes to use an MVC architecture and all benefits. If you don't want to re-invent the wheel, you should read this post.
menupriority: 2
-----
# Why This article and for whom? #
Many website explaining how MVC works. But I can't found one who explain why.
I have difficulties to obey some principle don't know *why* I should use it. And something better than the:
> "Smarter people than you decided you have to do so"
This article is for people who like me want to understand the real motivation of using an MVC architecture and which advantage it gives you.
Let's start making a project from scratch pretending we don't know anything about the MVC architecture. Then let see how we'll naturally derive to an MVC architecture.
<center>
<p> <%= lnkto('&rarr; Next','/blog/mvc/mvc1') %> </p>
</center>

View file

@ -0,0 +1,34 @@
-----
# Custom
kind: article
menupriority: 1
title: MVC explained
multiTitle:
fr: design naïf
en: Naive design
-----
## The naive design ##
Suppose you want to make a simple todo list application.
In your mind you draw a simple scheme:
<pre>
[ ] task 1 X
[ ] task 2 X
[ ] task 3 X
</pre>
If you click on the box, then it should show the task is done.
If you click on the cross, then it should delete the task from
the list.
You then think:
> "Whoa! That's easy!"
You want to be able to use it as fast as possible
and you also want to complexify this model later.
For example, adding dates, contexts and projects...

View file

@ -0,0 +1,56 @@
-----
# Built-in
filters_pre:
- "bluecloth"
# Custom
kind: article
menupriority: 2
title: MVC explained (Let's code it)
multiTitle:
fr: let's code it
en: Let's code it
-----
the purpose of this part is to code the webserver part of your
application. Some really complete framework already exists for that.
newcorps
## Let's code it ##
You choose a programming language (for readability I choosen
Ruby).
First you use a simple HTTP Server library (for simplicity
I choosen webrick)
Here an example of a very minimal HTTP Server. When it receives
a GET request at the port number 2000 at the directory '/' it returns:
<div><code class="html"><html>Content</html></code></div>
Here is the code:
<div>
<code class="ruby" file="minimalHttpServer.rb">
#!/usr/bin/env ruby
require 'webrick'
include WEBrick
s = HTTPServer.new( :Port => 2000 )
class HelloServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res.body = '<html>Content</html>'
res['Content-Type'] = "text/html"
end
end
s.mount("/", HelloServlet)
s.start </code>
</div>
You can try it yourself starting by downloading and starting the ruby program and clicking this [link (http://localhost:2000)](http://localhost:2000/) (You must start the server for this link to work).
I Believe what it does is mostly straightforward

View file

@ -0,0 +1,105 @@
-----
# Built-in
filters_pre:
- "bluecloth"
# Custom
kind: article
menupriority: 3
title: MVC explained (first design cleaning)
multiTitle:
fr: first design cleaning
en: first design cleaning
-----
## first design cleaning ##
If you want your applications to
generate strict XHTML 1.0 web pages you
have to modify your application to put the content
between an *header* and a *footer*.
Naturally, You write directly the header and footer
in the source code of the application.
You also want to initialize with some tasks.
And in order to prepare the future, you separate
the server code from you todo list code.
Then you write a specifical class for the two
*features* of your application.
Your new code will look like:
<div>
<code class="ruby">
class Todo
def content
Print the content of the list
...
todo = new Todo
HEADER="<... code HTML ...>"
FOOTER="<... code HTML ...>"
Class Server
def do_GET
return HEADER + (todo.content) + FOOTER
server = new Server
server.start # and for each GET request execute do_GET</code>
</div>
Here are the details of the modified code:
<div>
<code class="ruby" file="step0.rb">
#!/usr/bin/env ruby
require 'webrick'
include WEBrick
s = HTTPServer.new( :Port => 2000 )
class Todo
def initialize
@todoList=['first task','second task']
end
def content
res='<h1>Todo</h1><ul>'
@todoList.each{|task| res<<='<li>'+task+'</li>'}
res<<='</ul>'
return res
end
end
class Servlet
# you write the common header and footer of all pages
# directly in the source code
@@Header='<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Todo Application</title>
</head>
<body><div id="content">'
@@Footer='</div></body>'
@@Todo=Todo.new
def do_GET(req, res)
res.body = @@Header + @@Todo.content + @@Footer
res['Content-Type'] = "text/html"
end
end
servlet=Servlet.new
s.mount("/"){ |req,res| server.do_GET(req,res) }
trap("INT"){ s.shutdown }
s.start </code>
</div>
For now your application isn't functionnal. But it's great,
you can print your todo list. We just have to add content
at runtime now.

View file

@ -0,0 +1,133 @@
-----
# Built-in
filters_pre:
- "bluecloth"
# Custom
kind: article
menupriority: 4
title: MVC explained (make it usable)
multiTitle:
fr: make it usable
en: make it usable
-----
## Make it usable ##
The app is almost usable. You only need to have a way to
add new tasks and to delete them. Let's do it using
<div>
<code class="html">
http://localhost:2000/?newtask="new task text"
http://localhost:2000/?deletetask=taskNumber </code>
</div>
It is not a so difficult part, you only need a little
code in the `do_GET` function of server to call to correct
Todo methods depending of the request.
And of course code the correponding method in the Todo class.
<div>
<code class="ruby" file="naivetodolist.rb">
#!/usr/bin/env ruby
require 'webrick'
# the Todo class is in an external file
require 'todo.rb'
include WEBrick
s = HTTPServer.new( :Port => 2000 )
class Servlet
# you write the common header and footer of all pages
# directly in the source code
@@Header='<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
lang="fr" xml:lang="fr">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<title>Todo Application</title>
</head>
<body><div id="content">'
@@Footer='</div></body>'
def initialize()
@todo=Todo.new
end
# implement the GET request
def do_GET(req, res)
if req.query['newtask']
@todo.addTask(req.query['newtask'])
elsif req.query['deletetask']
@todo.deleteTask(req.query['deletetask'])
end
res.body = @@Header + @todo.content + @@Footer
res['Content-Type'] = "text/html"
end
end
servlet=Servlet.new
s.mount_proc("/"){ |req,res| servlet.do_GET(req,res) }
trap("INT"){ s.shutdown }
s.start</code>
</div>
Where the TODO class is really simple and coded like this:
<div>
<code class="ruby" file="todo.rb">
class Todo
def initialize
@todoList=['first task','second task']
end
def content
res='<h1>Todo</h1><ul>';
i=0
@todoList.each do |task|
res<<='<li>'+task+
' <a href="?deletetask='+ i.to_s +
'">done</a>'+'</li>'
i+=1
end
res<<='</ul>
<form name="input" action="#" metho="get">
Task: <input type="text" name="newtask"/>
</form>'
return res
end
def addTask(task)
@todoList<<=task
end
def deleteTask(taskNum)
@todoList.delete_at(Integer(taskNum.to_s))
end
end</code>
</div>
Here is the results :
![A screenshot of this minimal application](/Scratch/img/MVCWhy/Screenshot_v0.png "Screenshot naive version")
Now we have separated the server and the todo list into
two different files.
The application's working within only 76 lines of code
Now speak about the problems of this (working) implementation.
What will occurs if you want to change from list to tables for
example or more generally if we want to change the html structure?
You'll have to modify the **Todo** class.
This is why you should separate even more each concepts.

View file

@ -0,0 +1,23 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
title: About
multiTitle:
fr: Contact
en: Contact
menupriority: 5
-----
# How to contact me
<img src="/Scratch/img/about/avatar.png" alt="Avatar" class="left"/>
<span style="font-size: 1.5em; line-height: 2em">
<yann.esposito@gmail.com>
follow me on [twitter](http://twitter.com/yogsototh)
My bookmarks [diigo](http://diigo.com/profile/yogsototh)
</span>
<div class="flush"></div>

View file

@ -0,0 +1,24 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 401
error_message: Authorization required
noSubMenu: true
-----
If you don't have the password or believe it is an error you can mail me at <yann.esposito@gmail.com>.
newcorps
Vous pouvez me contacter par mail: <yann.esposito@gmail.com>.

View file

@ -0,0 +1,20 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 403
error_message: Forbidden
noSubMenu: true
-----
Contact: <yann.esposito@gmail.com>

View file

@ -0,0 +1,26 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 404
error_message: Page not found
noSubMenu: true
-----
The page you're looking at doesn't exists on the server.
If you have followed an internal link, you can tell me by mail <yann.esposito@gmail.com> and I'll fix it as soon as possible.
newcorps
La page que vous recherchez n'est pas présente sur le site.
Si vous avez suivi un lien vous pouvez me prévenir par mail <yann.esposito@gmail.com> et je réparerai ça dès que possible.

View file

@ -0,0 +1,20 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 408
error_message: Request Timed Out
noSubMenu: true
-----
Contact: <yann.esposito@gmail.com>

View file

@ -0,0 +1,20 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 500
error_message: Internal Server Error
noSubMenu: true
-----
Contact: <yann.esposito@gmail.com>

View file

@ -0,0 +1,20 @@
-----
# Built-in
layout: error
filters_pre:
- erb
- bluecloth
# Custom
# menu
is_hidden: true
title: Page not found
multiTitle:
fr: Page non trouvée
en: Page not found
error_number: 503
error_message: Service Unaviable
noSubMenu: true
-----
Contact: <yann.esposito@gmail.com>

View file

@ -1,15 +1,16 @@
---
title: English title
---
<h1 class="first" >A Brand New nanoc Site</h1>
-----
# Built-in
filters_pre:
- erb
- bluecloth
<p>You&#8217;ve just created a new nanoc site. The page you are looking at right now is the home page for your site (and it&#8217;s probably the only page).</p>
# Custom
# menu
title: Welcome
multiTitle:
fr: Bienvenue
en: Welcome
<p>To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p>
<ul>
<li><p><strong>Change this page&#8217;s content</strong> by editing &#8220;content.html&#8221; file in the &#8220;content&#8221; directory. This is the actual page content, and therefore doesn&#8217;t include the header, sidebar or style information (those are part of the layout).</p></li>
<li><p><strong>Change the layout</strong>, which is the &#8220;default.txt&#8221; file in the &#8220;layouts/default&#8221; directory, and create something unique (and hopefully less bland).</p></li>
</ul>
<p>If you need any help with customizing your nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>
noSubMenu: true
-----
Hello and welcome on my personnal website. This is mainly my blog.

54
content/html/en/rss.html Normal file
View file

@ -0,0 +1,54 @@
-----
# Custom
# menu
title: Welcome
multiTitle:
fr: Que sont les flux RSS ?
en: What is RSS?
multiSubTitle:
fr: Comment recevoir des news sans se fatiguer
en: Receive news for the lazy
isHidden: true
-----
When you click on this logo:
<img src="/Scratch/img/menu/rss-128.png" alt="rss"/>
You have the capability to subscribe to my RSS flux. But what it is all about?
You can visit [what is rss](http://www.whatisrss.com) or even better look this cool video: [RSS explained](http://www.youtube.com/watch?v=0klgLsSxGsU).
newcorps
## My explanation
It is an easy way to aggregate all the update made on websites you like in a single place. You'll never have to surf many website to see if there is news on a website.
### choose an aggregator
To begin, you must choose an RSS client called *aggregator*. There is many online clients: website which will present the news in a fancy way.
Personally I use [Netvibes](http://netvibes.com). I tried a bunch, and it is by far the best - In My Humble Opinion.
Of course [Google](http://google.com) has a client named [Google Reader](http://google.com/reader).
It is great for content you never want to forgot some article. It is not really useful when you have to handle flux generating many news per day.
### Subscribe to some website news
Once you have chosen your aggregator, you only have to subscribe to websites you like. Do do this, you only have to click on the RSS icon in the top bar of your navigator. Or generally a nice icon is shown into the page you're reading.
### Get the news
Now, you'll only have to use your RSS client. And you'll see all news on all subscribed websites. There is no more need to surf many websites. All news which interest you are in the same place.

View file

@ -0,0 +1,45 @@
-----
# Built-in
filters_pre:
- "bluecloth"
# Custom
title: validation
isHidden: true
multiTitle:
fr: Validation
en: Validation
menupriority: 500
-----
One word to explain why there is some validation errors.
I wanted to use `box-shadows` and `border-radius`.
Then here I prefered pragmatism against dogmatism.
Using these properties broke my validation
but work really well in the two most recent and main browsers
(Safari&nbsp;4 and Firefox&nbsp;3.5 at the time I'm writing these lines).
If you don't use these browser the page is
correctly displayed but not with all the 'eyecandy' effects.
I believed in the benefits of <abbr title="Cascading Style Sheet">CSS</abbr>
validation, this is why there is alway the
<abbr title="Cascading Style Sheet">CSS</abbr> validation link on my pages.
And all <abbr title="Cascading Style Sheet">CSS</abbr> validate except
for properities beginning by `-moz` and `-webkit`.

View file

@ -0,0 +1,99 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
title: About
multiTitle:
fr: À propos
en: About
menupriority: 4
-----
## Pour faire connaissance
![Une photo de moi](/Scratch/img/about/yann1.jpg)
<div class="en">
<desc miscellanious informations>
Name : Yann Esposito ::
Education : Post Ph. D. in Computer Science ::
School : Université de Provence ::
Job : IT at Sophia Antipolis (France) ::
</desc>
</div>
<div class="en">
</div>
<div class="fr">
<desc informations générales>
Nom : Yann Esposito ::
Diplôme : Doctorat d'Informatique ::
École : Université de Provence ::
Emplois : Informaticien à Sophia Antipolis ::
</desc>
</div>
Livres que j'aime :
- Goëdel, Escher &amp; Bach *[Hofstadter]*
- On Numbers And Games *[Conway]*
- Baudolino *[Eco]*
Films que j'aime :
- Eraserhead *[Lynch]*
- Mullholland Drive *[Lynch]*
- Le festin nu *[Cronenberg]*
- eXistenZ *[Cronenberg]*
[Mes sites préférés](http://diigo.com/profile/yogsototh)
newcorps
## En deux mots
<en>
Im a passionate guy. Passionate about
- Computer Science: [Ive got a post Ph. D. degree in Computer Science](http://yann.esposito.free.fr/recherche.php).
- Programming: [I developed two scientific apps](http://yann.esposito.free.fr/logiciels.php), [two Mac screen savers](/YBlog/Softwares.html),
- Computer Security: [I designed a secure web protocol (similar to TOR)](http://yann.esposito.free.fr/enseignement/rez0.php#projet), [a method to securely remember strong passwords](/YBlog/Computer/Entries/2008/7/30_Easy,_secure_and_portable_password_management_system.html) ([programmed a dashboard widget](/YBlog/YPassword.html) and a shell script to use this method).
</en>
<fr>
Je suis un passioné. Passioné par :
- L'informatique scientifique : [j'ai un doctorat en Informatique](http://yann.esposito.free.fr/recherche.php?lang=fr) ;
- Programmation: j'ai développé [deux applications scientifiques](http://yann.esposito.free.fr/logiciels.php) ainsi que des [éconimiseurs d'écran pour Mac](/YBlog/Softwares.html).
- Sécurité informatique: j'ai modélisé [un protocole sécurisé (similaire à TOR)](http://yann.esposito.free.fr/enseignement/rez0.php#projet), [une méthode pour gérer de façon sécurisé ses mots de passes](/YBlog/Computer/Entries/2008/7/30_Easy,_secure_and_portable_password_management_system.html), un [widget](/YBlog/YPassword.html) et un script shell pour utiliser cette méthode.
</fr>
<en>
But before all, I love to learn. For example, I learned many programming languages: `C`, `C++`, `Objective-C`, `Python`, `Java`, `Perl`, `awk`, `bash`, `zsh`, `LaTeX`, `Metapost`, `camL`... And Ive got the same passion about computer science research, computer security, philosophy and many other things.
</en>
<fr>
Mais avant tout j'adore apprendre. Par exemple, j'ai appris de nombreux langages de programmation:
`C`, `C++`, `Objective-C`, `Python`, `Java`, `Perl`, `awk`, `bash`, `zsh`, `LaTeX`, `Metapost`, `CamL`... Et j'ai la même passion pour la recherche scientifique, la sécurité informatique, la philosophie et encore pas mal d'autres choses.
</fr>
newcorps
## Ma petite histoire
J'ai eu mon doctorat en Informatique en décembre 2004 au [LIF](http://www.lif.univ-mrs.fr/) (Marseille). Pendant les trois années de ma formation j'ai non seulement fait de la recherche en informatique mais j'ai aussi enseigné à des étudiants de l'Université. J'ai aussi développé un programme informatique dont le but était de vérifier expérimentalement mes résultats théoriques.
J'ai ensuite fait un Post Doctorat au Laboratoire Hubert Curient de Saint-Etienne. Ma mission consistait à développer une application scientifique (SEDiL). Cette application visait comme public des biologistes et devait avoir une interface utilisateur agréable à utiliser.
Ajourd'hui je travaille pour AirFrance(c) via Astek. Ce travail est très diversifié. Il demande la connaissance des technologies Web, CMS mais aussi de la programmation en Perl, JSP, meta-programmation...

View file

@ -0,0 +1,506 @@
-----
# Built-in
filters_pre:
- erb
# Custom
title: Curriculum Vitæ
multiTitle:
fr: Curriculum Vitæ
en: Resume
multiSubTitle:
fr: résumé rapide
en: Short Abstract
menupriority: 1
-----
<div style="text-align: center">
<div class="fr">
<a href="/Scratch/files/cv.pdf">
<img class="inside" src="/Scratch/img/about/cv/cv.png" alt="preview cv"/>
&darr; La version pdf
</a>
</div>
<div class="en">
<a href="/Scratch/files/cv_en.pdf">
<img class="inside" src="/Scratch/img/about/cv/cv.png" alt="preview cv"/>
&darr; pdf version
</a>
</div>
</div>
newcorps
<h1>
Expérience professionnelle
</h1>
<fr>
<desc Expérience professionnelle>
<small>depuis</small> 2007 : Consultant Airfrance, Astek, Sophia Antipolis ::
2006-2007 : Post Doctorat au Laboratoire Hubert Curien, Saint-etienne ::
2004-2006 : ATER, Attaché Temporaire d'Enseignement et de Recherche ::
2001-2004 : Allocataire Moniteur (Étudiant ayant reçu une bourse ministérielle ainsi qu'une bourse permettant d'enseigner en faculté) ::
1999-2000 : Vacataire (enseignant pour DEUG) ::
</desc>
</fr>
<en>
<desc Professionnal background>
from 2007 : Airfrance consultant, Astek, Sophia Antipolis, France ::
2006-2007 : Post PhD in the Laboratory Hubert Curien, Saint-Etienne, France ::
2004-2006 : ATER, (College Degree Teacher) ::
2001-2004 : Allocataire Moniteur (PhD student with a grant + a teach grant) ::
1999-2000 : College degree teaching ::
</desc>
</en>
newcorps
<h1>
Formation
</h1>
<fr>
<desc>
2004 : Doctorat en informatique au
<a href="http://www.lif.univ-mrs.fr"><abbr title="Laboratoire d'Informatique Fondamentale">LIF</abbr></a>,
<a href="http://www.up.univ-mrs.fr/"> Université de Provence</a>,
Marseille (France) ::
2001 : DEA d'informatique ::
2000 : Maîtrise d'informatique ::
1999 : Licence d'informatique ::
1998 : DEUG MIAS (Mathématiques) ::
1995 : BAC S option mathématiques ::
</desc>
</fr>
<en>
<desc>
2004 : PhD Degree in computer science in the
<a href="http://www.lif.univ-mrs.fr"><abbr title="Laboratoire d'Informatique Fondamentale">LIF</abbr></a>,
<a href="http://www.up.univ-mrs.fr/"> Université de Provence</a>,
Marseille (France) ::
2001 : DEA in computer science ::
2000 : Maîtrise in computer science ::
1999 : Licence in computer science ::
1998 : DEUG MIAS (Math) ::
1995 : BAC S ::
</desc>
</en>
newcorps
<h1>
Activités de recherche
</h1>
<h4>
Domaines
</h4>
<en>
<ul>
<li>Machine Learning, </li>
<li>Data Mining, </li>
<li>Grammatical Inference </li>
</ul>
</en>
<fr>
<ul>
<li>Apprentissage automatique ; </li>
<li>Fouille de données ; </li>
<li>Inférence grammaticale </li>
</ul>
</fr>
<h4>
Objets étudiés
</h4>
<en>
<ul>
<li>Markov chains,</li>
<li>Hidden Markov Models, </li>
<li>Multiplicity Automata, </li>
<li>Weighted Transducer, </li>
<li>Tree Weighted Automata, </li>
<li>Tree Edit Distance</li>
</ul>
</en>
<fr>
<ul>
<li>Chaînes de Markov Cachées ; </li>
<li>Automates à multiplicité ; </li>
<li>Transducteurs pondérés ; </li>
<li>Automates d'arbres pondérés ; </li>
<li>Distances d'edition d'arbres</li>
</ul>
</fr>
<h4>
Principaux résultats théoriques
</h4>
<ul class="long">
<li>
Algorithme d'inférence d'automates à multiplicité
qui identifie l'ensemble des langages stochastiques rationels à la
limite avec probabilité 1,
</li>
<li>
savoir si un MA engendre une
distribution de probabilité est indécidable (était ouvert depuis 1977),
</li>
<li>
Algorithme d'inférence d'une sous-classe
non déterministe des <abbr title="Hidden Markov Model">HMM</abbr> qui identifie à la limite avec probabilité 1
</li>
</ul>
<h2>
Outils réalisés
</h2>
<h4><a href="http://yann.esposito.free.fr/sedil.php">SEDiL</a></h4>
<p>
<a href="http://yann.esposito.free.fr/sedil.php?lang=fr">SEDiL</a> :
Programme destiné à apprendre des distances d'éditions entre
des arbres. Érit en JAVA (librairie SWING)
(11 000 lignes commentaires javadoc compris) ;
</p>
<p>
principales fonctionnalités :
</p>
<ul class="petit">
<li>
apprentissage de matrices de coûts
d'éditions,
</li>
<li>
calcul de distance d'édition entre
arbres ou séquences de caractères,
</li>
<li>
visualisation d'arbres ou de séquences,
</li>
<li>
classification en utilisant les K plus proches
voisins,
</li>
<li>
Génération d'échantillons de couples d'arbres,
</li>
</ul>
<h4> <a href="http://yann.esposito.free.fr/dees.php">DEES</a> </h4>
<fr>
<a href="http://yann.esposito.free.fr/dees.php?lang=fr">DEES</a> :
Programme d'inférence d'automates à multiplicité
écrit en C++ (7<small>500</small> lignes, 10<small>000</small> avec les commentaires) ;
</fr>
<en>
<a href="http://yann.esposito.free.fr/dees.php">DEES</a>:
Software of Multiplicity Automata inference
written in C++ (7.500 lines, 10.000 with comments) ;
</en>
<p>
Principales fonctionnalités :
</p>
<ul class="petit">
<li>
Inférence d'automates à multiplicité,
</li>
<li>
Inférence d'automates probabilistes
résiduels (inférence de Chaînes de Markov cachées ;
apprentissage des paramètres et de la <b>structure</b>),
</li>
<li>
Inférence d'automates probabilistes déterministes,
</li>
<li>
Algorithme de Baum Welch
(Apprentissage des paramètres d'un
<a href="http://fr.wikipedia.org/wiki/Automate_de_Markov_%C3%A0_%C3%A9tats_cach%C3%A9s">
<abbr title="Hidden Markov Model">HMM</abbr></a> à partir
d'un échantillon de séquences),
</li>
<li>
Exportation au format
<a href="http://www.graphviz.org">GraphViz</a>,
</li>
<li>
Génération d'échantillons à partir d'un MA,
</li>
<li> et biens d'autres... </li>
</ul>
newcorps
<h1>
Publications scientifiques
</h1>
<desc>
Journaux internationaux
:
[Fundamenta&nbsp;Informaticæ,&nbsp;2008]
[Pattern&nbsp;Recognition,&nbsp;2004]
::
Journaux nationaux
:
[JEDAI&nbsp;2003]
::
Conférences internationales
:
[ECML&nbsp;2008] [ICGI&nbsp;2006] [COLT&nbsp;2006] [COLT&nbsp;2004]
[ICALP&nbsp;2003] [ICGI&nbsp;2002] ::
Conférences nationales : [CAp'06] [CAp'04] [CAp'03] ::
Workshop : [TAGI'05] ::
Rapport de thèse
: [Université&nbsp;de&nbsp;Provence&nbsp;2004] ::
</desc>
newcorps
<h1>
Compétences
</h1>
<desc>
Langages de programmation
:
<ul class="strong horizontal">
<li> Perl, </li>
<li> Ruby, </li>
<li> Awk, </li>
<li> Python, </li>
<li> Java, </li>
<li> C++, </li>
<li> C, </li>
<li> Objective-C, </li>
<li> PHP, </li>
<li> scripts shell (zsh et bash), </li>
<li> LaTeX, ConTeXt, Metapost </li>
</ul>
<ul class="horizontal">
<li> CamL </li>
</ul>
::
WEB :
<ul class="horizontal">
<li> HTML, </li>
<li> XHTML, </li>
<li> CSS, </li>
<li> SVG, </li>
<li> PHP, </li>
<li> MySQL, </li>
<li> PostGreSQL </li>
</ul>
::
Réseaux
:
<ul class="horizontal">
<li> Ethernet, </li>
<li> TCP/IP, </li>
<li> UDP, </li>
<li> DHCP, </li>
<li> DNS, </li>
<li> tcpdump, </li>
<li> ethereal, </li>
<li> VPN </li>
</ul>
::
Sécurité
:
<ul class="horizontal">
<li>
Cryptographie,
</li>
<li> PGP, GPG, </li>
<li>
Réseaux Anonymes,
</li>
<li> Sécurité des réseaux</li>
</ul>
::
Gestion de projet
:
<ul class="horizontal">
<li> UML, </li>
<li> Merise, </li>
<li> SVN, </li>
<li> CVS </li>
</ul>
::
API
:
<ul class="horizontal">
<li> System V, </li>
<li> POSIX, </li>
<li> STL (C++), </li>
<li> Cocoa (Mac OS X) </li>
</ul>
::
Outils
:
<ul class="horizontal">
<li> Entreprise Miner (SAS), </li>
<li> Weka, </li>
<li> Quartz Composer </li>
</ul>
::
Méthodes d'apprentissage
:
<ul class="horizontal small">
<li>
Selection&nbsp;d'attributs,
</li>
<li>
Naïve&nbsp;Bayes,
</li>
<li>
Arbres&nbsp;de&nbsp;décisions,
</li>
<li>
K&nbsp;plus&nbsp;proches&nbsp;voisins (KPP),
</li>
<li>
Chaînes&nbsp;de&nbsp;Markov (bigrammes,&nbsp;trigrammes,&nbsp;...),
</li>
<li>
Chaînes&nbsp;de&nbsp;Markov&nbsp;cachées (<abbr title="Hidden Markov Model">HMM</abbr>),
</li>
<li>
Réseaux&nbsp;de&nbsp;neurones (Perceptron&nbsp;multicouches),
</li>
<li>
SVM,
</li>
<li>
Boosting
</li>
</ul>
::
</desc>
newcorps
<h1>
Divers
</h1>
<h4>
Projet réseaux
</h4>
<p>
J'ai conçut avec
<a href="http://www.lif.univ-mrs.fr/~egodard"> Emmanuel Godard </a>
un protocole de
<a href="http://www.lif.univ-mrs.fr/~esposito/enseignement/rez0.php">
réseaux anonymes</a>.
</p>
<h4>
Développements Mac
</h4>
<p>
Parmis les
<a href="/YBlog/Softwares.html" >programmes pour Mac</a> que j'ai
réalisé ; certains sont disponibles au public.
</p>
<h4> Web </h4>
<p>
<%= lnkto("Vous pouvez voir ici les détails sur la création de ce site web","/blog/nanoc"); %>.
</p>

View file

@ -0,0 +1,38 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
# menu
title: Old
multiTitle:
fr: Autres sites
en: Other stuff
menupriority: 2
-----
<table class="darkimpact">
<tr><td><a href="/Softwares/Welcome.html">&#x27A8; Applications Mac</a></td></tr>
<tr><td>
<span class="en"><a href="http://yann.esposito.free.fr/recherche.php?css=blue.css&amp;lang=en">&#x27A8; Research</a></span>
<span class="fr"><a href="http://yann.esposito.free.fr/recherche.php?css=blue.css&amp;lang=fr">&#x27A8; Recherche</a></span>
</td></tr>
</table>
## Obsolètes
<table class="darkimpact">
<tr><td> <a href="/YBlog">&#x27A8; iWeb</a></td><td><small>&#x271E; 2009</small> </td></tr>
<tr><td> <a href="http://yann.esposito.free.fr">&#x27A8; Étudiant</a></td><td><small>&#x271E; 2007</small> </td></tr>
</table>
newcorps
# Password required
<div class="impact">
<a href="/Perso">&#x27A8; Famille &amp; Photos</a></sup>
</div>

View file

@ -0,0 +1,57 @@
-----
# Built-in
filters_pre:
- erb
- bluecloth
# Custom
# menu
title: Technical details
multiTitle:
fr: Détails techniques
en: Technical details
multiSubTitle:
fr: Comment ce site vie.
en: How live this website.
menupriority: 3
-----
Ce site a été réalisé à partir de rien ou presque. Quasiment toutes les
pages ont été codées avec [Vim](http://www.vim.org) et engendrées
avec [nanoc](http://nanoc.stoneship.org).
<p>
Les images ont été faites avec
<a href="http://inkscape.org">Inkscape</a> et
<a href="http://gimp.org">Gimp</a>.
J'utilise <a href="http://git-scm.com">Git</a>
comme
<a href="http://en.wikipedia.org/wiki/Distributed_Concurrent_Versions_System"><abbr title="Système de Versions Concurentes Décentralisées">DCVS</abbr></a>.
</p>
Les commentaires de blog sont gérés par
<del>[disqus](http://disqus.com)</del> [intense debate](http://intensedebate.com). Ainsi je n'ai besoin pour héberger mons site que
d'un serveur de pages statiques. Ce qui a de nombreux avantages.
Principalement concernant la charge et la sécurité du serveur.
<p>
Si vous n'avez pas tout compris, rappelez-vous simplement que je n'utilise
que des outils <a href="http://fr.wikipedia.org/wiki/OpenSource">Opensource</a>
et que j'ai conçu ce site quasiment <em>ex nihilo</em>.
</p>
Si au contraire vous voulez connaitre tous les détails je vous suggère
d'aller lire mon <%= lnkto( "article concernant nanoc","/blog/nanoc") %>.

55
content/html/fr/blog.html Normal file
View file

@ -0,0 +1,55 @@
-----
filters_pre:
- erb
- bluecloth
- frenchspace
filters_post:
- ytypo
- multilang
- multicorps
- firsthi
# Custom
kind: blog
title: Blog
multiTitle:
fr: Blog
en: Blog
menupriority: 2
-----
<div>
<%= tagCloud %>
</div>
newcorps
## Un petit mot sur le contenu
Vous trouverez ici des articles qui sont pour la plupart
écrits en anglais et qui sont techniques.
Certain sont justes là pour me souvenir de petits trucs, que
d'autres pourraient trouver utiles. Mais il y a aussi de
long articles techniques qui vont un peu plus dans les détails.
---
Je fais de mon mieux pour traduire chaque page en anglais et en français.
Cependant, ce n'est pas toujours évident.
Il m'arrive de faire de nombreuses fautes d'orthographes, des erreurs typographiques et autres.
<strong> Merci de ne pas me juger sur ces erreurs et de ne pas oublier que le fond est plus important que la forme. </strong>
L'impression que ce site laisse de moi n'est certainement pas l'impression que je vous laisserais si on se rencontrait.
Je vous souhaite de trouver ce que vous cherchez sur ce site.

View file

@ -0,0 +1,41 @@
-----
# Custom
date: 2008-10-10T16:15:23+02:00
kind: article
title: Nanoc
multiTitle:
fr: nanoc
en: nanoc
multiDescription:
fr: Il ne s'agit pas exactement d'un CMS, mais plutôt d'un *système* de gestion de pages statiques. Voici la présentation de l'outil que j'utilise pour créer ce site.
en: It is not exactly a CMS. But a Framework to generate static web pages. It is a short presentation of the software I use to make this website.
multiSubTitle:
fr: Nanoc pour ce site
en: How I used it for this website
menupriority: 1
-----
Qu'est-ce que nanoc ?
=============================================
Il ne s'agit pas exactement d'un
<abbr title="Content Management System">CMS</abbr>,
mais plutôt d'un *système* de gestion de pages statiques.
Il faut programmer sois-même les pages web,
le code pour engendrer les menus...
J'ai programmé des filtres pour rendre ce site multilangue par exemple
Vous pourrez trouver beaucoup d'informations sur
le [site officiel de nanoc](http://nanoc.stoneship.org).

View file

@ -0,0 +1,135 @@
-----
# Built-in
# Custom
kind: article
title: An ultraviolet test
multiTitle:
en: Ultraviolet
fr: Ultraviolet
multiSubTitle:
fr: les test du plugin ruby
en: ruby plugin tests
-----
<h1>
Comment intégrer Ultraviolet avec nanoc
</h1>
fr:
J'ai cherché sur Internet et j'ai trouver plusieurs
indications, malheureusement, elles ne sont plus
d'actualité avec la dernière version de nanoc.
:
Dans un premier temps il faut installer Ultraviolet :
<div>
<code class="zsh">
#!/usr/bin/zsh
wget http://www.geocities.jp/kosako3/oniguruma/archive/onig-5.9.1.tar.gz
tar zxvf onig-5.9.1.tar.gz
cd onig-5.9.1
./configure
make
sudo make install
sudo gem install ultraviolet
</code>
</div>
newcorps
<en>A ruby code</en><fr>Du code Ruby</fr>
=========================================
<en>A first simple test.</en>
<fr>Voilà le premier exemple simple.</fr>
<div>
<code class="ruby">['1','2','3'].each{ |x| puts 'chiffre '+x }</code>
</div>
<fr>Avec création et téléchargement de fichier.</fr>
<en>With file creation and download.</en>
<div>
<code class="ruby" file="ultraviolet.rb">
class UltraVioletFilter < Nanoc::Filter
identifier :ultraviolet
def run(content)
require 'rio'
require 'rubygems'
require 'uv'
code_rule = %r{(<code class="(.+?)"( file="(.+?)")?>(.+?)<}+%{/code>)}m
content.gsub!(code_rule) do |full|
# original, lang, filename, code = full[0], full[1], full[3], full[4]
original, lang, filename, code = $1, $2, $4, $5
if lang =~ /^(zsh|bash|sh|csh|shell)$/
lang='shell-unix-generic'
end
# Create a plaintext file version for download.
codeprefix=''
codesuffix=''
if filename
webpath = '/Scratch/multi'+@page.path
code_path = [@site.config[:output_dir], webpath, 'code']
url = webpath + 'code/' + filename
if (url == @url)
puts %{erreur de redo : #{url}}
break
end
@url=url
copy_text_to_file(code, filename, code_path)
codeprefix=%{<div class="file"><a href="#{url}"> &#x27A5; #{filename} </a></div><div class="withfile">\n}
codesuffix=%{\n</div>}
end
# Substitute the un-highlighted code with the highlighted code.
codeprefix+Uv.parse(code, "xhtml", lang, false, @site.config[:ultraviolet_theme])+codesuffix
end
content
end
private
def copy_text_to_file(str, fname, dir)
if @page_rep.name == :default then
dest_rio = rio(dir).mkpath
frio = rio(dir, fname).delete
frio << str
puts "\t\twrote file #{dir}/#{fname}"
end
end
end
</code>
</div>
newcorps
<en>A zsh code</en> <fr>Du code zsh</fr>
========================================
<fr>Un exemple en zsh.
J'ai fait en sorte de pouvoir utiliser le tag
<tt>zsh</tt> au lieu du compliqué <tt>shell-unix-generic</tt>
</fr>
<en>A simple zsh example. I made some modification in order to
use the <tt>zsh</tt> tag instead of the too much
complicated <tt>shell-unix-generic</tt></en>
<div>
<code class="zsh">
for fic in **/*(.); do
if [[ ! -x $fic ]]; then
chmod u+x $fic
fi
exec $fic
done
</code>
</div>

View file

@ -0,0 +1,73 @@
-----
# Custom
date: 2009-07-22T16:15:23+02:00
kind: article
title: Better than Grep
multiTitle:
fr: Mieux que grep
en: Better than Grep
multiDescription:
fr: grep avec de la coloration syntaxique sur de multiples fichiers. Pour rechercher une chaine de caractère efficacement dans de nombreux fichiers.
en: grep on multiple files with syntax coloring in one simple command. In order to find efficiently a string within many files.
menupriority: 1
-----
# Mise à jour
Comme [Andy Lester](http://www.theworkinggeek.com) me l'a fait remarqué. [`ack`](http://betterthangrep.com) est un simple fichier perl qu'il suffit de copier dans son répertoire personnel `~/bin`. Maintenant j'ai `ack` sur mon serveur professionnel.
Il suffit d'aller sur [http://betterthangrep.com](http://betterthangrep.com) pour le télécharger.
Sincèrement, je ne comprend pas qu'`ack` ne soit pas une commande implémentée par défaut sur les systèmes UNIX. Je ne peux vraiment plus m'en passer, il m'est devenu aussi essentiel qu'un `which` ou un `find`.
newcorps
Mieux que grep
=============================================
Un des mes usages principaux de `grep` est
<div>
<code class="zsh">
grep 'pattern' **/*(.)</code>
</div>
La plupart du temps c'est suffisant, mais ajouter de la coloration
améliore beaucoup l'utilité de cette commande. Il existe déjà un outil
pour ça : il s'appelle `ack-grep` sous Ubuntu.
Comme je ne peux pas l'installer sur le serveur de mon entreprise,
j'en ai créé un moi-même en quelques lignes :
<div>
<code class="zsh" file="ack">
#!/usr/bin/env zsh
(($#<1)) && { print 'usage: ack "regexp"' >&2; exit 1 }
listeFic=( **/*(.) )
autoload zargs
zargs -- $listeFic -- grep $1 | perl -ne 'use Term::ANSIColor;
if (m/([^:]*)(:.*)('$1')(.*)/) {
print color("green").$1;
print color("reset").$2;
print color("black","on_yellow").$3;
print color("reset").$4."\n";
} '
</code>
</div>
Pour mon utilisation personnelle et celle de mon équipe
c'est suffisant. J'espère que ça pourra vous aider.

View file

@ -0,0 +1,108 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu)
en: Lost Highway demystified (a bit)
multiDescription:
fr: ...Il faut garder à l'esprit qu'il n'existe pas une seule interprétation possible et cohérente du film. Seul David Lynch pourrait donner l'explication complète du film.<br/>Je donne quelques clés aidant à suivre le film sans être complètement perdu.Ces clés devraient vous aider à vous faire votre propre idée du film...
en: ...this movie must be watched knowing you'll cannot resolve the solution. At his best you'll can suggest an interpretation close to the one of David Lynch.<br/>I believe I had found a coherent interpretation which allow to follow the movie without being totally lost. I believed it can give the keys necessary to make its own idea of the movie...
-----
<%= blogimage( 'Lost Highway' , 'intro.jpg' ) %>
Lost Highway ne laisse pas indiférent. Le revoir ne lasse pas même s'il parrait complètement obscur. C'est une des forces de David Lynch.
!!fr!!
La première fois que j'ai vu Lost Highway je me suis senti un peu perdu.
J'en ai alors cherché le sens. Voilà ce que j'ai pu trouver sur Internet :
- Fred passe un pacte avec le diable incarné par l'homme en noir ;
- l'homme mystérieux est une (la) caméra ;
- seule la première histoire est vrai, la suite étant l'imagination de Fred ;
sans compter les multiples avis trouvés sur les forums. Tout cela ne me paraissait pas convaincant.
J'ai alors réussi à trouver deux articles (en anglais) qui proposent de bien meilleures interprétations. Mais aucun des deux ne m'a complètement convaincu :
- le permier est sur [mediacircus](http://www.mediacircus.net/lh.html),
- le second qui développe presque la même interprétation que la première est vraiment très détaillé sur [jasonweb](http://www.jasonsweb.com/LostHighway/main.htm).
Il faut garder à l'esprit qu'il n'existe pas une seule interprétation possible et cohérente du film. Seul David Lynch pourrait donner l'explication complète du film.
Je donne quelques clés aidant à suivre le film **sans être complètement perdu**.
Ces clés devraient vous aider à vous faire votre propre idée du film.
!!!!
!!en!!
The first time I watched Lost Highway, I was a bit lost.
Here some of explanations of Lost Highway I found on the Internet:
- Fred make a pact with the devil incarnated by the *Mysterious Man*,
- *Mysterious Man* is a video camera,
- Just the first part of the story is real. The rest is in the Fred's imagination,
and I don't speak about many point of view found in forums.
I finished to find two good site talking about this movie. But none of them still totally convinced me:
- the first is [mediacircus](http://www.mediacircus.net/lh.html),
- the second which state almost the same interpretation about the movie and explain with even more details is on [jasonweb](http://www.jasonsweb.com/LostHighway/main.htm)
Nonetheless, this movie must be watched knowing you'll cannot resolve the solution. At his best you'll can suggest an interpretation close to the one of David Lynch.
I believe I had found a coherent interpretation which allow to follow the movie **without being totally lost**. I believed it can give the keys necessary to make its own idea of the movie.
!!!!
## Le test de Rorschach
<%= leftblogimage( 'test de Rorschach','rorschach.gif' ) %>
!!fr!!
À l'instar du protagoniste chacun voit dans ce film ce qu'il a envie d'y voir. Nous pouvons nous y perdre simplement parce que nous pouvons nous perdre dans notre propre esprit. C'est une invitation à la réflexion. Regarder ce film c'est un peu comme passer un test de Rorschach. Qu'y voit-on ? Chacun y met un peu de sa propre personnalité dans l'explication du film.
- Si vous êtes un mystique, vous verrez dans l'homme mystérieux un démon
- si vous êtes plus psychanalytique vous y verrez une partie inconsciente du protagoniste...
En général en essayant d'expliquer ce film, on se perd un peu dans notre pensée. Et souvent on échoue à tout expliquer. Il y a toujours un point qui rend la construction incohérente avec le film. C'est pourquoi rechercher une explication unique est un entreprise vaine.
!!!!
!!en!!
Like the protagonist, everybody see what he want to see in this movie. It is an invitation to think. Watch this movie is a little like watch a Rorschach's test. What do we see in it? Everybody put its own personnality in the interpretation of the movie.
- If you are mystic, you'll see in the mysterious man a devil,
- If you are more psychanalytics, you'll see an inconscient part of the protagonist...
Generally, we stay in this movie and we fail explaining everything. There is almost always a point that don't fit within the interpretation of the movie. This is why trying to find a unique good interpretation of this movie is a mistake.
!!!!
## Interprétation &ne; Explication
Je donne une **interprétation** et non pas une **explication**. Ma vision des choses, me semble cohérente. Cependant il est très probable que mon adhésion au film soit très différente de la votre.
Il y a certainement beaucoup d'autres explications qui restent cohérentes.
J'écris cet article, parce que j'ai l'impression d'en avoir trouver une qui marche pour plus de 97% du film (peut-être 100%, mais j'en doute, il faudrait que je le revois encore une fois).
<div style="text-align: center">
<span style="font-size: 2em"> <a href="./03_losthighway_1/"><fr>Lire la suite</fr><en>Read more</en></a></span>
</div>

View file

@ -0,0 +1,71 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Les clefs du film
en: Lost Highway demystified (a bit) - Movie's keys
-----
# Les clefs du films
<div class="encadre" style="text-align: center">
<strong>
Tout se passe dans la mémoire de Fred
</strong>
</div>
Tout d'abord, il est clair que comprendre le film comme simplement un film fantastique ne fonctionne pas. En suivant ce point d'entrée on en fini pas de se heurter à des détails incompréhensibles.
Mon *hypothèse de départ* c'est que le film dépeint la représentation de la réalité que s'en fait Fred.
Chaque fois qu'il essaye d'échapper à la réalité, celle-ci finira par le rattraper.
Fred a commis un acte horrible, un meurtre, et essaye de *réparer* sa mémoire pour accepter son acte. Il va alors s'inventer des *réalitées alternatives*.
- Dans un premier temps il tue sa femme (Renée) parce qu'elle le trompe.
- Dans la deuxième partie, il est plus faible. La version blonde de Renée va le manipuler pour tuer Dick Laurent.
- Dans la troisième partie il tue Dick Laurent
## Quelle est la validité de ce choix ?
Cet interprétation me semble valide à cause du dialogue au début du film avec les policier qui demande au protagoniste s'il a une caméra :
> - &ndash; Do you own a video camera?
> - &ndash; No, Fred hates them.
> - &ndash; I like to remember things my own way.
> - &ndash; What do you mean by that?
> - &ndash; How I remember them, not necessarily the way they happened.
!!fr!!
Ce que l'on peut traduire approximativement par :
> - &ndash; Avez-vous une caméra ?
> - &ndash; Non, Fred les détestes.
> - &ndash; J'aime me rappeler les choses à ma façon.
> - &ndash; Qu'entendez-vous par là ?
> - &ndash; Je me rapelle des choses pas nécessairement comme elles se sont passées.
!!!!
Ainsi, ce que l'on voit n'est pas la réalité, mais la réalité telle que le conçoit Fred. Il est donc le Dieu de cette réalité. Ainsi les interprétations mystiques faisant intervenir le Diable ont une certaine validité.

View file

@ -0,0 +1,41 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 2
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Qui est l'homme mystérieux ?
en: Lost Highway demystified (a bit) - Who is the mystery man?
-----
## Qui est l'homme mystérieux ?
<%= leftblogimage( "l'homme mystérieux" , "mysteryman.jpg" ) %>
Qui est donc ce personnage étrange et inquiétant ?
Un être capable d'ubiquité qui dit être invité par Fred dans sa maison ?
Sans sourcils, le visage blême, les yeux écarquillés fixant sans relâche les faits et gestes de Fred.
C'est certainement une des clés du film.
À mon avis, il représente la partie *mauvaise* de Fred.
Certainement la jalousie. Si j'étais Catholique je dirai Satan, le tentateur.
Il n'agit jamais, mais ne fait qu'observer et filmer.
Par contre c'est lui qui donne les armes à Fred pour tuer Dick Laurent.
Fred l'a laissé entrer chez lui et il ne peut plus s'en débarrasser.
Un peu comme le _Iago_ de Shakespeare est enfermé dans sa jalousie.
Le personnage mystérieux prend toute l'importance, il le ronge de l'intérieur.
Il aide Fred à accomplir les actes de violences et aussi l'oblige à se souvenir de la réalité.
Quand il fait l'amour à Renée il voit le visage de l'homme mystérieux à la place du visage de sa femme. En réalité, il s'agit de la même personne d'après Fred. Ce serait donc elle qui est la source de son mal intérieur.

View file

@ -0,0 +1,36 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 3
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Qui filme et dépose les cassettes ?
en: Lost Highway demystified (a bit) - Who's at the origin of the video tapes?
-----
## Qui filme et dépose les cassettes ?
C'est certainement l'homme mystérieux (ou Fred lui-même) qui est à l'origine de ces cassettes.
Le rôle des cassettes est double :
!!fr!!
+ Rappeler à Fred la réalité. D'après Fred les cassettes video correspondent à la réalité. Il a beau essayer de se cacher la réalité, les cassettes finissent par aller jusqu'au bout et il se voit en train de tuer Renée.
+ La cassette peut aussi faire référence aux cassettes de films pornographique dans laquelle Renée a peut-être tournée dans la réalité ?
!!!!
!!en!!
+ Remember the reality to Fred. From Fred point-of-view, video tapes are the reality. He tries to forget reality. But, finally, the video tapes go to the end: the murder of his wife.
+ It may also be a reference to pornographic video tapes, made by Renee.
!!!!

View file

@ -0,0 +1,71 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 4
date: 2009-08-04T19:00:00+02:00
title: a try to demystify 'Lost Highway'
multiTitle:
fr: Lost Highway démystifié (un peu) - Que s'est-il vraiment passé ?
en: Lost Highway demystified (a bit) - What really happened?
multiDescription:
-----
## Que s'est-il vraiment passé ?
Ici, tout n'est pas donné, on garde une assez grande liberté. Mais on a des indices.
### Hypothese n°1
!!fr!!
Je dirais que le protagoniste est un garagiste qui est tombé amoureux d'une actrice porno. Il l'a certainement vu la première fois accompagnant le fameux Dick Laurent. Voyant qu'il ne peut pas l'avoir pour lui, fou de jalousie il tue Dick Laurent dans un motel où celui-ci à couché avec Renée.
On a la liberté de décider s'il a vraiment tué la femme ou pas.
Dans ma première vision du film, j'avais envie de dire qu'il ne la tue pas. Mais qu'une fois le meurtre commis, il va chez elle, sonne pour lui annoncer la mort de Dick Laurent. Il a alors juste le temps de s'enfuir, la police à ses trousses.
!!!!
!!en!!
The protagonist is a garagist fallen in love with a porno actress. He believe the producer is the bad guy who go again his will. Then he kills Dick Laurent.
!!!!
### Hypothese n°2
La première partie resemble à la réalité. Il a vraiment tué sa femme. Il se fait arrété et condamné (certainement à mort). Par contre on ne sait pas s'il est aussi allé tuer Andy.
## alors c'est laquelle ?
La seconde hypothèse me semble plus vraisemblable, car il y a plus de recoupements possibles.
La première me semble aussi cohérente. C'est cette première hypothèse que j'avais émise lors de mon premier visionnage du film.
Ce qui montre la force de ce film c'est de se dire qu'il y a de nombreuses autres hypothèses qui pourraient aussi bien fonctionner. C'est le fameux [effet Rashomon](http://en.wikipedia.org/wiki/Rashomon_effect). Plusieurs personnes peuvent décrire de façon cohérentes ce qu'elles ont vu, mais toutes les descriptions sont incohérentes entres-elles.
newcorps
## Conclusion
Il y aurait encore beaucoup à dire sur l'analyse de ce film. Mais il me semble que j'ai rassemblé l'essentiel des clés pour sa compréhension.
Il me semble qu'avoir à l'esprit l'effet "test de Rorschach" est essentiel lors de la visualisation de ce film.
J'aimerai avoir votre opinion ; mon interprétation tient-elle la route ?

View file

@ -0,0 +1,48 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-15T11:00:00+02:00
title: DRM are EVIL
multiTitle:
fr: Les protections anti-copies sont LE MAL
en: DRM are EVIL
multiDescription:
fr: Les protections nuisent à l'utilisateur qui paye (+1)
en: DRM are bad (+1)
tags:
- drm
- protection
- iTunes
- Apple
-----
# Protections anti-copie = Belle connerie (+1)!
Ma femme a acheté pour environ 500€ (au moins) de séries télé sur iTunes. Mais elles s'est trompé pour la première saison de Battlestar Galactica. Qu'elle a téléchargé en anglais. Hors comme les séries sont protégées, on ne peut simplement pas voir la série avec des sous-titres !
<div class="encadre">
<p style="text-align: center; font-size: 5em"><strong>WTF?</strong></p>
</div>
Résultat des courses, ma femme n'achetera plus de séries sur iTunes tant qu'elles resteront protégées par DRM, qu'elle ne pourront pas être gravées sur DVD (pour être regardées sur la télé). Et comme elle est bien moins prompte à acheter des DVD que simplement cliquer sur un bouton.
<div class="encadre">
Ca fera nettement moins d'argent pour vous les <strong>ayant-droits</strong>&nbsp;!!!
</div>
Et ma femme ne pourra pas voir ces épisodes. <br/>
C'est ce qu'on appelle une cooperation <strong>'LOSE-LOSE'</strong>.

View file

@ -0,0 +1,52 @@
-----
# Custom
# isHidden: true
kind: article
menupriority: 1
date: 2009-08-17T14:00:00+02:00
title: Git remote branch creation
multiTitle:
fr: Création de branches avec Git
en: Git branch Creation
multiDescription:
fr: J'utilise Git pour synchroniser des projets personnels. C'est pourquoi quand je crée une branche locale je souhaite quasiment toujours qu'elle soit aussi créée en <em>externe</em> (remote).<br/>Voici le script que j'utilise pour accomplir cette tâche ...
en: I use git to synchronize personnal projects. Therefore, most of time, when I create a local branch I want it to be created remotely.<br/>Here is the script I use to achieve that&hellip;
tags:
- git
- branch
- local
- remote
-----
## Créer une branche Git externe facilement
J'utilise Git pour synchroniser des projets personnels.
C'est pourquoi quand je crée une branche locale je souhaite quasiment toujours qu'elle soit aussi créée en *externe* (remote).
Voici le script que j'utilise pour accomplir cette tâche :
<div>
<code class="zsh" file="git-create-new-branch.sh">
#!/usr/bin/env zsh
if (($#<1)); then
print -- "usage: $0:t branch_name" >&2
exit 1
fi
branch=$1
git br ${branch}
git co ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
</code>
</div>
Bien sûr, je suppose qu'<code>origin</code> est déjà configurée.

View file

@ -0,0 +1,212 @@
-----
# Custom
# isHidden: true
menupriority: 1
kind: article
date: 2009-08-18T14:44:31+02:00
title: Git for self
multiTitle:
fr: Git en solo
en: Git for self
multiDescription:
fr: J'utilise Git pour des projets personnels gérés à partir de plusieurs oridinateurs. Voici comment concilier les avantages de Git avec un workflow proche de celui de SVN.
en: I use Git for personnal projects on many differents computers. Here is how to use almost the SVN workflow with all advantages of Git.
tags:
- git
- svn
- workflow
-----
<%= blogimage("central architecture","central_architecture.png") %>
J'utilise [Git](http://www.git-scm.org/) pour gérer mes projets personnels.
J'ai un *repository* centralisé et tous mes ordinateurs se synchronisent avec lui.
Cependant, dans la documentation officielle, je n'ai pas trouvé clairement ce que je souhaitais.
En d'autres termes, si vous souhaitez utiliser le type de *workflow* que SVN proposait avec Git (et ses avantages), voici comment procéder.
newcorps
## Initialisation
Disons que j'ai déjà un projet et que je veuille en créer un nouveau.
<div>
<code class="zsh">
cd to/project/directory/
git init
git add
git commit
</code>
</div>
fr:Maintenant tous les fichiers du répertoire <code>to/project/directory/</code> sont *versionnés*. Si vous voulez ignorer certains fichiers il suffit de modifier le fichier <code>.gitignore</code>.
Par exemple voici le mien :
<div>
<code class="zsh">
*.swp
.DS_Store
ikog.py.bak
output/Scratch/assets
output/Scratch/en
output/Scratch/fr
output/Scratch/multi
</code>
</div>
Ensuite, il faut placer ce projet dans un endroit sûr sur Internet.
<div>
<code class="zsh">
git clone --bare . protocol://url/of/the/repository
</code>
</div>
Maintenant à partir de n'importe quel ordinateur, voici ce que vous pouvez faire :
<div>
<code class="zsh">
git clone protocol://url/of/the/repository local_directory
</code>
</div>
et <code>local_directory</code> contiendra un projet à jour.
<div class="encadre"><em>
Je vous conseille de faire la même opération sur l'ordinateur qui à servi à créer le projet de façon à vérifier que tout fonctionne correctement.
</em>
</div>
newcorps
## L'utilisation courante
Pour résumer vous avez maintenant un repository sur Internet et un ou plusieurs ordinateurs lui sont associés. Maintenant il faut que tout soit toujours synchronisé.
Avant de commencer à travailler, la première chose à faire est de récupérer les modification à partir d'Internet vers votre poste local :
<div>
<code class="zsh">
git pull
</code>
</div>
Ensuit vous pouvez travailler en faisant (plusieurs fois) :
<div>
<code class="zsh">
hack, hack, hack...
git add some files
git commit
</code>
</div>
Quang vous voulez envoyez les modifications locales sur Internet, il suffit de faire :
<div>
<code class="zsh">
git push
</code>
</div>
Tout devrait être bon.
Si vous avez des problèmes avec le <code>push</code> et le <code>pull</code> ; vérifiez votre fichier <code>.git/config</code>. Il devrait contenir les lignes suivantes :
<div>
<code class="zsh">
...
[remote "origin"]
url = protocol://url/of/the/repository
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
...
</code>
</div>
## Synchronisation des branches
Bien, maintenant que tout semble bon, il faut encore s'occuper de quelques petites choses (sinon, SVN suffirait).
Git est complètement orienté sur la décentralisation et la création de nouvelles branches sur le même poste. Synchroniser des branches sur plusieurs serveurs différent n'est pas une opération naturelle.
C'est pourquoi j'ai créé deux simples scripts pour automatiser cette opération. Un script pour créer un branche localement et en ligne. Un autre script pour récupérer les branches en lignes qui ne sont pas présente localement.
Ainsi, lorsque je veux créer une nouvelle branche (localement et ligne) ; je lance le script :
<div><code class="zsh">git-create-new-branch branch_name</code></div>
et quand je suis sur un autre ordinateur et que je veux récupérer les branches crées sur un autre poste, j'exécute :
<div><code class="zsh">git-get-remote-branches</code></div>
Voici le code des deux script (en zsh) :
<div>
<code class="zsh" file="git-create-new-branch">
#!/usr/bin/env zsh
if (($#<1)); then
print -- "usage: $0:t branch_name" >&2
exit 1
fi
branch=$1
git br ${branch}
git co ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
</code>
</div>
<div>
<code class="zsh" file="git-get-remote-branches">
#!/usr/bin/env zsh
# recup branches not on local
localbranches=( $(git br | sed 's/\*/ /') )
remoteMissingBranches=( $(git br -r | \
egrep -v "origin/HEAD|(${(j:|:)localbranches})" ) )
for br in $remoteMissingBranches; do
branch=${br#origin/}
print "get remote branch $branch"
git br ${branch}
git config branch.${branch}.remote origin
git config branch.${branch}.merge refs/heads/${branch}
done
</code>
</div>

View file

@ -0,0 +1,34 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-06T17:59:16+02:00
title: Screensaver compilation option for Snow Leopard<sub>&copy;</sub>
multiTitle:
fr: Screensaver compilation option for Snow Leopard<small>&copy;</small>
en: Screensaver compilation option for Snow Leopard<small>&copy;</small>
multiDescription:
fr: no description.
en: no description.
tags:
- screensaver
- Apple
- mac
- Xcode
-----
# How to recompile your screensaver to be Snow Leopard(c) compatible
I upgraded to Mac OS X 10.6 Snow Leopard(c), and my [YClock](/YBlog/YClock.html) screensaver didn't work on it. After searching on google, the problem seems to be just a recompilation away.
Unfortunately, event recompiling it in 64 bit it didn't work either.
After a bit more research (thanks to [ElectricSheep](http://community.electricsheep.org/node/236) ).
I discovered the good parameters for compilation.
<%= blogimage("XCode configuration","xcodeConfig.png") %>
For now I didn't compiled it to work also on Tiger and Leopard. I don't know XCode enought to know how to make the Garbage collector to be disabled on 32 bits version and enabled on 64 bits version.
It was a bit difficult to discover these informations. Hope this post helped someone.

View file

@ -0,0 +1,92 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-07T20:25:56+02:00
title: Configure ssh to listen the port 443 on Snow Leopard
multiTitle:
fr: ssh to Listen 443 on Snow Leopard
en: ssh to Listen 443 on Snow Leopard
multiDescription:
fr: no description.
en: no description.
tags:
- Apple
- mac
- ssh
- security
-----
# Surf everywhere as if you were at home
In order to bypass *evil* company firewall and to surf safely on unsafe <sc>wifi</sc>. I keep an ssh server listening on the port 443.
Then from my laptop or my local computer I just have to launch the marvelous
<div>
<code class="zsh">
ssh -p 443 -D 9050 username@host
</code>
</div>
and a local <sc>socks</sc> proxy listening on port 9050 is launched. The <sc>socks</sc> proxy will transfer local requests via the ssh tunnel. Therefore I can surf locally as if I was on my own computer. I can put password and card number without fear the local <sc>wifi</sc> network to be *sniffed*. I simply need to configure my web browser to user the <sc>socks</sc> proxy on localhost and port 9050.
I get this information from [this post](http://dltj.org/article/ssh-as-socks-proxy/).
# Ssh and Snow Leopard(c)
Here I don't want to talk about how great <sc>socks</sc> proxy via ssh tunneling is but how to configure my local server.
I have Mac with Snow Leopard(c) at home and it is far from enough to modify the `/etc/sshd.config` file. The system use `launchd` to launch starting daemons.
I posted the question on [Apple Discussions](discussions.apple.com) in this [discussion thread](http://discussions.apple.com/thread.jspa?messageID=10141032). Thanks to all guys who helped me. And the solution is:
Create the file <tt>/Library/LaunchDaemons/ssh-443.plist</tt> containing:
<div>
<code class="xml" file="ssh-443.plist">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>local.sshd</string>
<key>Program</key>
<string>/usr/libexec/sshd-keygen-wrapper</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/sshd</string>
<string>-i</string>
</array>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>https</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>SHAuthorizationRight</key>
<string>system.preferences</string>
</dict>
</plist>
</code>
</div>
It is a copy of `/System/Library/LaunchDaemons/ssh.plist` with some modifications:
- the `SockServiceName` from `ssh` to `https`.
- the `Label` from `com.openssh.sshd` to something not existing as `local.sshd`
Tell me if it was helpfull or if you have any question.

View file

@ -0,0 +1,32 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-11T14:27:09+02:00
title: Why I didn't keep whos.amung.us
multiTitle:
fr: Why I didn't keep whos.amung.us
en: Why I didn't keep whos.amung.us
multiDescription:
fr: no description.
en: no description.
tags:
- analytics
- web
-----
I changed from [whos.amung.us](http://whos.amung.us) to [Google Analytics](http://www.google.com/analytics).
Most of time I prefer not to use the same product as everybody and try some new. But this time I believe whosamung.us had too much ads on the page. I had to put their image on my website and they only give then number of user currently on the website, not the number of visits.
This is why I now use google analytics. The only problem, remains for pages with no javascript support.
Then for now:
<div class="encadre">
Theorem:<br/>
<center>
Google Analytics <big><strong>&gt;</strong></big> Who's Amung Us
<center></div>

View file

@ -0,0 +1,285 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-11T14:35:35+02:00
title: Synchronize Custom WebSite with mobileMe
multiTitle:
fr: Héberger son site personnel sur le site mobileMe
en: Synchronize Custom WebSite with mobileMe
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- mobileme
- WebDav
- synchronisation
- zsh
- script
-----
# mise à jour du <small>28/10/2009</small>
J'ai mis à jour mon script [avec une version incrémentale](/Scratch/multi/blog/2009-10-28-custom-website-synchronisation-with-mobileme--2-) bien plus pratique.
En plus depuis l'écriture de cet article Apple(c) semble avoir nettement amélioré la vitesse de ses serveurs en Europe.
newcorps
# WebDav terror
En France l'iDisk d'Apple(c) est très lent. La vitesse d'upload me rapelle l'époque des modem 56k, c'est dire. La plupart du temps les opérations telles que lister le contenu d'un répertoire prennent au moins 30 secondes (pour 15 éléments). Renommer un répertoire échoue presque systématiquement.
Apple(c) utilise des serveurs WebDav pour héberger les fichiers. Le protocole fonctionne sur le port 80 (comme http). Je me suis rendu compte qu'utiliser WebDav via https fontionne bien mieux (2 à 3 fois plus rapide avec moins d'erreurs). Mais, ça reste quand même très lent et insuffisant.
J'*uploade* mes fichiers à partir de mon Mac et de temps en temps à partir d'un PC sous Ubuntu (iDisk monté avec webdavfs).
# Synchroniser de façon sûre
Voici le script que j'utilise pour synchroniser mon site web (non créé avec iWeb(c)) avec le maximum de sécurité. Chaque opération est répétée jusqu'à ce qu'elle fonctionne.
Les idées sont :
- synchronize to a temporary folder then swap the name therefore the website isn't accessible only during the swap time. It takes only the time of two rename.
- reiterate all operations until they work (for example, renaming).
Jusqu'ici j'utilise `rsync` qui n'est en fait pas plus efficace qu'une simple copie `cp` avec WebDav. Je devrais utiliser une méthode pour mémoriser les changements entre chaque publication.
En réalité quand je suis sur mon Mac j'utilise [Transmit](http://www.panic.com/transmit) qui est vraiment très bien et surtout beaucoup plus efficace que le finder pour synchroniser des fichiers. Ensuite, je ne fait que le "swap" des répertoires.
Mon script prend un paramètre `-s` pour ne faire que le "swap". Il prend aussi une option `-a` pour envoyer le fichier `index.html` qui va rediriger vers ma nouvelle page principale (iWeb(c) à la fâcheuse habitude de le remplacer).
Pour utiliser le script vous devriez remplacer la valeur de la variable `mobileMeUser` par votre nom d'utilisateur mobileMe(c).
<div class="fr">
<code class="zsh" file="publish">
#!/usr/bin/env zsh
# Script synchronisant le site sur me.com
# normalement, le site est indisponible le moins de temps possible
# le temps de deux renommages de répertoire
mobileMeUser="yann.esposito"
siteName="siteName"
# Depending of my hostname the
if [[ $(hostname) == 'ubuntu' ]]; then
iDisk='/mnt/iDisk'
else
iDisk="/Volumes/$mobileMeUser"
fi
root=$HOME/Sites/$siteName
destRep=$iDisk/Web/Sites/$siteName
[[ ! -d $root ]] && {
print -- "$root n'existe pas ; vérifiez la conf" >&2;
exit 1
}
[[ ! -d $destRep ]] && {
print -- "$destRep n'existe pas, veuillez remonter le FS" >&2;
exit 1
}
if [[ $1 == '-h' ]]; then
print -- "usage: $0:h [-h|-a|-s]"
print -- " -a sychronise aussi l'index"
print -- " -h affiche l'aide"
print -- " -s swappe simplement les répertoires"
fi
if [[ $1 == '-a' ]]; then
print -- "Synchronisation de l'index (${destRep:h})"
rsync -av $root/index.html ${destRep:h}/index.html
fi
print -- "Root = $root"
print -- "Dest = $destRep"
if [[ ! $1 = '-s' ]]; then
[[ ! -d $destRep.tmp ]] && mkdir $destRep.tmp
print -P -- "%B[Sync => tmp]%b"
result=1
essai=1
while (( $result > 0 )); do
rsync -arv $root/Scratch/ $destRep.tmp
result=$?
if (( $result > 0 )); then
print -P -- "%BEchec du rsync%b (essai n°$essai)" >&2
fi
((essai++))
done
fi
# SWAP
print -P -- "%B[Swap des Répertoires (tmp <=> target)]%b"
essai=1
while [[ -e $destRep.old ]]; do
print -n -- "suppression de $destRep.old"
if ((essai>1)); then
print " (essai n°$essai)"
else
print
fi
((essai++))
\rm -rf $destRep.old
done
print -- " renommage du repertoire sandard vers le .old"
essai=1
while [[ -e $destRep ]]; do
mv $destRep $destRep.old
(($?)) && print -- "Echec du renommage (essai n°$essai)" >&2
((essai++))
done
print -- " renommage du repertoire tmp (nouveau) vers le standard"
print -P -- " %BSite Indisponible%b $(date)"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.tmp $destRep
(($?)) && print -P -- "%B[Site Indisponible]%b(essai n°$essai) Echec du renommage (mv $destRep.tmp $destRep)" >&2
((essai++))
done
print -P -- "\t===\t%BSITE DISPONIBLE%b\t==="
print -- " renommage du repertoire old vers le tmp"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.old $destRep.tmp
(($?)) && print -P -- "Echec du renommage n°$essai" >&2
((essai++))
done
print -P -- " publication terminée"
</code>
</div>
<div class="en">
<code class="zsh" file="publish">
#!/usr/bin/env zsh
# Author: Yann Esposito
# Mail: yann.esposito@gmail.com
# Synchronize with "mobileMe" iDisk account.
mobileMeUser="firstname.lastname"
siteName="siteName"
# Depending of my hostname the
if [[ $(hostname) == 'ubuntu' ]]; then
iDisk='/mnt/iDisk'
else
iDisk="/Volumes/$mobileMeUser"
fi
root=$HOME/Sites/$siteName
destRep=$iDisk/Web/Sites/$siteName
[[ ! -d $root ]] && {
print -- "$root does not exist ; please verify the configuration ($0)" >&2;
exit 1
}
[[ ! -d $destRep ]] && {
print -- "$destRep does not exist, please mount the filesystem" >&2;
exit 1
}
if [[ $1 == '-h' ]]; then
print -- "usage: $0:h [-h|-a|-s]"
print -- " -a sychronize primary index"
print -- " -h show this help"
print -- " -s only swap directories"
fi
if [[ $1 == '-a' ]]; then
print -- "Index synchronisation (${destRep:h})"
rsync -av $root/index.html ${destRep:h}/index.html
fi
print -- "Root = $root"
print -- "Dest = $destRep"
if [[ ! $1 = '-s' ]]; then
[[ ! -d $destRep.tmp ]] && mkdir $destRep.tmp
print -P -- "%B[Sync => tmp]%b"
result=1
essai=1
while (( $result > 0 )); do
rsync -arv $root/Scratch/ $destRep.tmp
result=$?
if (( $result > 0 )); then
print -P -- "%Brsync failed%b (try n°$essai)" >&2
fi
((essai++))
done
fi
# SWAP
print -P -- "%B[Directory Swap (tmp <=> target)]%b"
essai=1
while [[ -e $destRep.old ]]; do
print -n -- "remove $destRep.old"
if ((essai>1)); then
print " (try n°$essai)"
else
print
fi
((essai++))
\rm -rf $destRep.old
done
print -- " renommage du repertoire sandard vers le .old"
essai=1
while [[ -e $destRep ]]; do
mv $destRep $destRep.old
(($?)) && print -- "Failed to rename (try n°$essai)" >&2
((essai++))
done
print -- " renaming folder tmp (new) to the standard one"
print -P -- " %BThe WebSite isn't working%b $(date)"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.tmp $destRep
(($?)) && print -P -- "%B[WebSite not working]%b(try n°$essai) Failed to rename (mv $destRep.tmp $destRep)" >&2
((essai++))
done
print -P -- "\t===\t%BWEBSITE SHOULD WORK NOW%b\t==="
print -- " rename old folder to tmp folder"
essai=1
while [[ ! -e $destRep ]]; do
mv $destRep.old $destRep.tmp
(($?)) && print -P -- "Failed to rename n°$essai" >&2
((essai++))
done
print -P -- " Publish terminated"
</code>
</div>

View file

@ -0,0 +1,84 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-17T23:27:54+02:00
title: Load Disqus Asynchronously
multiTitle:
fr: Load Disqus Asynchronously
en: Load Disqus Asynchronously
multiDescription:
fr: pas de description.
en: no description.
tags:
- disqus
- web
- javascript
- intense debate
- comments
-----
# Update
In fact this method works for old threads. But it fails to create new post threads. This is why I tried and be conquered by [intensedebate](http://intensedebate.com), as you can see in the bottom of this page.
Remark I didn't have any comment on my blog when I switched. Therefore my lack of influence was a good thing :-).
newcorps
Before begining, I must state that I **love** Disqus.
I know there is a similar blog entry at [Trephine.org](http://trephine.org/t/index.php?title=Site_improvements_-_fighting_with_Disqus). Here I just add a straight and easy way to load disqus asynchronously using jQuery.
I also know there is a jQuery plugin to make just that. Unfortunately I had some issue with CSS.
*Now let's begin.*
newcorps
# Why?
Why should I want to load the disqus javascript asynchronously?
- Efficiency: I don't want my page to wait the complete execution of disqus script to load.
- More independance: when disqus is down, my page is blocked!
newcorps
# How?
I give a solution with jQuery, but I'm certain it will work with many other js library.
### Javascript
replace:
<div>
<code class="javascript">
<script type="text/javascript" src="http://disqus.com/forums/YOUR_DISQUS_ID/embed.js"></script>
</code>
</div>
by
<div>
<code class="javascript">
window.disqus_no_style=true;
$(document).ready(function(){
$.getScript("http://disqus.com/forums/YOUR_DISQUS_ID/embed.js");
});
</code>
</div>
If you forget the `window.disqus_no_style=true;` then your page will be blank. Simply because without this option, the javascript use a `document.write` action after the document was closed, which cause a complete erasing of it.
### CSS
But with this option you still need to provide a CSS. This is why you have to copy the css code from the `embed.js` file and rewrite it in a CSS file. You can [download the CSS](/Scratch/multi/blog/11_Load_Disqus_Asynchronously/code/original_disqus.css) I obtained.
---
Now it's done. I believe all should be fine but I just finished the manip for my own site only 1 hour ago. Therefore there should be some error, tell me if it is the case.

View file

@ -0,0 +1,71 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-28T10:58:20+02:00
title: Disqus versus Intense Debate (Why I switched)
multiTitle:
fr: Disqus contre Intense Debate (pourquois j'ai changé)
en: Disqus versus Intense Debate (Why I switched)
multiDescription:
fr: pas de description.
en: no description.
tags:
- disqus
- intense debate
- web
- blog
-----
# [Disqus](http://disqus.com/) *vs.* [Intense Debate](http://intensedebate.com/)
J'ai écrit un article sur la façon dont j'ai essayé d'intégrer [Disqus](http://disqus.com). Mon problème majeur avec [Disqus](http://disqus.com/) c'était que ma page ne s'affichait pas correctement tant que les commentaire n'avait pas fini de s'afficher. Ça m'est arrivé plusieurs fois d'avoir ma page complètement bloquée parce que les serveurs de [Disqus](http://disqus.com/) ne répondait pas.
C'est pourquoi j'ai essayer de l'inclure de manière asynchrone. Cependant j'ai eu des [difficultés pour le faire fonctionner correctement](/Scratch/multi/blog/11_Load_Disqus_Asynchronously/).
De plus il n'a pas été trivial de faire en sorte que les commentaires soient commun à plusieurs pages différentes (chaque page à trois représentations différentes, une par language plus une version multi-langue).
Je dois reconnaître que je suis un peu triste de quitter [Disqus](http://disqus.com) parce que pour chacun de mes problèmes [giannii](http://giannii.com) m'a aidé du mieux qu'il a pu. Cependant les problèmes que j'ai eu étaient inhérents à des choix de conceptions plus que de simples petits problèmes techniques.
Lorsque j'ai commencé à intégrer [Disqus](http://disqus.com/) je n'ai jamais essayé [Intense Debate](http://intensedebate.com). Maintenant que j'ai essayé je doit dire que je suis conquis. Il correspond exactement à ce que j'espérais de ce type de service.
Pour le rendre complètement asynchrone il suffit de récupérer leur js commun et de remplacer la ligne suivante :
<div>
<code class="javascript">
document.getElementsByTagName("head")[0].appendChild(commentScript);
</code>
</div>
par (si vous utilisez jQuery) :
<div>
<code class="javascript">
$(document).ready( function() {
document.getElementsByTagName("head")[0].appendChild(commentScript);
});
</code>
</div>
## And the Winner is: [Intense Debate](http://intensedebate.com/)
Pour conclure les avantages majeurs (pour moi) d'[Intense Debate](http://intensedebate.com/) par rapport à [Disqus](http://disqus.com/):
- Se charge de façon asynchrone ; ne bloque pas mon site web
- Permet d'ajouter sans rien de plus des boutons comme "share to any" et les charge eux aussi de façon asynchrone.
Voilà.

View file

@ -0,0 +1,266 @@
-----
filters_pre:
- erb
- bluecloth
- frenchspace
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-23T13:18:26+02:00
title: jQuery Tag Cloud
multiTitle:
fr: jQuery Tag Cloud
en: Simple jQuery Tag Cloud
multiDescription:
fr: pas de description.
en: no description.
tags:
- jquery
- javascript
- web
- ruby
-----
Here is how I done the tag cloud of my blog. It is done mostly in jQuery.
All my site is static and pages are generated with [nanoc](nanoc.stoneship.org).
It is (in my humble opinion) the modern geek way to make a website.
This is why I'll give only a Ruby Generator, not a full javascript generator.
But you can easily translate from Ruby to Javascript.
Here is what you should obtain:
newcorps
<div>
<%= tagCloud %>
</div>
newcorps
# jQuery
Here is the simple jQuery code:
<div>
<code class="javascript">
$(document).ready( function(){$('.list').hide();} );
function tagSelected(id) {
$('.list').hide();
$('#'+id).fadeIn();
$('.tag.selected').removeClass('selected');
$('#tag_'+id).addClass('selected');
}
</code>
</div>
This code will hide all the div containing links to articles containing the tag. And create a function do show the div containing the tag.
For each tag I create a span element:
<div>
<code class="html">
<span style="font-size: 1.0em;"
class="tag"
onClick="tagSelected('[TAG]')"
id="tag_[TAG]">
[TAG]
</span>
</code>
</div>
and a div containing links associtated to this tag:
<div>
<code class="html">
<div id="[TAG]">
<h4>[TAG]</h4>
<ul>
<li> LINK 1 </li>
<li> LINK 2 </li>
</ul>
</div>
</code>
</div>
newcorps
# nanoc
Here is how I generate this using nanoc 2.
If you want to make it fully jQuery one, it shouldn't be
too difficult, to use my ruby code and translate it into javascript.
In a first time `tags` correpond of the list of all tags.
<div>
<code class="ruby">
def tags
return @page.tags.join(', ')
end
</code>
</div>
A function to create a data structure associating to each
tag its occurence.
<div>
<code class="ruby">
# generate an hash tag => number of occurence of tag
def tagNumber
tags={}
@pages.each do |p|
if p.tags.nil?
next
end
p.tags.each do |t|
if tags[t]
tags[t]+=1
else
tags[t]=1
end
end
end
return tags
end
</code>
</div>
I also need a data structure who associate to each
tag a list of pages (at least url and title).
<div>
<code class="ruby">
# generate an hash tag => [ page1, page2 ... ]
def tagRefs
tagLinks={}
@pages.each do |p|
if p.tags.nil?
next
end
p.tags.each do |t|
if tagLinks[t].nil?
tagLinks[t]=[ p ]
else
tagLinks[t] <<= p
end
end
end
return tagLinks
end
</code>
</div>
Calculate the real size of each tag to be displayed.
I choosen not to use the full range of size for all the tag. Because if no
tag has more than `n` (here 10) occurences, then it doesn't deserve to be
of the maximal size.
<div>
<code class="ruby">
def tagRealSize
tags=tagNumber
max=tags.values.max
min=tags.values.min
# size in CSS em.
minSize=1.0
maxSize=2.5
tagSize={}
tags.each do |t,n|
if ( max == min )
tagSize[t]=minSize
else
# normalized value between 0 and 1
# if not tag appear more than 10 times,
# then it cannot have the maximal size
tagSize[t]=[ ( n - min + 0.0 ) / ( max - min ) ,
(n - min) / 10.0 ].min
# from normalized size to real size
tagSize[t]=( tagSize[t] ) * (maxSize - minSize) + minSize
end
end
return tagSize
end
</code>
</div>
Finaly a function to generate the XHTML/jQuery code
<div>
<code class="ruby">
# generate an XHTML/jQuery code for tag cloud
def tagCloud
tagLinks=tagRefs
tagSize=tagRealSize
# begin to write the code
tagCloud=%{<script type="text/javascript">
$(document).ready( function(){$('.list').hide();} );
function tagSelected(id) {
$('.list').hide();
$('#'+id).fadeIn();
$('.tag.selected').removeClass('selected');
$('#tag_'+id).addClass('selected');
}
</script><div id="tagcloud">}
# Creation of the tags <span>
tagSize.sort{|a,b| a[0].downcase <=> b[0].downcase}.each do |t,s|
tag_in_id=t.gsub(/\W/,'_')
# HTML protected version of the tag
# for example, replace ' ' by '&nbsp;'
protected=t.gsub(/&/,'&amp;').gsub(/ /,'&nbsp;').gsub(/</,'&lt;').gsub(/>/,'&gt;')
tagCloud <<= %{
<span style="font-size: #{s}em;"
class="tag"
onClick="tagSelected('#{tag_in_id}')"
id="tag_#{tag_in_id}">
#{protected}
</span> }
end
tagCloud <<= %{</div><div id="hiddenDivs" >}
# Creation of the divs containing links associated to a tag.
tagLinks.each do |t,l|
tag_in_id=t.gsub(/\W/,'_')
tagCloud <<= %{
<div id="#{tag_in_id}" class="list">
<h4>#{t}</h4><ul>}
# generate the link list
l.each do |p|
tagCloud <<= %{<li><a href="#{p.path}">#{p.title}</a></li>}
end
tagCloud <<= %{</ul></div>}
end
tagCloud <<= %{</div>}
return tagCloud # yeah I know it is not necessary
end
</code>
</div>
You can [download the complete file](/Scratch/multi/blog/2009-09-jQuery-Tag-Cloud/code/tag.rb) to put in your 'lib' directory. **Beware, it is a nanoc 2 version, you'll have to make some small changes like replace `@pages` by `@items` to be nanoc3 compatible.**
Of course to be nice you need the associated CSS
<div>
<code class="css">
// Change the color when mouse over
.tag:hover {
color: #cc0000; }
// Change the color when tag selected
.tag.selected {
color: #6c0000; }
// a bit of space and pointer cursor
.tag {
cursor: pointer;
margin-left: .5em;
margin-right: .5em; }
</code>
</div>
That's all folks.

View file

@ -0,0 +1,101 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-09-22T22:13:25+02:00
title: replace all except some part
multiTitle:
fr: replace all except some part
en: replace all except some part
multiDescription:
fr: pas de description.
en: no description.
tags:
- ruby
- regexp
- regular expression
-----
My problem is simple:
I want to filter a text except some part of it. I can match easily the part I don't want to be filtered. For example
<div>
<code class="html">
...
text
...
BEGIN not to filter
...
text
...
END not to filter
...
text
...
</code>
</div>
I searched a better way to do that, but the best I can do is using `split` and `scan`.
<div>
<code class="ruby">
def allExceptCode( f, content )
regexp=/<code[^>]*>.*?<\/code>/m
tmp=""
mem=[]
content.scan(regexp).each do |c|
mem <<= c
end
i=0
content.split(regexp).each do |x|
tmp <<= send(f,x)
if not mem[i].nil?
tmp <<= mem[i]
i+=1
end
end
tmp
end
</code>
</div>
An usage is:
<div>
<code class="ruby">
def filter(content)
content.gsub(/e/,'X')
end
...
allExceptCode(:filter, content)
...
</code>
</div>
A better syntax would be:
<div>
<code class="ruby">
# !!!!!!!!!! THIS SYNTAX DOES NOT WORK !!!!!!! #
def allExceptCode( f, content )
regexp=/<code[^>]*>.*?<\/code>/m
tmp=""
content.split(regexp).each do |x|
separator=$&
tmp <<= send(f,x)
if not separator.nil?
tmp <<= separator
end
end
tmp
end
</code>
</div>
I would expect the split make a search on a regular expression and then give the matched expression into the `$&` variable. But it is not the case.
If someone know a nicer way to do that I will be happy to know how.

View file

@ -0,0 +1,296 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-28T11:03:30+02:00
title: custom website synchronisation with mobileme (2)
multiTitle:
en: custom website synchronisation with mobileme (2)
fr: Synchronisation avec mobileme (2)
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- mobileme
- WebDav
- synchronisation
- zsh
- script
-----
J'ai déjà discuté de la façon dont je [synchronise mon site web sur mobileme](/Scratch/multi/blog/10_Synchronize_Custom_WebSite_with_mobileMe). J'ai amélioré mon script pour le rendre incrémental.
Voici mon script, il créé tout d'abord un fichier qui contient la liste des fichiers avec leur *hash*. Afin de les comparer avec ceux qui sont en ligne sans avoir à les parcourir. Ensuite pour chaque fichier qui semble différent, je met à jour le contenu.
Cependant même avec ce script j'ai encore des problèmes. Dû à webdav. En particulier le renommage de répertoire. Par exemple :
<div><code class="zsh">
mv folder folder2
</code></div>
Retourne OK et pourtant :
<div><code class="zsh">
$ ls
folder folder2
</code></div>
Bouuhh...
Pour résoudre ce type de problèmes j'utilise un *framework* en zsh. Il résout presque tous les problèmes liés à webdav à l'exception du renommage de répertoire.
<div><code class="zsh" file="webdav-framework">
#!/usr/bin/env zsh
function samelineprint {
print -n -P -- "\r$*"
}
# avec 1 essai par seconde: 300 = 5 minutes
maxessais=300
# try to create a directory until success
function trymkdir {
target="$1"
print -- mkdir -p $target
local essai=1
while ! mkdir -p $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to copy until success
function trycp {
element="$1"
target="$2"
if [[ ! -d ${target:h} ]]; then
trymkdir ${target:h}
fi
local essai=1
print -- cp $element $target
while ! \cp $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to remove until success
function tryrm {
target="$1"
local essai=1
local options=''
[[ -d $target ]] && options='-rf'
print -- rm $options $target
while ! rm $options $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
essai=1
while [[ -e $element ]]; do
samelineprint "rm reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to rename until success
function tryrename {
element="$1"
target="$2"
local essai=1
while [[ -e $target ]]; do
samelineprint "Echec n°$essai le fichier $target existe déjà"
((essai++))
((essai>maxessais)) && exit 5
sleep 1
done
print -- mv $element $target
while ! mv $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 4
done
essai=1
while [[ -e $element ]]; do
samelineprint "mv reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
# try to move until success
function trymv {
element="$1"
target="$2"
local essai=1
print -- mv $element $target
while ! mv $element $target; do
samelineprint "Echec: essai n°$essai"
((essai++))
((essai>maxessais)) && exit 5
done
essai=1
while [[ -e $element ]]; do
samelineprint "mv reussi mais fichier source non disparu n°$essai"
sleep 1
((essai++))
((essai>maxessais)) && exit 5
done
print
}
</code></div>
Et voici le code qui me permet de synchroniser mon site web. Il y a une partie un peu incompréhensible. C'est pour enlever les mail réencodés par le filtre bluecloth qui est une implémentation de markdown. Mes mails, sont encodés à chaque fois de façon différente à chaque réengendrement de page html. C'est pourquoi je les enlève pour ne pas les *uploadés* inutilement à chaque fois.
<div><code class="zsh" file="publish">
#!/usr/bin/env zsh
# Script synchronisant le site sur me.com
# normalement, le site est indisponible le moins de temps possible
# le temps de deux renommages de répertoire
# get configuration
# mostly directories
source $0:h/config
# get trycp function (copy until success)
source $0:h/webdav-framework
if [[ $1 == '-h' ]]; then
print -- "usage : $0:h [-h|-s|-d]"
print -- " -a sychronise aussi l'index"
print -- " -h affiche l'aide"
print -- " -d modification directe (pas de swap)"
print -- " -s swappe simplement les répertoires"
fi
# publication incrementale
function incrementalPublish {
local ydestRep=$destRep$suffix
localRef="$srcRep/map.yrf"
print -- "Creation du fichier de references"
create-reference-file.sh > $localRef
remoteRef="/tmp/remoteSiteMapRef.$$.yrf"
if [[ ! -e "$ydestRep/map.yrf" ]]; then
# pas de fichier de reference sur la cible
print -- "pas de fichier de reference sur la cible, passage en mode rsync"
rsyncPublish
swap
else
trycp "$ydestRep/map.yrf" "$remoteRef"
typeset -U filesToUpdate
filesToUpdate=( $(diff $localRef $remoteRef | awk '/^[<>]/ {print $2}' ) )
if ((${#filesToUpdate} == 1)); then
print -- "Seul le fichier ${filesToUpdate} sera téléversé"
elif ((${#filesToUpdate}<10)); then
print -- "${#filesToUpdate} fichiers seront téléversés :"
print -- "${filesToUpdate}"
else
print -- "${#filesToUpdate} fichiers seront téléversés"
fi
# copy all file with some differences
# except the map in case of error
for element in $filesToUpdate; do
if [[ $element == "/map.yrf" ]]; then
continue
fi
if [[ -e $srcRep$element ]]; then
trycp $srcRep$element $ydestRep$element
else
tryrm $ydestRep$element
fi
done
# if all went fine, copy the map file
trycp $srcRep/map.yrf $ydestRep/map.yrf
# remove the temporary file
\rm $remoteRef
# if we have used the tmp directory we swap
if [[ "$suffix" != "" ]]; then
swap
fi
fi
}
# publication via rsync
function rsyncPublish {
result=1
essai=1
while (( $result > 0 )); do
print -- rsync -arv $srcRep/ $destRep.tmp
if ((!testmode)); then
rsync -arv $srcRep/ $destRep.tmp
fi
result=$?
if (( $result > 0 )); then
print -P -- "%BEchec du rsync%b (essai n°$essai)" >&2
fi
((essai++))
done
}
# swap
function swap {
print -P -- "%B[Directory Swap (tmp <=> target)]%b"
[[ -e $destRep.old ]] && tryrm $destRep.old
print -- " renommage du repertoire sandard vers le .old"
tryrename $destRep $destRep.old
print -- " renommage du repertoire tmp (nouveau) vers le standard"
print -P -- "%B[Site Indisponible]%b $(date)"
tryrename $destRep.tmp $destRep
print -P -- "%B[Site Disponible]%b $(date)"
print -- " renommage du repertoire old vers le tmp"
tryrename $destRep.old $destRep.tmp
print -P -- " publication terminée"
}
print -- "Root = $webroot"
print -- "Dest = $destRep"
if [[ "$1" = "-s" ]]; then
swap
else
print -P "Copie de l'init"
\cp -f $webroot/Scratch/multi/index.html $webroot/index.html
if [[ "$1" = "-d" ]]; then
suffix=""
else
suffix=".tmp"
fi
print -P -- "%BSync%b[${Root:t} => ${destRep:t}$suffix]"
incrementalPublish
fi
</code></div>
C'est ma façon de remplacer `rsync` avec des filesystem qui ne permettent pas de l'utiliser. J'espère que ça pourra vous être utile. Je serai heureux de savoir si quelqu'un à une idée sur comment gérer le problème de renommage de répertoire avec webdav.

View file

@ -0,0 +1,56 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-30T22:34:46+02:00
title: How to handle evil IE
multiTitle:
en: How to handle evil IE with jQuery
fr: Une CSS pour IE seulement
multiDescription:
fr: Pour les développeur de site web Internet Explorer est un cauchemar. C'est pourquoi j'utilise un style complètement différent pour ce navigateur. Avec la librairie jQuery.
en: For developer IE is a nightmare. This is why, I use a method to disable my standard CSS and enable a IE only CSS. I use jQuery to accomplish that.
tags:
- web
- webdesign
- jQuery
-----
Pour les développeur de site web Internet Explorer est un cauchemar. C'est pourquoi j'utilise un style complètement différent pour ce navigateur. Avec la librairie jQuery.
<div><code class="javascript">
$(document).ready( function() {
if ($.browser["msie"]) {
// include the ie.js file
$('head').append('<script type="text/javascript" src="/js/ie.js"></scr' + 'ipt>');
}
});
</code></div>
<div><code class="javascript" file="ie.js">
// Remove all CSS I don't want to use on IE
$('link[rel=stylesheet]').each(function(i)
{
if (this.getAttribute('href') == '/css/layout.css')
this.disabled = true;
if (this.getAttribute('href') == '/css/shadows.css')
this.disabled = true;
if (this.getAttribute('href') == '/css/gen.css')
this.disabled = true;
}) ;
// Append the CSS for IE only
$('head').append('<link rel="stylesheet" type="text/css" href="/css/ie.css"/>');
// I also add a message on top of the page
$('body').prepend('<div id="iemessage"><p><span class="fr"><em>Avec <a href="http://www.firefox.com"> Firefox </a> et <a href="http://www.apple.com/safari">Safari</a> cette page est bien plus jolie !</em></span><span class="en"><em>This page is far nicer with <a href="http://www.firefox.com"> Firefox </a> and <a href="http://www.apple.com/safari">Safari</a>!</em></span></p>.</div>');
</code></div>
Voilà.

View file

@ -0,0 +1,99 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-22T20:45:18+02:00
title: Focus vs Minimalism
multiTitle:
fr: <em>Focus</em> &gt; Minimalisme
en: Focus &gt; Minimalism
multiSubTitle:
fr: Cacher la navigation pour une meilleure concentration
en: Hide navigation for better focus
multiDescription:
fr: Je crois que le but du minimalisme est de facilité le <em><strong>Focus</strong></em> c'est-à-dire la concentration sur le contenu. Je crois que le minimalisme doit être un moyen et pas une fin.
en: I believe the goal researched by minimalism is <strong>Focus</strong>. But I don't believe minimalism should be the goal. Focus should be the goal, and I believe minimalism isn't necessary to reach it.
tags:
- jquery
- design
- web
-----
Je crois que le but du minimalisme est de facilité le <em><strong>Focus</strong></em> c'est-à-dire la concentration sur le contenu. Je crois que le minimalisme doit être un moyen et pas une fin. Le <em>Focus</em> devrait être le but, et je pense que le minimalisme n'est pas obligatoire pour l'atteindre.
en: I believe the goal researched by minimalism is <strong>Focus</strong>. But I don't believe minimalism should be the goal. Focus should be the goal, and I believe minimalism isn't necessary to reach it.
C'est pourquoi mon design n'est pas minimaliste. Mais j'ai décidé d'enlever la majorité des objets servant à la navigation pour améliorer l'attention sur l'article. Peut-être que plus tard, je préfèrerai laisser le menu dans les pages normales du site pour ne le cacher que dans les articles de blog.
Pour l'instant je le cache partout.
newcorps
## Détails techniques
Pour ceux qui souhaitent connaître les détails techniques derrière le menu apparaissant/disparaissant, voici le code utilisant jQuery.
L'HTML :
<div>
<code class="html">
<div id="menuButton"></div>
<div id="entete">#content of the menu</div>
</code>
</div>
La CSS :
<div><code class="css">
#menuButton {
font-size: 2em;
height: 2em;
line-height: 1.8em;
width: 2em;
position: fixed;
left: 0;
top: 0;
z-index: 9001 }
#menuButton:hover {
cursor: pointer; }
#entete {
top: 5em;
left: 0;
position: fixed;
width: 10em;
z-index: 9000; }
</code>
</div>
Le code javascript (utilisant jQuery)
<div>
<code class="javascript">
function hideMenu() {
$('#entete').animate({left:"-10em"}, 500 );
$('#menuButton').html('&rarr;');
}
function showMenu() {
$('#entete').animate({left:"0em"}, 500 );
$('#menuButton').html('&larr;');
}
function toggleMenu() {
if ( $('#entete').css('left')=='-10em' ) {
showMenu();
} else {
hideMenu();
}
}
</code>
</div>
Le résultat est visible dans le coin en haut à droite de cet article.

View file

@ -0,0 +1,112 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-03T14:34:11+02:00
title: How to preload your site with style
multiTitle:
fr: La classe pour charger une page web
en: How to preload your site with style
multiDescription:
fr: pas de description.
en: no description.
tags:
- web
- jquery
- webdesign
-----
## Exemple
Voici comment apparaissent mes pages pendant leur chargement.
<div id="demo" style="width:45%; position: relative; height: 8em; background-image: url('/Scratch/css/img/red.jpg'); background-position: 50% 50%; color: #fff; text-align: center; padding-top: 1em; margin-left: auto; margin-right: auto; border: solid 10px rgba(255,255,255,0.7); -webkit-border-radius: 1em; -moz-border-radius: 1em; border-radius: 1em; cursor: pointer; ">
<p><en>Hello! I've finished loading!</en><fr>Voilà ! Je suis chargée !</fr></p>
<p><en>Click me to see me disapear again.</en><fr>Cliquez-moi dessus pour recommencer.</fr></p>
<div id="todisapear" style="color: #000; position:absolute;top:0;left:0;text-align: center; padding-top: 1em; width: 100%; background-color: #eee; height: 8em;">
Loading...
<img style="border: none; background-color: none; background: none" src="/Scratch/img/loading.gif" alt="loading logo"/>
</div>
<script>
function Rabbit(){
$('#todisapear')
.show()
.animate({opacity: 1.0},3000)
.fadeOut();
}
$(document).ready(function(){
$('#todisapear').animate({opacity: 1.0},3000).fadeOut();
$('#demo').click(Rabbit);
});
</script>
</div>
J'ai d'abord essayé d'intégrer [queryLoader](http://www.gayadesign.com/diy/queryloader-preload-your-website-in-style/), mais il ne comblait pas mes besoins.
Ce plugin ajoutait un 'div' noir pour cacher le contenu du site. Cependant, comme le script doit être lancé à la fin du code source. Pendant un petit moment, on peut voir mon site en train de se mettre à jour.
Pour cacher ce petit 'artefact', voici comment je m'y suis pris.
## Code
D'abort il faut ajouter tout en haut du body cette fois un div qui va être le voile noir qui va tout cacher.
<div>
<code class="html">
...
<body>
<div id="blackpage">
content to display during the loading.
</div>
...
</code>
</div>
et le CSS correspondant au div `#blackpage` :
<div>
<code class="css">
#blackpage
top: 0
left: 0
width: 100%
height: 100%
margin-left: 0
margin-right: 0
margin-top: 0
margin-bottom: 0
position: absolute
text-align: center
color: #666
padding-top: 10em
background-color: #eee
z-index: 9000
</code>
</div>
ainsi que le code jQuery associé :
<div>
<code class="javascript">
$(document).ready(function(){
$('#blackpage').fadeOut();
});
</code>
</div>
Oui, c'est aussi simple que ça. Maintenant ajouter le `#blackpage` tout en haut de ma page me permet d'être certain de tout cacher pendant le chargement de la page.
J'espère que ça a pu vous être utile !

View file

@ -0,0 +1,107 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-26T21:56:09+02:00
title: Wait to hide a menu in jQuery
multiTitle:
fr: Un menu qui attends avant de se cacher
en: Menu waiting to hide himself
multiDescription:
fr: pas de description.
en: no description.
tags:
- jQuery
- web
- javascript
- design
-----
J'ai déjà dit pourquoi [je préférais que mon menu de navigation soit caché](/Scratch/multi/blog/2009-10-Focus-vs-Minimalism). J'ai finalement décidé d'attendre un peu avant de cacher le menu. Juste le temps que l'utilisateur le voit. Mais voilà. Comment faire pour qu'il ne disparaisse que lorsque l'on ne s'en sert pas pendant un petit moment ?
Voici la solution que j'utilise avec jQuery
HTML :
<div>
<code class="html">
<div id="menuButton"></div>
<div id="entete">
<ul>
<li> menu item 1 </li>
...
<li> menu item n </li>
</ul>
</div>
</code>
</div>
CSS :
<div><code class="css">
#entete {
top: 1em;
left: 0;
position: fixed;
width: 10em;
z-index: 2000; }
#entete {
top: 1em;
height: 22em;
left: 0;
position: fixed;
width: 10em; }
</code></div>
Javascript :
<div><code class="javascript">
var last=0;
// will hide the menu in 5 seconds
// if the variable 'last' has not changed its value
function autoHideMenu(value) {
setTimeout(function(){
if ( last == value ) { hideMenu(); }
},5000);
}
$(document).ready( function() {
// show the menu when the mouse is on
// the good area
$('#menuButton').hover(showMenu);
// If the mouse is on the menu change the
// value of 'last'
// try to hide the menu when the mouse
// go out off the menu.
$('#entete').hover(
function(){last+=1;},
function(){autoHideMenu(last);} );
autoHideMenu(0);
});
// show / hide menu functions details
// move to the left
function hideMenu() {
$('#entete').animate({left:"-10em"}, 500 );
}
// move to right and will try to hide in 5 sec.
function showMenu() {
$('#entete').animate({left:"0em"}, 500 );
last+=1;
autoHideMenu(last);
}
</code></div>
Simple et peu gourmand en ressources. Pas de timer (ou presque), pas de fuite de mémoire, pas d'utilisation de date...

View file

@ -0,0 +1,36 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-23T10:53:16+02:00
title: launch daemon from command line
multiTitle:
fr: lancer un démon en ligne de commande
en: launch daemon from command line
multiDescription:
fr: Pour lancer une commande qui continue de tourner après la fermeture du terminal il suffit de lancer la commande <code>nohup cmd &amp;</code>
en: To launch a command which will continu to run after the terminal is closed you only have to use <code>nohup cmd &amp;</code>
tags:
- zsh
- shell
- script
- tip
-----
Une petite astuce dont je ne me souvient jamais (je ne sais pas pourquoi).
Lorsque que vous souhaitez lancer une commande qui ne soit pas tuée après la fermeture du terminal voici comment s'y prendre :
<div><code class="zsh">
nohup cmd &
</code>
<small><code>cmd</code> est la commande que vous souhaitez lancer.</small>
</div>
Je laisse cette astuce ici pour moi et dans l'espoir que ça pourra aussi être utile à quelqu'un d'autre.

View file

@ -0,0 +1,270 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-10-13T13:10:09+02:00
title: untaught Git usage
multiTitle:
fr: Usages non dits de Git
en: Untaught Git usage
multiDescription:
fr: Je décris pourquoi j'ai eu tant de mal à me faire à Git. Il y a en effet une partie "non dite" qui m'a bloqué pendant un bon moment. Jusqu'à ce que je découvre le bon document.<br/>Le fait est que les *branches légères* ne sont pas destinée à être des branches isolées. Ainsi, il y a un <em>"workflow standard"</em> qui s'il n'est pas suivi rend l'utilisation de Git inappropriée.
en: I explain why I had so much difficulties to use Git. There is an "untaught rule" that make hard to work without. Until I read the good document.<br/> "Cheap branches" aren't designed to be totally isolated branches but rather should follow a "Master Branch". There is a <em>Standard Workflow</em> to follow. If you don't follow it, you prepare yourself with some hard time with Git.</em>
tags:
- git
- dcvs
- programming
-----
<en>
<small> <em>I explain why I had so much difficulties to use Git. There is an "untaught rule" that make hard to work without. Until I read the good document. </em></small>
</en>
<fr>
<small> <em>Je décris pourquoi j'ai eu tant de mal à me faire à Git. Il y a en effet une partie "non dite" qui m'a bloqué pendant un bon moment. Jusqu'à ce que je découvre le bon document. </em></small>
</fr>
<en>
<small> <em> "Cheap branches" aren't designed to be totally isolated branches but rather should follow a "Master Branch". There is a </em>Standard Workflow<em> to follow. If you don't follow it, you prepare yourself with some hard time with Git.</em> </small>
</en>
<fr>
<small> <em> Le fait est que les *branches légères* ne sont pas destinée à être des branches isolées. Ainsi, il y a un </em>"workflow standard"<em> qui s'il n'est pas suivi rend l'utilisation de Git inappropriée. </em> </small>
</fr>
newcorps
# La décentralisation en action
### De SVN à Bazaar
J'étais un fervent utilisateur de [subversion (svn)](http://subversion.tigris.org). Lorsqu'un jour, comme beaucoup de gens je découvris ce qu'en pensais [Linus Torvald sur une vidéo](http://www.youtube.com/watch?v=4XpnKHJAok8). Ventant les mérites d'un *système de versions concurrentes décentralisé*.
En effet une fois qu'on s'y intéresse un peu, on voit tous les avantages pratiques qu'apporteraient en théorie un tel système.
J'ai alors eu besoin d'un système de version dans mon équipe.
Ils n'étaient pas familier avec les systèmes de versions. À par ceux possédant une <abbr title="Interface Utilisateur">GUI</abbr>, qui sont lourds et administrés par un responsable<sup><a href="#note1">&dagger;</a></sup>.
Après quelques recherches trois choix se dessinent :
- [Git](http://git-scm.com)
- [Bazaar](http://bazaar-vcs.org)
- [Mercurial](http://selenic.com/mercurial)
En me renseignant un peu sur les forums et en essayant les trois, je me suis vite rendu compte que celui possédant l'interface utilisateur la plus simple était Bazaar<sup><a href="#note2">&#42;</a></sup>. Mon choix était fait.
### De bazaar à Git
Je me suis alors familiarisé avec Bazaar. Et je dois dire que c'était vraiment naturel en venant de subversion. La commande `pull` correspond au `update`, la commande `push` correspond au `commit`. Puis les commandes `commit` et `update` existent toujours si on en a besoin et qu'on veut utiliser un *workflow* identique à celui de subversion.
Mais plus le temps passe et plus de partout sur les blog, c'est surtout Git qui a le vent en poupe.
Je décide alors d'utiliser Git en particulier pour *versionner* le site que vous êtes en train de lire. Sauf que je le trouve vraiment difficile d'utilisation et surtout complètement contre intuitif (j'y reviendrai plus tard).
Alors que j'essaye de trouver de l'aide et que je dis qu'il est plus difficile à utiliser que Bazaar, beaucoup me répliquent que c'est :
> &mdash; *Super-tellement-trop-simple que même ma fille de 12 ans qui n'y comprend rien en informatique l'utilise pour versionner ses documents. Elle s'en sert très facilement en créant des branches et tout et tout...*
Bon alors si une gamine 12 ans trouve ça très naturel et que moi (avec mon Doctorat en informatique) j'ai du mal à faire ce que je veux, c'est un peu frustrant et humiliant. Mais qu'est-ce qui fait que Git est naturel aux uns (comme pour [CocoaSamurai](http://cocoasamurai.blogspot.com) ) et très confus pour moi ?
C'est en lisant un article j'ai enfin compris ce qu'il me manquait. C'est la partie **non dite** de la conception. Celle que tous les développeurs et les concepteurs trouvaient comme *aller de soi*. Sauf que pour moi, ce n'était pas du tout le cas.
<small><a name="note1">&dagger;</a> - Je parle de *ClearCase(c)*. Et oui, je sais qu'il existe des commandes en lignes pour ClearCase(c), mais ce n'est pas comme ça qu'ils étaient habitués à travailler avec des systèmes de "versionning".</small>
<small><a name="note2">&#42;</a> - Je n'ai pas vraiment donné sa chance à Mercurial, la terminologie qu'ils utilisaient était trop éloignée de celle de svn à laquelle je m'étais habituée.</small>
newcorps
Lorsqu'on voit les présentations autour de la notion de *branche* et de <abbr title="Système de Version Concurentes Décentralisé"><sc>dcvs</sc></abbr>, on s'imagine dans un monde où chaque branche est totalement isolée des autres sauf au moment de "merger" les différences les unes des autres.
Tout est magique. C'est la façon de voir "*Mondes Parallèles*". Cette façon de voir est expliquée dans le [très bon article sur les branches](http://betterexplained.com/articles/a-visual-guide-to-version-control/) sur betterexplained.
Sauf que les concepteurs de Git (conçu pour le noyau Linux) ont plutôt imaginé un système basé non pas autour des mondes parallèles, mais sur la notion de *Patch*.
D'un côté *Mondes Parallèles*, de l'autre *Patchs*. Il y a beaucoup de notions équivalentes dans les deux cas, mais aussi quelques différences.
* Bazaar est complètement basé sur la notion de *Mondes Parallèles* qui va impliquer un phénomène de *Patch*.
* Alors que Git est basé sur la notion de *Patch* qui va impliquer la création de *Mondes Parallèles*.en:While Git seem base on the *Patch* model which will implie the creation of *Parallel Worlds*.
Je ne vais pas argumenté pour savoir si une façon de voir est meilleure que l'autre. Disons simplement que ma façon d'entrer dans l'explication des DCVS était par le biais des *Mondes Parallèles* alors que Git est conçut selon l'autre notion<sup><a href="#note3">&Dagger;</a></sup>.
## De la théorie à la pratique
Bien que je pense avoir bien compris les mécanismes conceptuels de Git, la mise en pratique posait problème. Et le point noir, celui qui m'empêchait de comprendre Git comme je le souhaitais était dû à la notion de *branche légère*.
Une *branche légère* qu'est-ce que c'est me demanderez-vous ? Si comme moi on vient de Bazaar, c'est une notion complètement nouvelle. Il s'agit simplement de la capacité de créer une nouvelle branche en réutilisant le répertoire dans lequel on se trouve.
En pratique pour changer de branche, il faut lancer une commande. Tous les fichiers locaux non modifiés depuis le dernier commit seront alors modifiés pour correspondre à la version de la branche.
En théorie, les *branches légères* sont des branches tout comme avec bazaar. D'ailleurs le mot utilisé n'est pas *branche légère* mais *branche* tout court.
Sauf que contrairement à une branche standard résidant dans son propre répertoire, une branche légère est destinée à n'être qu'un **patch** de la branche principale du répertoire dans lequel elle réside.
Bien entendu on pourra m'objecter que l'on peut tout à fait utiliser ces branches légères comme des branches normales. Mais elles n'ont pas été conçues pour ça. Et donc, en pratique, c'est gênant de les utiliser de la sorte.
Voici comment Git est censé être utilisé (pour plus de détails vous pouvez lire [Git for Designers](http://hoth.entp.com/output/git_for_designers.html) en anglais) :
* récupération ou création d'un "repository" central **<sc>Le Grand Repository</sc>**
* Création d'un *branche légère* locale qui contient les différences qui vont devoir être "patché" dans **<sc>LE GRAND REPOSITORY</sc>**.
Voici comment n'est **<sc>pas</sc>** censé être utilisé Git :
* Récupération ou création d'un "repository" quelconque
* Création d'un *branche légère* locale qui n'a pas pour vocation de mettre à jour le "repository" d'origine, mais de vivre sa vie de façon autonome et de récupérer les mises à jour des autres du "repository" d'origine.
En effet cette petite notion m'a empêché de fonctionner correctement.
### En pratique
Maintenant que j'ai compris ça, je peux enfin comprendre pourquoi Git a tant de défenseurs qui continue de trouver que Git est meilleur que les autres.
La notion de branche légère est essentielle à Git et vraiment utile en pratique. Notamment pour la gestion de ce site. Par contre, elle m'empêche d'utiliser les branches comme je le souhaiterai.
Mais dans ce cas-là, je n'ai qu'à utiliser des *clônes* et pas des *branches légères*.
### Des exemples
Je trouve toujours que les terminologies de bazaar sont plus claires et plus concises.
<div><code class="zsh">bzr revert</code></div>
est quand même plus clair que
<div><code class="zsh">git reset --hard HEAD</code></div>
De la même façon
<div><code class="zsh">bzr revert -r -3</code></div>
je trouve ça mieux que
<div><code class="zsh">git reset --hard HEAD~3</code></div>
Là ça va commencer à se compliquer. Si on veut revenir dans le temps sur toute l'arborescence, avec Git on utilise `reset`.
<center>OK</center>
Maintenant si je veux revenir dans le temps sur un seul fichier. Naturellement on se dit :
<div><code class="zsh">git reset --hard FILE</code></div>
<center>**ET BIEN NON !**</center>
La solution c'est :
<div><code class="zsh">git checkout FILE</code></div>
Quoi ? **`checkout`** !? Bon, d'accord, j'accepte, pourquoi pas après tout ?
En plus quand on est habitué à Bazaar c'est :
<div><code class="zsh">git revert FILE</code></div>
Ce que je trouve quand même bien plus naturel.
Mais là où ça devient vraiment difficile de s'y faire c'est pour changer de branche.
Avec Bazaar ça donne :
<div><code class="zsh">cd ../branch</code></div>
Bon ok, il faut changer de répertoire, un répertoire par branche. Ça consomme de l'espace disque mais au moins on voit où on est. Avec Git voilà comment on change de branche (*branche légère*) :
<div><code class="zsh">git checkout branch</code></div>
Alors là, on se dit "<abbr title="What the Fuck?">WTF?</abbr>" ; en français : mais qu'est-ce que c'est que ça ? Je croyais que `checkout` c'était pour récupérer l'état d'un fichier ?
En fait le mot `checkout` sert à la fois à revenir en arrière sur un fichier (MAIS PAS TOUTE UNE ARBORESCENCE où là ça sera `reset --hard`) et à **changer de branche* !
Je trouve ça carrément contre nature. Même si c'est totalement justifié du point de vue théorique voir le très bon article (en anglais) [Git for Computer Scientist](http://eagain.net/articles/git-for-computer-scientists/). Du point de vue interface utilisateur, on peut difficilement faire pire. On dirait que les mots clés sont utilisés pour piéger l'utilisateur.
> - &mdash; Alors, essaye de deviner ce qu'il va falloir écrire pour faire cette opération ?
> - &mdash; Perdu. Essaye encore, cherche sur Internet (blaireau).
> - &mdash; Non, c'est toujours pas bon, recommence (sale nul).
Bon alors, voilà, les défauts de Git. Mais, il a par contre beaucoup d'avantages. Une fois qu'on a compris le principe des branches légères. Tout devient plus clair. Même si en pratique, l'édition du fichier `.git/config` peut s'avérer un peu fastidieuse et surtout contre intuitive.
<small><a name="note3">&Dagger;</a> - Il faut aussi préciser qu'ayant travaillé sur les logiques multi-modales et en particulier sur les logiques temporelles (linéaires ou non), j'étais plus enclin à adhérer à cette vision des choses. "Ah mes premiers amours dans la recherche scientifique !"</small>
newcorps
# Conclusion
### DCVS vs. CVS ?
Est-ce que ça valait la peine d'utiliser un système de "versionning" décentralisé ? Indéniablement la réponse est oui. On peut très bien vivre avec des systèmes de versions centralisés, mais la souplesse apportée par la facilité de "merger" différentes branches. De travailler de façon autonomes sur différentes parties d'un projets sont vraiment des plus appréciables. J'aurai vraiment du mal à revenir en arrière.
### Est-ce que Git est meilleurs que Bazaar ?
En terme de *fonctionnalités* je dirai que Git est meilleurs.
Par contre, je dois avouer qu'il s'agit d'un CVS qui s'est mis dans mes pattes. Or c'est exactement ce que je ne souhaitait pas lors de mon premier choix.
Je n'aurai pas dû avoir du mal à comprendre cette notion de *branche légère* qui doit être un patch sinon tu reçois des messages t'expliquant que tu es en retard. En réalité, Git différencie la notion d'arbre de la notion de branche. Ce qui n'est pas le cas dans Bazaar. Conceptuellement, c'est beaucoup plus simple de comprendre avec Bazaar.
### Finalement ?
Pour conclure, j'utilise plus souvent Git que Bazaar et je dois dire que je préfère utiliser Git. Cependant, les commandes comme `revert` manquent cruellement avec Git. Pour l'instant je n'ai pas encore fait d'alias pour renommer les commandes Git comme je le souhaite.

View file

@ -0,0 +1,75 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-11-12T11:39:54+02:00
title: Git for n00b
multiTitle:
en: Git for n00b
fr: Git pour les 'n00b'
multiDescription:
fr: Voici un tutoriel <a href="http://git-scm.org">Git</a> détaillé pour ceux qui en connaissent très peu sur les systèmes de versions. Vous comprendrez l'utilité de tels systèmes et surtout comment on se sert des systèmes de versions modernes, le tout en restant le plus pragmatique possible.
en: A detailed tutorial of <a href="http://git-scm.org">Git</a> for people knowing very few about versions systems. You'll understand utility of such program and how we use modern version control system. I try to stay as pragmatic as possible.
tags:
- git
-----
begindiv(intro)
Voici un tutoriel <a href="http://git-scm.org">Git</a> détaillé pour ceux qui en connaissent très peu sur les systèmes de versions. Vous comprendrez l'utilité de tels systèmes et surtout comment on se sert des systèmes de versions modernes, le tout en restant le plus pragmatique possible.
enddiv
newcorps
# Pour commencer, la conclusion
Voici la liste des commandes nécessaires et suffisantes pour utiliser [Git][git]. Il y en a très peu. Il est normal de ne pas les comprendre tout de suite mais c'est pour vous donner une idée. Malgré la longueur de l'article, 95% de l'utilisation de [Git][git] tiens dans les 7 commandes décrites ci-après.
Récupérer un projet :
<div><code class="zsh">
git clone ssh://server/path/to/project
</code></div>
Utiliser [Git][git] tous les jours :
<div><code class="zsh">
# get modifications from other
git pull
# read what was done
git log
# Make local changes to files
hack, hack, hack...
# list the modified files
git status
# show what I've done
git diff
# tell git to version a new file
git add new/file
# commit its own modifications
# to its local branch
git commit -a -m "Fix bug #321"
# send local modifications to other
git push
</code></div>
Cet article est écrit pour ceux qui en savent très peu sur les systèmes de version. Il est aussi écrit pour ceux qui n'ont pas suivi les progrès accomplis depuis CVS ou subversion (SVN). C'est pourquoi dans un premier temps j'explique rapidement quel sont le buts poursuivis par les systèmes de versions. J'explique ensuite comment installer et configurer [Git][git]. Puis, pour chaque action que doivent accomplir les <abbr title="Decentralized Concurent Versions System">DCVS</abbr> je donne les commandes [Git][git] qui y correspondent.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,245 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-11-12T11:39:54+02:00
title: Git for n00b
multiTitle:
fr: Git pour quoi faire ?
en: Git for what?
-----
# [Git][git] pour quoi faire ?en:[Git][git] for what?
begindiv(intro)
Si tout ce qui vous intéresse c'est d'utiliser [Git][git] **tout de suite**. Lisez simplement les parties sur fond noir. Je vous conseille aussi de revenir relire tout ça un peu plus tard, pour mieux comprendre les fondements des systèmes de versions et ne pas faire de bêtises quand vous les utilisez.
enddiv
[Git][git] est un <abbr title="Decentralized Concurent Versions System">DCVS</abbr>, c'est-à-dire un système de versions concurrentes décentralisé. Analysons chaque partie de cette appellation compliqué.
### Système de versions
Tout d'abord, les systèmes de versions gèrent des fichiers.
Quand on travaille avec des fichiers sans système de version voilà ce qui arrive souvent :
Lorsqu'on modifie un fichier un peu critique et qu'on a pas envie de perdre, on se retrouve souvent à le recopier sous un autre nom. Par exemple
<div><code class="zsh">$ cp fichier_important.c fichier_important.c.bak</code></div>
Du coups, ce nouveau fichier joue le rôle de *backup*. Si on casse tout, on peut toujours écraser les modifications que nous avons faites. Évidemment le problème avec cette façon de faire c'est que ce n'est pas très professionnel. Et puis c'est un peu limité. Si on veut faire trois ou quatre modifications on se retrouve avec plein de fichiers. Parfois avec des nom bizarres comme :
<div>
<code class="zsh">
fichier_important.c.bak
fichier_important.c.old
fichier_important.c.Bakcup
fichier_important.c.BAK.2009-11-14
fichier_important.c.2009.11.14
fichier_important.c.12112009
old.fichier_important.c
</code>
</div>
Bon alors si on veut que ça marche il faut se fixer des conventions de nommage. Les fichiers prennent beaucoup de place alors que souvent il n'y a que quelques lignes différentes entre le fichier et son backup...
*Heureusement les systèmes de version viennent à la rescousse.*
Il suffit de signaler que l'on va faire une nouvelle version d'un fichier et le système de version se débrouille pour l'enregistrer quelque part où on pourra facilement le retrouver. Et en général, le système de version fait les choses bien. C'est-à-dire qu'il n'utilise que très peu d'espace disque pour faire ces backups.
Il fut un temps où les versions étaient gérées fichier par fichier. Je pense à CVS. Puis on s'est vite aperçu qu'un projet c'est un ensemble de fichiers cohérents. Et donc il ne suffit pas de pouvoir revenir en arrière par fichier, mais plutôt dans le temps. Les numéros de versions sont donc passé d'un numéro par fichier à un numéro par projet tout entier.
Ainsi on peut dire, «je veux revenir trois jours en arrière», et tous les fichiers se remettent à jour.
begindiv(black)
*Qu'apportent les systèmes de versions ?* (je n'ai pas tout mentionné)
<fr>
- backup automatique de tous les fichiers: *Revenir dans le temps.* ;
- donne la possibilité de voir les différences entre chaque version et les différences entre la version en cours et les modifications locales ;
- permet de poser un *tag* sur certaines versions et ainsi pouvoir s'y référer facilement ;
- permet d'avoir un historique des modifications. Car en général il est demandé aux utilisateur d'ajouter un petit commentaire à chaque nouvelle version.
</fr>
<en>
- automatic backups: *back in time*,
- gives the ability to see differences between each version,
- put a *tag* on some version to be able to refer to them easily,
- gives the ability to see an historic of all modifications. Generally the user must add a comment for each new version.
</en>
enddiv
### concurrentesen:concurrent:
Les systèmes de versions sont déjà intéressants pour gérer ses projets personnels. Car ils permettent de mieux organiser celui-ci. De ne (presque) plus se poser de questions à propos des backups. Je dis presque parce qu'il faut quand même penser à protéger par backup son repository. Mais là où les systèmes de versions deviennent vraiment intéressant, c'est pour la gestion de projets à plusieurs.
Commençons par un exemple avec un projet fait par deux personnes ; Alex et Béatrice.
Sur un fichier contenant un liste de dieux *Lovecraftiens* :
<div style="width: 10em; margin-left: auto; margin-right: auto">
<code class="zsh">
Cthulhu
Shubniggurath
Yogsototh
</code></div>
Disons que Alex est chez lui, il modifie le fichier :
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
Shubniggurath
<span class="StringConstant"><strong>Soggoth</strong></span>
Yogsototh
</pre>
</div>
puis il envoi ce fichier sur le serveur du projet. Ainsi sur le serveur, il y a le fichier d'Alex.
Ensuite c'est Béatrice qui n'a pas récupéré le fichier d'Alex sur le serveur qui fait une modification.
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
<span class="Constant"><strong>Dagon</strong></span>
Shubniggurath
Yogsototh
</pre>
</div>
Puis Béatrice envoi son fichier sur le serveur.
La modification d'Alex est *perdue*. Encore une fois les systèmes de versions sont là pour résoudre ce type de soucis.
Un système de version aurait *mergé* les deux fichiers au moment où Béatrice voulait envoyer la modification sur le serveur. Et comme par magie, sur le serveur le fichier deviendra :
<div style="width: 10em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Cthulhu
<span class="Constant"><strong>Dagon</strong></span>
Shubniggurath
<span class="StringConstant"><strong>Soggoth</strong></span>
Yogsototh
</pre>
</div>
En pratique, au moment où Béatrice veut envoyer ses modifications, le système de version la préviens qu'une modification a eu lieu sur le serveur. Elle utilise la commande qui rapatrie les modifications localement et qui va mettre à jour le fichier. Ensuite Béatrice renvoie le nouveau fichier sur le serveur.
begindiv(black)
**Qu'apportent les Systèmes de Versions Concurrentes ?**
<fr>
- récupérer sans problème les modifications des autres ;
- envoyer sans problème ses modifications aux autres ;
- permet de gérer les conflits. Je n'en ai pas parlé, mais quand un conflit arrive (ça peut arriver si deux personnes modifient la même ligne avec deux contenus différents), les <abbr title="Systèmes de versions concurrentes">SVC</abbr> proposent leur aide pour les résoudre. J'en dirai un mot plus loin.
- permet de savoir qui a fait quoi et quand
</fr>
<en>
- get without any problem others modifications,
- send without any problem its own modifications to others,
- manage conflicts. I didn't speak about it, but sometimes a conflict can occur (when two different people modify the same line on a file for example). SVC help to resolve such problem. More on that later,
- help to know who done what and when.
</en>
enddiv
### décentralisé
Ce mot n'est devenu populaire que très récemment dans le milieu des systèmes de version. Et bien ça veut dire principalement deux choses.
Tout d'abord, jusqu'à très récemment (SVN) il fallait être connecté sur un serveur distant pour avoir des informations sur un projet. Comme avoir l'historique. Les nouveaux systèmes décentralisés permettent de travailler avec un *REPOSITORY* (le répertoire contenant tous les backups, et les différentes info nécessaires au fonctionnement du système de versions) local au projet. Ainsi on peut avoir l'historique du projet sans avoir à se connecter au serveur.
Toutes les instances de projets peuvent vivre de façon indépendantes.
Pour préciser, les systèmes de versions concurrentes décentralisés sont basés sur la notion de **branche**.
Et la signification pratique est très importante. Ça veut dire que tout les utilisateurs travaillent de façon complètement indépendante les uns des autres. Et c'est l'outil de version qui se charge de mettre tout ça ensemble.
Ça va même encore plus loin. Ça permet de développer plusieurs features de manière complètement indépendantes. Sous les autres systèmes c'était plus difficile.
L'exemple type :
> Je développe mon projet. Je suis en train de l'améliorer. Lorsqu'un bug urgent est reporté.
>
> Je peux très facilement avec un système décentralisé, revenir sur la version qui pose problème. Résoudre le bug. Renvoyer les modifications. Puis revenir à ma version avec les améliorations en cours. Et même récupérer la correction de bug dans ma nouvelle version avec les améliorations.
>
> Dans un système non décentralisé, cela est possible, mais fastidieux. Les systèmes décentralisés rendent ce type de comportement très naturels. Ainsi, il devient naturel de tirer des *branches* pour toutes les features, les bug...
begindiv(black)
**Avantages donnés par la décentralisation des systèmes de versions concurrentes : **
- Possibilité de travailler sans être connecté au serveur de version ;
- Possibilité de créer beaucoup de `patches` atomiques ;
- Grande facilité de maintenance de plusieurs versions différentes de la même application.
enddiv
## Pour résumer
Résumons l'ensemble des choses que l'on peut faire facilement avec un <abbr title="Decentralized Concurrent Versions System">DCVS</abbr> :
**Systèmes de versions**
- revenir dans le temps ;
- lister les différences entre chaque version ;
- nommer certaines versions pour s'y référer facilement ;
- afficher l'historique des modifications.
**Concurrentes**
- récupérer les modifications des autres ;
- envoyer ses modifications aux autres ;
- permet de savoir qui a fait quoi et quand ;
- gestion des conflits.
**Décentralisé**
- manipuler facilement des branches
Maintenant voyons comment obtenir toutes ces choses facilement avec [Git][git].
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,137 @@
-----
# Custom
isHidden: false
menupriority: 3
kind: article
date: 2009-11-12T11:39:54+02:00
title: The Adventure Begins
multiTitle:
fr: Utiliser Git simplement et rapidement
en: Use Git with very few commands
-----
# Et c'est parti !
Voici une parmi de nombreuses autres façon d'utiliser [Git][git]. Cette méthode est nécessaire et suffisante pour travailler seul ou en collaboration sur un projet commun. Cependant, on peut faire beaucoup mieux avec [Git][git] que ce *workflow* (en langage anglo-saxon).
## Utilisation basique
La façon immédiate de travailler avec [Git][git] :
<fr>
+ récupérer les modifications des autres <span class="black">`git pull`</span>
+ voir les détails de ces modifications <span class="black">`git log`</span>
+ Plusieurs fois:
+ *Faire une modification atomique*
+ verifier le details de ses modifications <span class="black">`git status`</span> et <span class="black">`git diff`</span>
+ indiquer si nécessaire que de nouveaux fichiers doivent être *versionnés* <span class="black">`git add [file]`</span>
+ enregistrer ses modifications <br/><span class="black">`git commit -a -m "message"`</span>
+ envoyer ses modifications aux autres <span class="black">`git push`</span> (refaire un `git pull` si le push renvoie une erreur).
</fr>
<en>
+ Get modification done by others <span class="black">`git pull`</span>,
+ See details of these modifications <span class="black">`git log`</span>,
+ Many times:
+ *Make an atomic modification*
+ Verify details of this modification: <span class="black">`git status`</span> and <span class="black">`git diff`</span>,
+ Add some file to be versionned if necessary:<br/><span class="black">`git add [file]`</span>,
+ Save you modifications <br/><span class="black">`git commit -a -m "message"`</span>,
+ Send your modifications to others: <span class="black">`git push`</span> (redo a `git pull` if push return an error).
</en>
Voilà, avec ces quelques commandes vous pouvez utiliser [Git][git] sur un projet avec d'autres personnes. Même si c'est suffisant, il faut quand même connaître une chose avant de se lancer ; la gestion des *conflits*.
### Gestion des conflits
Les conflits peuvent survenir lorsque vous modifiez les même lignes de codes sur le même fichier d'une autre branche que vous *mergez*. Ça peut sembler un peu intimidant, mais avec [Git][git] ce genre de chose est très facile a régler.
#### exemple
Vous partez du fichier suivant :
<div style="width: 18em; margin-left: auto; margin-right: auto">
<code class="zsh">
Zoot
</code>
</div>
et vous modifiez une ligne
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot <span class="Constant"><strong>the pure</strong></span>
</pre>
</div>
sauf que pendant ce temps, un autre utilisateur a aussi modifié cette ligne et a fait un `push` de sa modification.
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot<span class="StringConstant"><strong>, just Zoot</strong></span>
</pre>
</div>
Maintenant quand vous lancez la commande
<div>
<code class="zsh">
$ git pull
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/e640846/tmp/conflictTest
d3ea395..2dc7ffb master -> origin/master
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Automatic merge failed; fix conflicts and then commit the result.
</code>
</div>
Notre fichier `foo` contient alors :
<div>
<pre class="twilight">
<<<<<<< HEAD:foo
Zoot <span class="Constant"><strong>the pure</strong></span>
=======
<span>Zoot<span class="StringConstant"><strong>, just Zoot</strong></span></span>
>>>>>>> 2dc7ffb0f186a407a1814d1a62684342cd54e7d6:foo
</pre>
</div>
#### Résolution du conflit
Régler le conflit, il suffit d'éditer le fichier, par exemple en écrivant :
<div style="width: 18em; margin-left: auto; margin-right: auto">
<pre class="twilight">
Zoot <span class="Constant"><strong>the not so pure</strong></span>
</pre>
</div>
et de 'commiter' tout simplement :
<div>
<code class="zsh">
git commit -a -m "conflict resolved"
</code>
</div>
Maintenant vous êtes fin prêt pour utiliser [Git][git].
Sauf que [Git][git], c'est un outil qui permet de faire beaucoup plus que juste ça. Alors nous allons maintenant voir des façon d'utiliser git qui étaient avant lui interdite d'utilisation pour les autres CVS.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,163 @@
-----
# Custom
isHidden: false
menupriority: 30
kind: article
date: 2009-11-12T11:39:54+02:00
title: The Adventure Begins
multiTitle:
fr: Liste de commandes
en: Command List
tags:
- git
-----
# Liste de commandes
## Les commandes pour chaque choses
Dans la première partie, nous avons vu la liste des problèmes résolus par [Git][git]. En résumé Git doit pouvoir :
<fr>
- récupérer les modifications des autres ;
- envoyer ses modifications aux autres ;
- revenir dans le temps ;
- lister les différences entre chaque version ;
- nommer certaines versions pour s'y référer facilement ;
- afficher l'historique des modifications ;
- savoir qui a fait quoi et quand ;
- gérer des conflits ;
- manipuler facilement des branches.
</fr>
<en>
- get others modifications,
- send modifications to others,
- get back in time,
- list differences between each version,
- name some versions in order to refer easily to them,
- write an historic of modifications,
- know who did what and when,
- manage conflicts,
- easily manage branches.
</en>
### récupérer les modifications des autres
<div><code class="zsh">
$ git pull
</code></div>
### envoyer ses modifications aux autres
<div><code class="zsh">
$ git push
</code></div>
ou plus généralement
<div><code class="zsh">
$ git pull
$ git push
</code></div>
### revenir dans le temps
#### Pour toute l'arborescence
<div><code class="zsh">
$ git checkout
</code></div>
<div><code class="zsh">
$ git revert
</code></div>
revenir trois versions en arrière
<div><code class="zsh">
$ git uncommit 3
</code></div>
Revenir avant le dernier merge (s'il s'est mal passé).
<div><code class="zsh">
$ git revertbeforemerge
</code></div>
#### Pour un seul fichier
<div><code class="zsh">
$ git checkout file
$ git checkout VersionHash file
$ git checkout HEAD~3 file
</code></div>
### lister les différences entre chaque version
liste les fichier en cours de modifications
<div><code class="zsh">
$ git status
</code></div>
fr:différences entre les fichier de la dernière version et les fichiers locaux.
<div><code class="zsh">
$ git diff
</code></div>
liste les différences entre les fichier d'une certaine version et les fichiers locaux.
<div><code class="zsh">
$ git diff VersionHash fichier
</code></div>
### nommer certaines versions pour s'y référer facilement
<div><code class="zsh">
$ git tag 'toto'
</code></div>
### afficher l'historique des modifications
<div><code class="zsh">
$ git log
$ git lg
$ git logfull
</code></div>
### savoir qui a fait quoi et quanden:know who did what and when::
<div><code class="zsh">
$ git blame fichier
</code></div>
### gérer des conflits
<div><code class="zsh">
$ git conflict
</code></div>
### manipuler facilement des branches
Pour créer une branche :
<div><code class="zsh">
$ git branch branch_name
</code></div>
Pour changer de branche courante :
<div><code class="zsh">
$ git checkout branch_name
</code></div>
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,42 @@
-----
# Custom
isHidden: false
menupriority: 10
kind: article
date: 2009-11-12T11:39:54+02:00
title: Understanding
multiTitle:
fr: Comprendre
en: Understanding
tags:
- git
-----
# Pourquoi Git est cool ?
Parce que grace à [Git][git] vous pouvez travailler sur plusieurs partie du projet de façon complètement isolée les unes des autres. Ça c'est la partie décentralisée de [Git][git].
Toutes les branches locales utilisent le même répertoire. Ainsi on peu changer de branche très aisément et rapidement. On peut aussi changer de branche alors que certains fichier sont en cours de modifications. On peut même pousser le vice jusqu'à modifier un fichier, changer de branche, commiter une partie seulement des modifications de ce fichier dans la branche courante. Revenir dans l'ancienne branche et commiter à nouveau les modifications restantes. Et merger dans une troisième branche les deux modifications.
Avec la command `git rebase` on peut après coup, décider que certaines modifications devaient aller dans certaines branches, que d'autres ne servaient à rien. C'est une commande vraiment très puissante pour organiser l'historique.
En pratique, qu'est-ce que ça signifie ? Mieux qu'avec tous les autres systèmes de versions, vous pouvez utiliser [Git][git] pour vous concentrer sur votre code. En effet, on peut envoyer les commits après avoir coder. Par exemple, vous pouvez coder sur la résolution du bug b01, du bug b02 et de la feature f03. Puis ensuite, vous pouvez créer une branche par bug et par feature. Puis commiter les modifications pour chaque branche et chaque feature. Puis finalement merger tous les modifications dans la branche principale.
Tout a été pensé pour vous permettre de coder d'abord, puis de vous occuper du système de version plus tard. Bien entendu, faire des commit atomique au fur et à mesure du code permet de gagner du temps et de ne pas trop s'embêter pour organiser les branches. Mais rien ne vous y oblige. Par contre faire la même chose dans d'autres systèmes de versions n'est absolument pas naturel.
Avec [Git][git] vous pouvez aussi dépendre de plusieurs sources. Ainsi, plutôt que d'avoir un serveur centralisé, vous pouvez avoir plusieurs sources. Vous pouvez définir ce genre de chose très finement.
Ce qui change le plus avec [Git][git] c'est la vision d'un projet centralisé sur un serveur avec plusieurs personnes qui travaillent dessus. Avec [Git][git] plusieurs personnes peuvent travailler sur le même projet, mais sans nécessairement avoir un *repository* de référence. On peut très facilement résoudre un bug et envoyer le patch à plein d'autres versions du projet.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,155 @@
-----
# Custom
isHidden: false
menupriority: 2
kind: article
date: 2009-11-12T11:39:54+02:00
title: Configure before Use
multiTitle:
fr: Avant l'utilisation, la configuration
en: Configure before use
-----
# Avant l'utilisation, la configuration
## installation
Sous Linux Ubuntu ou Debian :
<div><code class="zsh">$ sudo apt-get install git</code></div>
Sous Mac OS X :
* installez [MacPorts](http://macports.org/install.php)
* installez [Git][git]
<div><code class="zsh">
$ sudo port selfupdate
$ sudo port install git-core
</code></div>
## Configuration globale
Enregistrez le fichier suivant comme le fichier `~/.gitconfig`.
<div><code class="zsh" file="gitconfig">
[color]
branch = auto
diff = auto
status = auto
[alias]
st = status
co = checkout
br = branch
lg = log --pretty=oneline --graph
logfull = log --pretty=fuller --graph --stat -p
undo = checkout
unstage = reset HEAD
# there should be an article on what this command do
uncommit = !zsh -c '"if (($0)); then nb=$(( $0 - 1 )); else nb=0; fi; i=0; while ((i<=nb)); do git revert -n --no-edit HEAD~$i; ((i++)); done; git commit -m \"revert to $0 version(s) back\""'
undomerge = reset --hard ORIG_HEAD
conflict = !gitk --left-right HEAD...MERGE_HEAD
# under Mac OS X, you should use gitx instead
# conflict = !gitx --left-right HEAD...MERGE_HEAD
[branch]
autosetupmerge = true
</code></div>
Vous pouvez obtenir le même résultat en utilisant pour chaque entrée la commande `git config --global`.
Configurez ensuite votre nom et votre email. Par exemple si vous vous appelez John Doe et que votre email est `john.doe@email.com`. Lancez les commandes suivantes :
<div><code class="zsh">
$ git config --global user.name John Doe
$ git config --global user.email john.doe@email.com
</code></div>
Voilà, la configuration de base est terminée. J'ai créé dans le fichier de configuration global des *alias* qui vont permettre de taper des commandes un peu plus courtes.
## Récupération d'un projet déjà versionné
Si un projet est déjà versionné avec [Git][git] vous devez avoir une `URL` pointant vers les sources du projet. La commande a exécuter est alors très simple.
<div><code class="zsh">
$ cd ~/Projets
$ git clone git://main.server/path/to/file
</code></div>
S'il n'y a pas de serveur git sur le serveur distant, mais que vous avez un accès `ssh`, il suffit de remplacer le `git` de l'url par `ssh`. Pour ne pas avoir à entrer votre mot de passe à chaque fois le plus simple est de procéder comme suit :
<div><code class="zsh">
$ ssh-keygen -t rsa
</code></div>
Répondez aux question et n'entrez **surtout PAS** de mot de passe. Ensuite copiez les clés sur le serveur distant. Ce n'est pas la façon la plus sûre de procéder. L'idéal étant d'écrire quand même un mot de passe et d'utiliser `ssh-agent`.
<div><code class="zsh">
me@locahost$ scp ~/.ssh/id_rsa.pub me@main.server:
me@locahost$ ssh me@main.server
password:
me@main.server$ cat id_rsa.pub >> ~/.ssh/authorized_keys
me@main.server$ rm id_rsa.pub
me@main.server$ logout
</code></div>
Maintenant vous n'avez plus besoin de taper votre mot de passe pour accéder à `main.server`. Et donc aussi pour les commandes `git`.
## Créer un nouveau projet
Supposons que vous avez déjà un projet avec des fichiers. Alors il est très facile de le versionner.
<div><code class="zsh">
$ cd /path/to/project
$ git init
$ git add .
$ git commit -m "Initial commit"
</code></div>
Une petite précision. Si vous ne souhaitez pas *versionner* tous les fichiers. Par exemple, les fichiers de compilations intermédiaires. Alors il faut les exclure. Pour cela, avant de lancer la commande `git add .`. Il faut créer un fichier `.gitignore` qui va contenir les *pattern* que git doit ignorer. Par exemple :
<div><code class="zsh">
*.o
*.bak
*.swp
*~
</code></div>
Maintenant si vous voulez créer un repository sur un serveur distant, il faut absolument qu'il soit en mode `bare`. C'est-à-dire que le repository ne contiendra que la partie contenant les informations utile à la gestion de git, mais pas les fichiers du projet. Sans rentrer dans les détails, il suffit de lancer :
<div><code class="zsh">
$ cd /path/to/local/project
$ git clone --bare . ssh://server/path/to/project
</code></div>
Les autres pourront alors récupérer les modifications via la commande vue précédemment :
<div><code class="zsh">
git clone ssh://server/path/to/project
</code></div>
## Résumé de la seconde étape
Vous avez maintenant un répertoire sur votre ordinateur local. Il est versionné. Vous pouvez vous en rendre compte parcequ'à la racine (et à la racine seulement), il y a un répertoire `.git`. Ce répertoire contient tous les fichiers nécessaires au bon fonctionnement de [Git][git].
Il ne reste plus qu'à savoir comment s'en servir maintenant pour obtenir toutes les jolie promesses faites dans la première partie.
[git]: http://git-scm.org "Git"

View file

@ -0,0 +1,31 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-12-06T11:35:34+02:00
title: iphone call filter
multiTitle:
fr: Filtrage d'appel avec l'iPhone
en: iPhone call filter
multiDescription:
fr: Il est vraiment incroyable qu'une telle chose ne soit pas disponible.
en: I can't believe such a lack.
tags:
- iPhone
- Apple
- filter
- blacklist
-----
Il est vraiment incroyable que le filtrage d'appel soit impossible avec un iPhone ! Le *seul* intérêt que j'y vois, c'est une négociation avec les opérateurs pour interdire aux utilisateurs de passer à travers la publicité. C'est tout simplement inacceptable.
Je suis un utilisateur λ de l'iPhone. Le seul moyen de filtrer ses appels, de faire des blacklists ou autre c'est de *jailbreaker* son iPhone. Et je n'en ai aucune envie. Alors si comme moi, vous trouvez ça inacceptable, envoyez un mot à Apple : [http://www.apple.com/feedback/iphone.html](http://www.apple.com/feedback/iphone.html)

View file

@ -0,0 +1,210 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2009-12-14T10:46:36+02:00
title: Git vs. Bzr
multiTitle:
fr: Git ou Bazaar ?
en: Git vs. Bzr
multiSubTitle:
fr: Pourquoi je suis passé de Bazaar à Git
en: Why I switched from bazaar to git
multiDescription:
fr: pas de description.
en: no description.
tags:
- git
- bzr
- DCVS
- Bazaar
-----
begindiv(intro)
Même si je considère que `git` a beaucoup de points noirs, je pense qu'il reste le meilleur DCVS à ce jour avec lequel travailler. C'est pourquoi je commencerai par parler des qualité de bazaar qui manquent à git. Ensuite seulement je donnerai le seul avantage de git qui suffit à le rendre préférable à Bazaar.
enddiv
## La découverte des DCVS
À savoir avant de débuter l'article. Je suis, comme beaucoup, un ancien utilisateur de *subversion*. Je trouve subversion très bien, mais j'ai été conquis par les capacités supplémentaires apportées par les systèmes de versions concurrentes *décentralisés*.
Il y a deux façon de percevoir les systèmes de versions. Soit on voit un système de branches (voir le très bon article sur [betterexplained](http://betterexplained.com/articles/a-visual-guide-to-version-control/)). Soit on peut voir les systèmes de versions comme des moyens d'appliquer des patches. C'est-à-dire que l'on peut soit se concentrer sur les nœuds soit sur les transitions du graphe induit par les différentes versions d'un projet.
Pour git, c'est plutôt ce deuxième point de vue qui a été adopté. C'est un peu normal, étant donné que c'est Linus Torvald qui l'a inventé pour combler les problèmes inhérent aux problèmes de création de code dans le noyau Linux. Et comme historiquement, la communauté Linux se base beaucoup sur les patches, il semblait logique que ce soit ce second point de vue qui soit adopté.
J'ai d'abord été convaincu par Bazaar. Pourquoi ? Les arguments en faveur de bazaar étaient : facilité d'utilisation en particulier, facilité d'adaptation pour tous ceux qui étaient habitués à subversion. Comme c'était mon cas, et que lorsque j'avais essayé de suivre la doc Git à l'époque c'était un peu épique.
Puis avec le temps, je me suis dit que je n'allais quand même pas mourir idiot et que j'allais me mettre sérieusement à `git` histoire de voir si ses défenseurs avaient vraiment raison.
Mon dieu, que ce fut fastidieux. La terminologie est *affreuse* ! Et ce n'est rien de le dire.
## Là où Bazaar est meilleur que `git`
Par exemple, `checkout` qui sert certainement à la même chose du point de vue technique, est dans l'usage un terme employé pour faire des actions qui semblent très différentes à un utilisateur λ. Exemple :
<div><code class="zsh">
git checkout pipo
</code></div>
annule une modification courante du fichier `pipo`
<div><code class="zsh">
git checkout pipo
</code></div>
change de la branche courante vers la branche `pipo`
Et là, comme moi, vous remarquez que la même commande à deux sens complètement différents. Comment ça se passe alors, quand il y a une branche `pipo` et un fichier `pipo` alors ? Et bien par défaut, ça change de branche. Pour lever l'ambigüité il faut utiliser la syntaxe
<div><code class="zsh">
git checkout ./pipo
</code></div>
Oui, bon... Voilà, voilà, voilà....
Ça marche, mais ce n'est pas très convivial. D'autant plus que le mot clé checkout signifiait sous CVS et SVN l'opération pour récupérer un projet distant.
Là où la différence se creuse c'est avec la terminologie Bazaar qui est bien plus naturelle. Car il n'y a pas de commande pour changer de branche, puisqu'il y a une branche par répertoire. Ainsi, pour changer de branche, il suffit de faire `cd path/to/branch`. Et pour revenir en arrière :
<div><code class="zsh">
bzr revert pipo
</code></div>
De plus, la plupart des commandes bazaar prennent en paramètre un numéro de révision, par exemple pour revenir 3 versions précédentes il suffit d'écrire :
<div><code class="zsh">
bzr revert -r -3 pipo
</code></div>
L'équivalent sous git est beaucoup plus cryptique :
<div><code class="zsh">
bzr checkout HEAD~3 pipo
</code></div>
Encore un fois, Bazaar est bien plus lisible.
Revenir dans le temps pour tout le projet :
avec Bazaar :
<div><code class="zsh">
bzr revert -r -3 pipo
</code></div>
et avec `git` ? `git checkout` ? Bien sûr que non voyons ! Ce serait bien trop simple. Ce que l'on trouve dans les forums c'est :
<div><code class="zsh">
git reset --hard HEAD~3
</code></div>
Sauf que cette syntaxe est horrible. Elle oublie 'réellement' les révisions. Il faut donc l'utiliser avec prudence. Mais en effet, je conseillerai plutôt :
<div><code class="zsh">
git checkout HEAD~3 -- . && git commit -m 'back in time'
</code></div>
Histoire d'avoir la branche backup sous la main, car sinon, on risque de perdre définitivement la version courante de HEAD. Qui ramène la branche locale à ce point. Mais il reste des erreur s'il y a eu des ajouts de fichier entre temps. *Le seul et l'unique vraiment propre de revenir en arrière dans git c'est de lancer la commande suivante :*
<div><code class="zsh">
for i in $(seq 0 2); do
git revert -n --no-edit head~$i;
done
git commit -m "reverted 3 versions back"
</code></div>
ce qui signifie sur un système `UNIX` en `zsh` (ou `bash`) faire `git revert` de toutes les dernières versions. Même si quelqu'un d'autre à fait un pull de vos modification intermédiaire il ne sera pas embêté et il sera au courant de ce qu'il s'est passé.
La règle est simple : *Ne JAMAIS utiliser la commande `git reset` avec une version que d'autres personnes auraient pu avoir `fetcher`.*
Voilà, c'est dit. Découvrir ça m'a pris pas mal de temps, avec plein d'essai de tous les cotés. Le plus sûr reste toujours la méthode vue plus haut. Si vous souhaitez automatiser cela, le plus simple est d'ajouter l'alias suivant à votre fichier `~/.gitconfig`. Bien sûr l'alias ne fonctionnera que sur les environnement possédant `zsh`, ce qui est le cas de la plupart des environnements UNIX (Ubuntu, Mac OS X...).
<div><code class="zsh" file="gitconfig">
[alias]
uncommit = !zsh -c '"if (($0)); then nb=$(( $0 - 1 )); else nb=0; fi; i=0; while ((i<=nb)); do git revert -n --no-edit HEAD~$i; ((i++)); done; git commit -m \"revert to $0 version(s) back\""'
</code></div>
# Ce qui fait que `git` est le meilleur DCVS jusqu'à aujourd'hui
Après avoir énoncé les cotés négatifs (et je les trouve nombreux) de git. Voici les cotés positifs qui a eux seul valent la peine de se coltiner tous les problèmes inhérent à `git`.
## Cheap branching
Vous travaillez toujours dans le même répertoire principal. Par exemple, vous pouvez travailler sur deux corrections de bug. Disons `fix1` et `fix2` nécessitant la modification respective de `file1` et `file2`. Vous pouvez travailler dans n'importe quel ordre sur vos deux fichiers dans la branche `master`. Puis, une fois votre travail fini. Aller dans la branche `fix1` pour commiter `file1`. Puis aller dans la branche `fix2` pour commiter `file2`. Et enfin, merger les deux branches dans `master`.
<div><code class="zsh">
> vim file1
> vim file2
> git br fix1
> git add file1
> git commit -m 'fix1'
> git br fix2
> git add file2
> git commit -m 'fix2'
> git commit master
> git merge fix1
> git merge fix2
</code></div>
Et il est vraiment très agréable de ne pas se soucier d'être dans la *bonne* branche. Vous n'avez à vous occuper que de votre code et seulement ensuite vous occuper du système de version.
Sous Bazaar, il m'est souvent arriver de coder dans la mauvaise branche. Pour récupérer le coup, on doit copier les modifications du fichier dans la bonne branche et faire un revert sur le fichier en question, puis aller dans la bonne branche pour commiter les modifications. Enfin, la plupart du temps, je me trompe de branche et puis tant pis, je merge les deux tout en sachant que c'est sale.
C'est pourquoi je préfère utiliser `git`. Si Bazaar venait à implémenter ce système de *cheap branching*, je le replacerai certainement en tête.

View file

@ -0,0 +1,27 @@
-----
# Custom
isHidden: false
menupriority: 1
kind: article
date: 2010-01-04T12:31:47+02:00
title: Change default shell on Mac OS X
multiTitle:
fr: Changer le shell par défaut sous Mac OS X
en: Change default shell on Mac OS X
multiDescription:
fr: pas de description.
en: no description.
tags:
- Apple
- Mac
- OS X
-----
Je viens de trouver le moyen de changer son shell par défaut sous Mac OS X. Cette note est plus pour moi. Mais elle peut aussi servir à quelqu'un d'autre. Il suffit de lancer la commande :
<div><code class="zsh">
> chsh
</code></div>

Some files were not shown because too many files have changed in this diff Show more