<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code-It</title>
	<atom:link href="http://lois.di-qual.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lois.di-qual.net/blog</link>
	<description></description>
	<lastBuildDate>Tue, 30 Oct 2012 19:19:29 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Install and use tesseract on iOS with tesseract-ios</title>
		<link>http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/</link>
		<comments>http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/#comments</comments>
		<pubDate>Mon, 08 Oct 2012 21:56:02 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[lib]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[tesseract]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=159</guid>
		<description><![CDATA[Update 10/10/12 I updated tesseract-ios-lib with a (fake) armv7s slice. There is no need to remove armv7s from build architectures anymore. More informations about this change on my previous post. Introduction In my last article about how to compile tesseract for iOS SDK 6, I quickly posted two links to my github repos: tesseract-ios: an [...]]]></description>
				<content:encoded><![CDATA[<h3>Update 10/10/12</h3>
<p>I updated <code class="codecolorer text default"><span class="text">tesseract-ios-lib</span></code> with a (fake) armv7s slice. There is no need to remove armv7s from build architectures anymore. More informations about this change on <a href="http://lois.di-qual.net/blog/compile-tesseract-for-ios-sdk-6-0/">my previous post</a>.</p>
<h2>Introduction</h2>
<p>In my last article about <a href="http://lois.di-qual.net/blog/compile-tesseract-for-ios-sdk-6-0/">how to compile tesseract for iOS SDK 6</a>, I quickly posted two links to my github repos:</p>
<ul>
<li><a href="https://github.com/ldiqual/tesseract-ios">tesseract-ios</a>: an Objective-C wrapper for tesseract</a></li>
<li><a href="https://github.com/ldiqual/tesseract-ios-lib">tesseract-ios-lib</a>: the tesseract library compiled for iOS (universal armv7/i386 library)</a>
</ul>
<p>Some comments complained about the lack of guide to install and use this wrapper. I&#8217;m going to show you how to build a new iOS project with tesseract, from scratch.</p>
<p><span id="more-159"></span></p>
<h2>Create the project</h2>
<p>Create a simple Single View Application from XCode:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_create_project.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_create_project-1024x628.png" alt="" title="ts_create_project" width="1024" height="628" class="alignnone size-large wp-image-188" /></a></p>
<p>Name it whatever you want:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_create_project2.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_create_project2-1024x628.png" alt="" title="ts_create_project2" width="1024" height="628" class="alignnone size-large wp-image-189" /></a></p>
<h2>Project structure</h2>
<p>Download <a href="https://github.com/ldiqual/tesseract-ios">tesseract-ios</a>, <a href="https://github.com/ldiqual/tesseract-ios-lib">tesseract-ios-lib</a>, and <a href="http://code.google.com/p/tesseract-ocr/downloads/list">your language trained data</a>.</p>
<p>Then, open your project folder in Finder, and organise it like this:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_folder_structure.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_folder_structure.png" alt="" title="ts_folder_structure" width="528" height="542" class="alignnone size-full wp-image-190" /></a></p>
<p>Add &#8220;tesseract-ios&#8221; and &#8220;tesseract-ios-lib&#8221; in your project by creating groups:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_add_libs.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_add_libs-1024x628.png" alt="" title="ts_add_libs" width="1024" height="628" class="alignnone size-large wp-image-184" /></a></p>
<p>Then, add &#8220;tessdata&#8221; <strong>by reference</strong>:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_add_tessdata.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_add_tessdata-1024x628.png" alt="" title="ts_add_tessdata" width="1024" height="628" class="alignnone size-large wp-image-185" /></a></p>
<p>This step is extremely important, double check that you&#8217;re adding it by reference or your application will crash.</p>
<h2>Project settings</h2>
<p>Go to your project configuration, select your target, and click on &#8220;Build Settings&#8221;. Then, set the C++ compiler to default:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_change_compiler.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_change_compiler.png" alt="" title="ts_change_compiler" width="826" height="313" class="alignnone size-full wp-image-187" /></a></p>
<p>And set the build architecture to &#8220;armv7&#8243; (instead of &#8220;armv7 armv7s&#8221;, as tesseract-ios-lib doesn&#8217;t contain an armv7s slice for now):</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_change_arch.png"><img src="http://lois.di-qual.net/blog/wp-content/uploads/2012/10/ts_change_arch.png" alt="" title="ts_change_arch" width="772" height="487" class="alignnone size-full wp-image-186" /></a></p>
<p>We&#8217;re ready to use tesseract.</p>
<h2>Usage</h2>
<p>Add an image called &#8220;image_sample.jpg&#8221; to your project. </p>
<p>Then, in <code class="codecolorer text default"><span class="text">ViewController.m</span></code>, add <code class="codecolorer text default"><span class="text">#import tesseract.h</span></code> and put the following lines in <code class="codecolorer text default"><span class="text">-viewDidLoad</span></code>:</p>
<div class="codecolorer-container objc twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Tesseract<span style="color: #002200;">*</span> tesseract <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>Tesseract alloc<span style="color: #002200;">&#93;</span> initWithDataPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;tessdata&quot;</span> language<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;eng&quot;</span><span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#91;</span>tesseract setImage<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>UIImage imageNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;image_sample.jpg&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#91;</span>tesseract recognize<span style="color: #002200;">&#93;</span>;<br />
<br />
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, <span style="color: #002200;">&#91;</span>tesseract recognizedText<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>Methods reference is available <a href="https://github.com/ldiqual/tesseract-ios">on the project repo</a>.</p>
<p>You should get the image-extracted text in your console.</p>
<h2>Project code</h2>
<p>You can download the tutorial source code right here: <a href='http://lois.di-qual.net/blog/wp-content/uploads/2012/10/TesseractSample.zip'>TesseractSample</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Compile tesseract for iOS SDK 6.0</title>
		<link>http://lois.di-qual.net/blog/compile-tesseract-for-ios-sdk-6-0/</link>
		<comments>http://lois.di-qual.net/blog/compile-tesseract-for-ios-sdk-6-0/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 19:00:34 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ios6.0]]></category>
		<category><![CDATA[iphone-sdk]]></category>
		<category><![CDATA[ocr]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=141</guid>
		<description><![CDATA[Update 10/25/12 Added instructions to integrate an armv7s slice in liblept.a and libtesseract_all.a. Update 09/24/12 To make the iOS integration easier, I made a Github repo containing an Objective-C wrapper for Tesseract. It relies on an other repo containing tesseract &#038; leptonica libs. Feel free to improve them ! Objective-C wrapper: https://github.com/ldiqual/tesseract-ios Compiled libraries: https://github.com/ldiqual/tesseract-ios-lib [...]]]></description>
				<content:encoded><![CDATA[<h3>Update 10/25/12</h3>
<p>Added instructions to integrate an armv7s slice in <code class="codecolorer text default"><span class="text">liblept.a</span></code> and <code class="codecolorer text default"><span class="text">libtesseract_all.a</span></code>.</p>
<h3>Update 09/24/12</h3>
<p>To make the iOS integration easier, I made a Github repo containing an Objective-C wrapper for Tesseract. It relies on an other repo containing tesseract &#038; leptonica libs. Feel free to improve them !</p>
<ul>
<li>Objective-C wrapper: <a href="https://github.com/ldiqual/tesseract-ios">https://github.com/ldiqual/tesseract-ios</a></li>
<li>Compiled libraries: <a href="https://github.com/ldiqual/tesseract-ios-lib">https://github.com/ldiqual/tesseract-ios-lib</a></li>
</ul>
<p>More informations about these repos on my <a href="http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/">next article</a>.</p>
<h2>Introduction</h2>
<p>I had troubles while following the compiling guide from this blog: <a href="http://tinsuke.wordpress.com/2011/11/01/how-to-compile-and-use-tesseract-3-01-on-ios-sdk-5/">http://tinsuke.wordpress.com/2011/11/01/how-to-compile-and-use-tesseract-3-01-on-ios-sdk-5/</a>. Some dependencies are missing on a fresh Mountain Lion with Xcode 4.5, and more importantly: the <code class="codecolorer text default"><span class="text">build_dependencies.sh</span></code> won&#8217;t work.</p>
<p>Here is why: Xcode 4.5 and iOS SDK 6.0 don&#8217;t support armv6 anymore.</p>
<p>So here are the steps to build <a href="http://code.google.com/p/tesseract-ocr/">tesseract-ocr</a> for iOS SDK 6.0.</p>
<p><span id="more-141"></span></p>
<h2>Requirements</h2>
<p>If you don&#8217;t have HomeBrew already, that&#8217;s a shame. Run to <a href="http://mxcl.github.com/homebrew/">this website</a> and install it.</p>
<p>Then, install libtool and automake:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ brew install libtool automake</div></td></tr></tbody></table></div>
<p>You should have installed &#8216;Command Line Tools&#8217; after the Homebrew installation, but if you forgot: Open Xcode&#8217;s preferences, and install them from the &#8216;Downloads&#8217; tab.</p>
<p>The build process will need <code class="codecolorer text default"><span class="text">libtoolize</span></code>. Just make a symlink to <code class="codecolorer text default"><span class="text">glibtoolize</span></code>:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize</div></td></tr></tbody></table></div>
<p>We&#8217;re good to go.</p>
<h2>Sources and compilation</h2>
<p>The steps will more or less follow the tinsuke&#8217;s article, except for one thing: the build script.</p>
<p>Get the following sources:</p>
<ul>
<li>tesseract: <a href="http://code.google.com/p/tesseract-ocr/downloads/detail?name=tesseract-3.01.tar.gz">http://code.google.com/p/tesseract-ocr/downloads/detail?name=tesseract-3.01.tar.gz</a></li>
<li>leptonica: <a href="http://www.leptonica.com/source/leptonica-1.69.tar.gz">http://www.leptonica.com/source/leptonica-1.69.tar.gz</a></li>
<li>build_dependencies.sh: <a href="https://gist.github.com/3763217">https://gist.github.com/3763217</a> (click on &#8220;raw&#8221; and save it to your computer)</li>
</ul>
<p>Then, organize your folder with the following structure:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">./build/<br />
&nbsp; dependencies/ <br />
&nbsp; leptonica-1.69/<br />
&nbsp; tesseract-3.01/<br />
&nbsp; build_dependencies.sh</div></td></tr></tbody></table></div>
<p>You might want to modify <code class="codecolorer text default"><span class="text">build_dependencies.sh</span></code> to make <code class="codecolorer text default"><span class="text">LEPTON_LIB</span></code> and <code class="codecolorer text default"><span class="text">TESSERACT_LIB</span></code> match the proper folders.</p>
<p>Now, you can build the libraries:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ chmod +x ./build_dependencies.sh<br />
$ ./build_dependencies</div></td></tr></tbody></table></div>
<p>In <code class="codecolorer text default"><span class="text">dependencies/lib/</span></code>, you&#8217;ll find <code class="codecolorer text default"><span class="text">liblept.a</span></code> and <code class="codecolorer text default"><span class="text">libtesseract_all.a</span></code>, these are the only libraries you need so you can remove other ones. Both contain armv7 and i386 slices only, but many iOS 5 projects require an armv7s slice.</p>
<p>Just <a href="http://www.galloway.me.uk/2012/09/hacking-up-an-armv7s-library/">follow this Matt Galloway&#8217;s blog post</a> to generate and put an armv7s slice into the libs.</p>
<p>Now you just have to copy <code class="codecolorer text default"><span class="text">dependencies/</span></code> in your Xcode Project, and follow <a href="http://lois.di-qual.net/blog/install-and-use-tesseract-on-ios-with-tesseract-ios/">my next article</a> on how to use tesseract.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/compile-tesseract-for-ios-sdk-6-0/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Watch TV on Raspberry Pi with OpenELEC media-build</title>
		<link>http://lois.di-qual.net/blog/watch-tv-on-raspberry-pi-with-openelec-media-build/</link>
		<comments>http://lois.di-qual.net/blog/watch-tv-on-raspberry-pi-with-openelec-media-build/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 17:34:55 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=107</guid>
		<description><![CDATA[I&#8217;m using an Elgato EyeTV DTT to watch TV on my Macbook Pro. I wanted to use this USB tuner on my Rasperry Pi with Raspbian, but VLC doesn&#8217;t support hardware-accelerated video yet. So I found this post on Tiago Pires&#8217; blog, which describes how to build OpenElec from scratch including media-build. Unfortunately, some things [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m using an <a href="http://www.elgato.com/elgato/int/mainmenu/products/tuner/DTT08/product1.en.html">Elgato EyeTV DTT</a> to watch TV on my Macbook Pro. I wanted to use this USB tuner on my Rasperry Pi with Raspbian, but VLC doesn&#8217;t support hardware-accelerated video yet. So I found <a href="http://tandrepires.wordpress.com/2012/08/01/raspberry-pi-openelec-pvr-dvb-t/">this post</a> on Tiago Pires&#8217; blog, which describes how to build OpenElec from scratch including media-build. Unfortunately, some things are missing in this post, and some others are unnecessary. A lot of things in this post comes from his article, so thank you <img src='http://lois.di-qual.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Media-build is just a script that will get the most up-to-date dvb drivers and include them in OpenElec. I don&#8217;t think it&#8217;s required if your DVB tuner is supported for a longtime by Linux, but let&#8217;s include it anyway.</p>
<p><span id="more-107"></span></p>
<h2>The easy way</h2>
<p>
As I&#8217;m really kind, I built OpenELEC.tv, media-build, and tvheadend for you. Just download these files and go to the &#8220;Create SD-card&#8221; step.
</p>
<ul>
<li><a href="https://docs.google.com/open?id=0B5y4Va3eNoFCbS1Na2xpNkJKZGM">OpenELEC (commit 1355da624e) + media-build (commit 425bf0084e)</a></li>
<li><a href="https://docs.google.com/open?id=0B5y4Va3eNoFCM3dTUjdiQjVhVWs">tvheadend</a>
</ul>
<h2>The hard way &#8211; let&#8217;s build this</h2>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">// Coming soon</div></td></tr></tbody></table></div>
<h2>Create the SD-card</h2>
<p>If you&#8217;re not coming from the build section, just download OpenElec from the top of this post, and put it in a folder. Then, open a terminal and go to this folder.</p>
<p>Insert your SD card, and extract the archive:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ tar zxvf ...</div></td></tr></tbody></table></div>
<p>Then, it depends of what you platform is.</p>
<h3>Linux</h3>
<p>I&#8217;m assuming that <code class="codecolorer text default"><span class="text">/dev/sdb</span></code> is your SDCard device:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ sudo ./create_sdcard /dev/sdb<br />
$ sudo umount /dev/sdb1 &amp;&amp; umount /dev/sdb2</div></td></tr></tbody></table></div>
<h3>OSX</h3>
<p>I made a pending Pull Request on Github to handle OSX SDCard installation. As it&#8217;s not yet merged to the official OpenELEC repo, you&#8217;ll have to go <a href="https://raw.github.com/ldiqual/OpenELEC.tv/650f5a9db89d2c7bbde069ac761cf10f29173f31/packages/tools/bcm2835-bootloader/files/create_sdcard">here</a> and save it to <code class="codecolorer text default"><span class="text">./create_sdcard</span></code>.</p>
<p>Then, assuming that your SDCard is <code class="codecolorer text default"><span class="text">/dev/disk3</span></code>:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ sudo ./create_sdcard /dev/disk3</div></td></tr></tbody></table></div>
<h2>Tvheadend</h2>
<p>Boot your RPi, you should get a beautiful XBMC interface. From your regular computer you should see an <code class="codecolorer text default"><span class="text">openelec</span></code> shared network folder. Extract the <code class="codecolorer text default"><span class="text">tvheadend</span></code> archive somewhere on your computer, and move the resulting folder to <code class="codecolorer text default"><span class="text">openelec/downloads/</span></code>.</p>
<p>On XBMC, go to <code class="codecolorer text default"><span class="text">System -&gt; Settings -&gt; Add-ons -&gt; Install from zip file</span></code>. Then, select thz tvheadend zip file from <code class="codecolorer text default"><span class="text">Home/downloads/service.multimedia.hts-tvheadend/</span></code>. You should get an installation confirmation message. Reboot your RPi.</p>
<p>When your RPi is fully started up, navigate to the following link from your computer&#8217;s browser:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://RPI_ADDRESS:9981/extjs.html</div></td></tr></tbody></table></div>
<p>Then, navigate to <code class="codecolorer text default"><span class="text">Configuration -&gt; TV Adapters</span></code> and select your adapter in the list. You can now configure your tuner&#8230; and watch TV !</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/watch-tv-on-raspberry-pi-with-openelec-media-build/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>django-wkhtmltopdf on a linux (Webfaction) server</title>
		<link>http://lois.di-qual.net/blog/django-wkhtmltopdf-on-a-linux-webfaction-server/</link>
		<comments>http://lois.di-qual.net/blog/django-wkhtmltopdf-on-a-linux-webfaction-server/#comments</comments>
		<pubDate>Tue, 04 Sep 2012 13:10:08 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[webfaction]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=119</guid>
		<description><![CDATA[Generating PDF with python is not an easy thing. Here is what I&#8217;ve tried: xhtml2pdf: the worst. It has a very bad CSS interpreter and it is pretty impossible to make a clean PDF out from a complex html page. WeasyPrint: that&#8217;s better. It has its own HTML and CSS2 interpreters, and despite some minor [...]]]></description>
				<content:encoded><![CDATA[<p>Generating PDF with python is not an easy thing. Here is what I&#8217;ve tried:</p>
<ul>
<li><a href="http://www.xhtml2pdf.com/">xhtml2pdf</a>: the worst. It has a very bad CSS interpreter and it is pretty impossible to make a clean PDF out from a complex html page.</li>
<li><a href="http://weasyprint.org/">WeasyPrint</a>: that&#8217;s better. It has its own HTML and CSS2 interpreters, and despite some minor issues it is fairly reliable. However it requires <a href="http://lois.di-qual.net/blog/python-install-weasyprint-on-a-dedicated-webfaction-server/">some big dependencies</a>, and I eventually had some memory issues on my webserver.</li>
<li><a href="https://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a> with its <a href="https://github.com/incuna/django-wkhtmltopdf">Django wrapper</a>: for now, the best. It makes use of Webkit to render HTML+CSS+JS(!) pages, I don&#8217;t think you can do better. However, it requires QT, and this is big. Well, not the &#8220;classical&#8221; QT, a patched QT (that&#8217;s even worse) that allows to run without an X server. This is what I&#8217;m using for now in my projects</li>
</ul>
<p>We&#8217;ll see here how to build wkhtmltopdf and a basic <code class="codecolorer text default"><span class="text">django-wkhtmltopdf</span></code> usage. These steps has been tested on a Webfaction server (CentOS 6) through SSH.</p>
<p><span id="more-119"></span></p>
<h2>The easy way</h2>
<p>Enter this command and go to the &#8220;Post-install&#8221; chapter.</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">curl -fsSkL https://raw.github.com/gist/3608048/wkhtmltopdf.sh | sh</div></td></tr></tbody></table></div>
<p>It will install wkhtmltopdf in <code class="codecolorer text default"><span class="text">~/bin</span></code> with its static libraries. </p>
<h2>The hard way &#8211; Let&#8217;s build this</h2>
<p>This is mostly taken from the <a href="https://code.google.com/p/wkhtmltopdf/wiki/compilation">wkhtmltopdf Wiki</a>, but with some no-shared-libraries webserver specifics. Log on SSH, and let the magic begin.</p>
<p>Create a <code class="codecolorer text default"><span class="text">~/download</span></code> folder</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ mkdir -p ~/downloads<br />
$ cd ~/downloads</div></td></tr></tbody></table></div>
<p>Get wkhtmltopdf-qt:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ git clone git://gitorious.org/+wkhtml2pdf/qt/wkhtmltopdf-qt.git wkhtmltopdf-qt<br />
$ cd wkhtmltopdf-qt<br />
$ git checkout staging<br />
$ QTDIR=. ./bin/syncqt</div></td></tr></tbody></table></div>
<p>Configure, and build it! It will take some time (about an hour, which is not much as we disabled a lot of features):</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./configure -release -static -fast -exceptions -no-accessibility -no-stl -no-sql-ibase -no-sql-mysql -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 -no-qt3support -xmlpatterns -no-phonon -no-phonon-backend -webkit -no-scripttools -no-mmx -no-3dnow -no-sse -no-sse2 &nbsp;-qt-zlib -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg -graphicssystem raster -opensource -nomake tools -nomake examples -nomake demos -nomake docs -nomake translations -no-opengl -no-dbus -no-multimedia -openssl -no-declarative -largefile -rpath -no-nis -no-cups -no-iconv -no-pch -no-gtkstyle -no-nas-sound -no-sm -no-xshape -no-xinerama -no-xcursor -no-xfixes -no-xrandr -no-mitshm -no-xinput -no-xkb -no-glib -no-openvg &nbsp;-no-xsync -no-audio-backend -no-sse3 -no-ssse3 -no-sse4.1 -no-sse4.2 -no-avx -no-neon -confirm-license -prefix &quot;../wkqt&quot;<br />
$ gmake -j3<br />
$ gmake install</div></td></tr></tbody></table></div>
<p>Then, download wkhtmltopdf, and build it:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cd ~/downloads<br />
$ git clone git://github.com/antialize/wkhtmltopdf.git wkhtmltopdf<br />
$ cd wkhtmltopdf<br />
$ ../wkqt/bin/qmake<br />
$ make</div></td></tr></tbody></table></div>
<p>You now have wkhtmltopdf and its static dependencies in <code class="codecolorer text default"><span class="text">./bin/</span></code>. Let&#8217;s copy them into <code class="codecolorer text default"><span class="text">~/bin</span></code>:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ mkdir -p ~/bin<br />
$ cp bin/* ~/bin/</div></td></tr></tbody></table></div>
<h2>Post-installation</h2>
<p>We need <code class="codecolorer text default"><span class="text">~/bin</span></code> in our <code class="codecolorer text default"><span class="text">$PATH</span></code>. That&#8217;s where django-wkhtmltopdf will look for. Add the following line in your <code class="codecolorer text default"><span class="text">~/.bashrc</span></code>.</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">export PATH=$HOME/bin:$PATH<br />
export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH</div></td></tr></tbody></table></div>
<p>And source it:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ source ~/.bashrc</div></td></tr></tbody></table></div>
<p>We&#8217;re done with wkhtmltopdf, let&#8217;s install its Django wrapper.</p>
<h2>django-wkhtmltopdf</h2>
<p>Go to your django app, and install django-wkhtmltopdf with PIP:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ pip install wkhtmltopdf</div></td></tr></tbody></table></div>
<p>Then, in your view:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> wkhtmltopdf.<span style="color: black;">views</span> <span style="color: #ff7700;font-weight:bold;">import</span> PDFTemplateResponse<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> view<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; PDFTemplateResponse<span style="color: black;">&#40;</span>request<span style="color: #66cc66;">,</span> template_name<span style="color: #66cc66;">,</span> context_dictionary<span style="color: black;">&#41;</span>.<span style="color: black;">rendered_content</span></div></td></tr></tbody></table></div>
<p>Be careful, this last line of code is not documented in the django-wkhtmltopdf&#8217;s wiki. It may be subject to changes in future releases. However, that&#8217;s the only way I found to get a binary-string instead of a HttpResponse.</p>
<p>That&#8217;s all, folks !</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/django-wkhtmltopdf-on-a-linux-webfaction-server/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python &#8211; Install WeasyPrint on a linux (Webfaction) server</title>
		<link>http://lois.di-qual.net/blog/python-install-weasyprint-on-a-dedicated-webfaction-server/</link>
		<comments>http://lois.di-qual.net/blog/python-install-weasyprint-on-a-dedicated-webfaction-server/#comments</comments>
		<pubDate>Thu, 23 Aug 2012 16:28:39 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[weasyprint]]></category>
		<category><![CDATA[webfaction]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=95</guid>
		<description><![CDATA[WeasyPrint is a great python library to generate PDFs from HTML. It beats hands down xhtml2pdf, by interpreting CSS and HTML the right way. However, it has a lot of dependencies and it just can&#8217;t fit in a simple python virtual environment. It took me a whole day to install on Webfaction, so I think [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://weasyprint.org/">WeasyPrint</a> is a great python library to generate PDFs from HTML. It beats hands down <a href="http://www.xhtml2pdf.com/">xhtml2pdf</a>, by interpreting CSS and HTML the right way.</p>
<p>However, it has a lot of dependencies and it just can&#8217;t fit in a simple python virtual environment. It took me a whole day to install on Webfaction, so I think it would be helpful to show how to do it properly.</p>
<p>These steps has been tested on a Webfaction CentOS 6 server (python2.7), and they should be the same for others Linux systems. If your system is not exactly the same, you might have to install other dependencies manually. <a href="http://www.linuxfromscratch.org/">Linux From Scratch</a> is your helpful friend in this kind of situation.</p>
<p><span id="more-95"></span></p>
<p>Log to ssh, and let the magic begin.</p>
<h2>Dependencies</h2>
<p>WeasyPrint relies on the following dependencies:</p>
<ul>
<li>Pango >= 1.29.3 (with introspection)</li>
<li>pycairo</li>
<li>GdkPixbuf >= 2.25 (with introspection, required for images other than PNG)</li>
<li>PyGObject 3.x</li>
</ul>
<p>Of course, these dependencies have their own dependencies. It becomes really hard to install all of them by hand, so I made a small <a href="https://raw.github.com/gist/3438324/weasyprint_webfaction.sh">shell script</a> to do it automatically. It will install all of them in your home directory (with <code class="codecolorer text default"><span class="text">--prefix=$HOME</span></code>).</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ curl -fsSkL https://raw.github.com/gist/3438324/weasyprint_webfaction.sh | sh</div></td></tr></tbody></table></div>
<p>Then, add the following lines to your <code class="codecolorer text default"><span class="text">~/.bashrc</span></code>:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">export LD_LIBRARY_PATH=$HOME/lib<br />
export PYTHONPATH=&quot;$HOME/lib/python2.7/site-packages/:$PYTHONPATH&quot;</div></td></tr></tbody></table></div>
<p>And source it:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ source ~/.bashrc</div></td></tr></tbody></table></div>
<h2>Virtual environment</h2>
<p>As we will install global python libraries, we need a virtual environment that is aware of system packages. If you didn&#8217;t create one yet:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cd /path/to/project<br />
$ virtualenv --system-site-packages ./venv</div></td></tr></tbody></table></div>
<p>If your virtual env is already created:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cd /path/to/project<br />
$ mv ./venv/lib/python2.7/no-global-site-packages.txt ./venv/lib/python2.7/_no-global-site-packages.txt</div></td></tr></tbody></table></div>
<h2>WeasyPrint</h2>
<p>Here we are. Install WeasyPrint using the following lines:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ source ./venv/bin/activate<br />
$ pip install weasyprint</div></td></tr></tbody></table></div>
<p>Finally, test it:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ weasyprint http://weasyprint.org ./weasyprint-website.pdf</div></td></tr></tbody></table></div>
<p>If there is an import error, please check that you correctly sourced your <code class="codecolorer text default"><span class="text">~/.bashrc</span></code>.</p>
<p>Thanks to <a href="http://community.webfaction.com/users/1146/iliasr/">Ilias Romanos</a> from the Webfaction Q/A forum for the pyCairo part ! Don&#8217;t hesitate to improve the install script on <a href="https://gist.github.com/3438324">github:gist</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/python-install-weasyprint-on-a-dedicated-webfaction-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django &#8211; UnicodeDecodeError using i18n</title>
		<link>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/</link>
		<comments>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/#comments</comments>
		<pubDate>Mon, 30 Jul 2012 21:32:11 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[UnicodeDecodeError]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=83</guid>
		<description><![CDATA[If you&#8217;re using i18n in your django website, you may encounter this issue. It took me two hours to find where the problem came from: you have to use ugettext instead of gettext if your translated strings contains non-ascii characters. gettext => ugettext With gettext: 12345from django.utils.translation import gettext as _ define my_view&#40;request&#41;: &#160; &#160; [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;re using i18n in your django website, you may encounter this issue. It took me two hours to find where the problem came from: you have to use <code class="codecolorer text default"><span class="text">ugettext</span></code> instead of <code class="codecolorer text default"><span class="text">gettext</span></code> if your translated strings contains non-ascii characters.</p>
<p><span id="more-83"></span></p>
<h2>gettext => ugettext</h2>
<p>With <code class="codecolorer text default"><span class="text">gettext</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">gettext</span> <span style="color: #ff7700;font-weight:bold;">as</span> _<br />
<br />
define my_view<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span><span style="color: black;">&#41;</span> // Raises a <span style="color: #008000;">UnicodeDecodeError</span> because <span style="color: #483d8b;">&quot;é&quot;</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">unicode</span></div></td></tr></tbody></table></div>
<p>With <code class="codecolorer text default"><span class="text">ugettext</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> ugettext <span style="color: #ff7700;font-weight:bold;">as</span> _<br />
<br />
define my_view<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes nothing&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span><span style="color: black;">&#41;</span> // Prints <span style="color: #483d8b;">&quot;Here comes something spécial&quot;</span></div></td></tr></tbody></table></div>
<h2>ugettext or ugettext_lazy ?</h2>
<p>Two simple rules:</p>
<ul>
<li>Use <code class="codecolorer text default"><span class="text">ugettext_lazy</span></code> in global scopes (model fields, django settings, everything not wrapped by a function or method, &#8230;)</li>
<li>Use <code class="codecolorer text default"><span class="text">ugettext</span></code> everywhere else (in views, methods, functions, &#8230;)</li>
</ul>
<p>That&#8217;s it !</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/django-unicodedecodeerror-using-i18n/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django &#8211; Absolute media URIs from templates</title>
		<link>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/</link>
		<comments>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/#comments</comments>
		<pubDate>Mon, 16 Jul 2012 21:54:17 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=74</guid>
		<description><![CDATA[Sometimes, you need to build an absolute URI to a media file from your templates: 1http://example.com/media/sample.jpg After following this small tutorial, you&#8217;ll be able to do this: 12{% load mytemplatetags %} {{ media_name&#124;absolute_media_url:request }} Settings In urls.py, in urlpatterns, add a reverse name to the media URL: 123456urlpatterns = patterns&#40;'', &#160; &#160; # Before &#160; [...]]]></description>
				<content:encoded><![CDATA[<p>Sometimes, you need to build an absolute URI to a media file from your templates:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://example.com/media/sample.jpg</div></td></tr></tbody></table></div>
<p>After following this small tutorial, you&#8217;ll be able to do this:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{% load mytemplatetags %}<br />
{{ media_name|absolute_media_url:request }}</div></td></tr></tbody></table></div>
<p><span id="more-74"></span></p>
<h2>Settings</h2>
<p>In <code class="codecolorer text default"><span class="text">urls.py</span></code>, in <code class="codecolorer text default"><span class="text">urlpatterns</span></code>, add a reverse name to the media URL:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">urlpatterns <span style="color: #66cc66;">=</span> patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Before</span><br />
&nbsp; &nbsp; <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^media/(?P&lt;path&gt;.*)$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'django.views.static.serve'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'document_root'</span>: settings.<span style="color: black;">MEDIA_ROOT</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># After</span><br />
&nbsp; &nbsp; url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^media/(?P&lt;path&gt;.*)$'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'django.views.static.serve'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'document_root'</span>: settings.<span style="color: black;">MEDIA_ROOT</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;media&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>You can now reverse media files using <code class="codecolorer text default"><span class="text">request.build_absolute_uri(reverse('media', args=['/path/to/media']))</span></code>.</p>
<p>In <code class="codecolorer text default"><span class="text">settings.py</span></code>, add <code class="codecolorer text default"><span class="text">django.core.context_processors.request</span></code> to <code class="codecolorer text default"><span class="text">TEMPLATE_CONTEXT_PROCESSORS</span></code>.</p>
<p>This context processor allows you to access the <code class="codecolorer text default"><span class="text">request.build_absolute_uri()</span></code> function from templates:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: black;">&#123;</span><span style="color: black;">&#123;</span> request.<span style="color: black;">build_absolute_uri</span> <span style="color: black;">&#125;</span><span style="color: black;">&#125;</span></div></td></tr></tbody></table></div>
<p>However, you can&#8217;t pass parameters to this function, so you won&#8217;t be able to reverse media path to URL. That&#8217;s why we need a filter.</p>
<h2>Absolute url for a media</h2>
<p>The following filter will allow you to build an absolute URL to a media. In <code class="codecolorer text default"><span class="text">templatetags/mytemplatetags.py</span></code>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #483d8b;">'''<br />
Usage: {{ media|absolute_media_url:request }}<br />
'''</span><br />
<span style="color: #66cc66;">@</span>register.<span style="color: #008000;">filter</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> absolute_media_uri<span style="color: black;">&#40;</span>media<span style="color: #66cc66;">,</span> request<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> request.<span style="color: black;">build_absolute_uri</span><span style="color: black;">&#40;</span>reverse<span style="color: black;">&#40;</span><span style="color: #483d8b;">'media'</span><span style="color: #66cc66;">,</span> args<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>media<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Don&#8217;t forget to add a blank <code class="codecolorer text default"><span class="text">__init__.py</span></code> in <code class="codecolorer text default"><span class="text">templatetags/</span></code> or django won&#8217;t take your template tag into account.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/django-absolute-media-uris-from-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MantisBT et PHPMailer: problème avec l&#8217;envoi de mails</title>
		<link>http://lois.di-qual.net/blog/mantisbt-et-phpmailer-probleme-avec-lenvoi-de-mails/</link>
		<comments>http://lois.di-qual.net/blog/mantisbt-et-phpmailer-probleme-avec-lenvoi-de-mails/#comments</comments>
		<pubDate>Thu, 07 Jun 2012 17:34:17 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=65</guid>
		<description><![CDATA[Je me suis retrouvé récemment face à un problème assez facheux. MantisBT, un logiciel de tracking de bugs, n&#8217;envoyait plus de mail. Que ce soit lors d&#8217;un ajout de bug ou lors de la procédure de réinitialisation du mot de passe: rien, nada. Pourtant, MantisBT affirmait que le mail était envoyé. Un petit coup d&#8217;oeil [...]]]></description>
				<content:encoded><![CDATA[<p>Je me suis retrouvé récemment face à un problème assez facheux. <a href="http://www.mantisbt.org/">MantisBT</a>, un logiciel de tracking de bugs, n&#8217;envoyait plus de mail. Que ce soit lors d&#8217;un ajout de bug ou lors de la procédure de réinitialisation du mot de passe: rien, nada. Pourtant, MantisBT affirmait que le mail était envoyé.</p>
<p>Un petit coup d&#8217;oeil dans le fichier <code class="codecolorer text default"><span class="text">core/email_api.php</span></code> permet de voir que Mantis prend en compte les erreurs de <a href="http://phpmailer.worxware.com/index.php">PHPMailer</a> via les try/catch suivants:</p>
<div class="codecolorer-container php twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">// Insertion du mail dans la BDD</span><br />
try<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Envoi du mail</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Suppression du mail dans la BDD</span><br />
<span style="color: #009900;">&#125;</span><br />
catch <span style="color: #009900;">&#40;</span> phpmailerException <span style="color: #000088;">$e</span> <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;">// Rien</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Mais vous l&#8217;avez bien compris, MantisBT ne génère pas de message d&#8217;erreur (ni de log) si l&#8217;envoi du mail n&#8217;est pas correctement effectué. Par contre, il laisse le mail dans la BDD pour qu&#8217;il puisse être envoyé dès que le système marche à nouveau (voir <code class="codecolorer text default"><span class="text">core/email_queue_api.php</span></code>).</p>
<p>Pour débugger mon affaire, j&#8217;ai donc du insérer une petite ligne de code juste après le <code class="codecolorer text default"><span class="text">catch</span></code>:</p>
<div class="codecolorer-container php twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">echo</span> <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Et là, bingo: <code class="codecolorer text default"><span class="text">Could not instantiate mail function</span></code>.</p>
<p>Pourtant, j&#8217;avais bien vérifié que la fonction <code class="codecolorer text default"><span class="text">mail</span></code> fonctionnait correctement avec un petit <code class="codecolorer text default"><span class="text">if (mail(&quot;toto@test.com&quot;, &quot;sujet&quot;, &quot;message&quot;)) echo &quot;ok&quot;;</span></code>. Chose que je ne savais pas: si PHP est en <code class="codecolorer text default"><span class="text">safe_mode</span></code>, la fonction <code class="codecolorer text default"><span class="text">mail()</span></code> est amputée d&#8217;un argument:</p>
<blockquote><p>
<a href="http://php.net/features.safe-mode.functions.php">Fonctions désactivées par le Safe Mode</a>:<br />
<code class="codecolorer text default"><span class="text">mail()</span></code>: Si le Safe Mode est actif, le 5ème paramètre est désactivé (note : uniquement affecté depuis PHP 4.2.3)
</p></blockquote>
<p>Super.</p>
<p>Il faut donc vérifier que <code class="codecolorer text default"><span class="text">safe_mode = On</span></code> dans <code class="codecolorer text default"><span class="text">php.ini</span></code> pour que tout ça marche. Autre solution si votre hébergeur ne vous permet pas d&#8217;accéder au fichier de configuration, ajouter <code class="codecolorer text default"><span class="text">php_flag safe_mode off</span></code> dans votre <code class="codecolorer text default"><span class="text">.htaccess</span></code>.</p>
<p>Cela montre encore une fois que <a href="http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/">PHP est totalement imprévisible<a>. Il y a tellement d&#8217;endroits où l&#8217;on peut écraser les paramètres d&#8217;une configuration que l&#8217;on ne peut savoir si telle ou telle fonction va marcher. Mais bon, problème résolu !</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/mantisbt-et-phpmailer-probleme-avec-lenvoi-de-mails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bloquer ou monitorer AJAX à partir d&#8217;un script GreaseMonkey (ou Userscript)</title>
		<link>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/</link>
		<comments>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/#comments</comments>
		<pubDate>Fri, 01 Jun 2012 00:13:05 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[userscript]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=60</guid>
		<description><![CDATA[Facebook a récemment ajouté une fonctionnalité qui m&#8217;est très désagréable: la notification de la lecture des messages à l&#8217;expéditeur. Impossible dès lors d&#8217;ignorer un message instantané sans que la personne le sache, or c&#8217;est un droit immuable qui devrait être inscrit au burin dans la roche des droits de l&#8217;homme. Modification de XMLHttpRequest Pour empêcher [...]]]></description>
				<content:encoded><![CDATA[<p>Facebook a récemment ajouté une fonctionnalité qui m&#8217;est très désagréable: la notification de la lecture des messages à l&#8217;expéditeur. Impossible dès lors d&#8217;ignorer un message instantané sans que la personne le sache, or c&#8217;est un droit immuable qui devrait être inscrit au burin dans la roche des droits de l&#8217;homme.</p>
<h2>Modification de XMLHttpRequest</h2>
<p>Pour empêcher ces notifications, il faut empêcher l&#8217;envoi de données vers <code class="codecolorer text default"><span class="text">http(s)://www.facebook.com/ajax/mercury/change_read_status.php</span></code> à partir d&#8217;un script Greasemonkey. Le principe du blocage consiste en la modification de l&#8217;objet <code class="codecolorer text default"><span class="text">XMLHttpRequest</span></code> pour que la méthode <code class="codecolorer text default"><span class="text">open</span></code> n&#8217;autorise pas l&#8217;ouverture du socket vers la page en question:</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// On sauvegarde la méthode open originale</span><br />
window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">trueOpen</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// On modifie la méthode open avec la notre</span><br />
window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color: #006600; font-style: italic;">// Du code pour bloquer ou logger ce qui se passe</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// On peut notamment regarder ce qu'il y a dans arguments</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// pour bloquer: return;</span><br />
<br />
&nbsp; <span style="color: #006600; font-style: italic;">// Si on ne souhaite pas bloquer l'ouverture du socket,</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// on fait appel à la méthode originale</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">trueOpen</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Vous pouvez ainsi intercepter chaque appel aux méthodes de <code class="codecolorer text default"><span class="text">XMLHttpRequest</span></code>, et les bloquer ou les rerouter à votre guise. Pour la liste complète des méthodes en question, je vous invite à consulter <a href="http://www.w3.org/TR/XMLHttpRequest">sa documentation W3C</a>.</p>
<p>Dans le cas d&#8217;un blocage (pas d&#8217;appel à <code class="codecolorer text default"><span class="text">trueOpen</span></code>), voici ce qu&#8217;il va se passer du côté de la page monitorée:</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// Instanciation normale de notre objet</span><br />
<span style="color: #003366; font-weight: bold;">var</span> xhr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// Rien ne se passe, l'instance de xhr n'est pas modifiée et le socket n'est pas ouvert</span><br />
xhr.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;get&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;page_bloquee.html?param=1&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// Le send échoue car le socket n'est pas ouvert</span><br />
xhr.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>L&#8217;appel à <code class="codecolorer text default"><span class="text">xhr.send</span></code> ne provoque aucune erreur, du moins sous Chrome.</p>
<h2>Le script Greasemonkey</h2>
<p>Le script abordé précédemment suppose que vous soyez dans le scope de la page dont vous souhaitez monitorer les appels AJAX. Ce n&#8217;est pas le cas pour les scripts GreaseMonkey. Comme expliqué très judicieusement <a href="http://stackoverflow.com/a/10828021/646960">dans ce post sur StackOverflow</a>, Firefox et Chrome exécutent ces scripts dans une sandbox qui ne permet pas d&#8217;accéder à l&#8217;environnement javascript de la page concernée.</p>
<p>Néanmoins, il existe une méthode assez simple pour sortir de cette sandbox: injecter un élément <code class="codecolorer text default"><span class="text">script</span></code> dans la page en question qui exécutera le code de notre choix.</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// Notre code précédent</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// On crée un élément &lt;script&gt;&lt;/script&gt; et on l'injecte dans la page à contrôler</span><br />
<span style="color: #006600; font-style: italic;">// Dans cet élément, on copie la fonction main afin qu'elle soit exécutée</span><br />
<span style="color: #003366; font-weight: bold;">var</span> script <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
script.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;(&quot;</span> <span style="color: #339933;">+</span> main.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)();&quot;</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<h2>Le code final</h2>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">trueOpen</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// this.trueOpen.apply(this, arguments);</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> script <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
script.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;(&quot;</span> <span style="color: #339933;">+</span> main.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)();&quot;</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>En ce qui concerne le blocage de la notification facebook, voici <a href="https://github.com/ldiqual/facebook-read-status-disabler">facebook-read-status-disabler</a>. Il est également à noter que ce monitoring ne fonctionnera pas avec Internet Explorer car celui-ci utilise un autre objet pour les requêtes AJAX. Un script plus complet est disponible sur github: <a href="https://github.com/creotiv/AJAX-calls-intercepter">AJAX Calls Intercepter</a>, avec notamment la prise en compte d&#8217;Internet Explorer.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un PDF à l&#8217;image de votre CV en ligne avec wkpdf</title>
		<link>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/</link>
		<comments>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/#comments</comments>
		<pubDate>Thu, 31 May 2012 22:32:46 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[astuce]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[CV]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wkpdf]]></category>

		<guid isPermaLink="false">http://127.0.0.1/ldiqual/blog/?p=14</guid>
		<description><![CDATA[Tout comme il est intéressant pour un employeur d&#8217;avoir accès au CV en ligne d&#8217;une potentielle nouvelle recrue, il est également pratique de pouvoir imprimer ce CV dans un format qui convient. La génération automatique d&#8217;un PDF associé au contenu de votre site présente plusieurs avantages: Le PDF est constamment à jour du contenu de [...]]]></description>
				<content:encoded><![CDATA[<p>Tout comme il est intéressant pour un employeur d&#8217;avoir accès au CV en ligne d&#8217;une potentielle nouvelle recrue, il est également pratique de pouvoir imprimer ce CV dans un format qui convient.</p>
<p>La génération automatique d&#8217;un PDF associé au contenu de votre site présente plusieurs avantages:</p>
<ul>
<li>Le PDF est constamment à jour du contenu de votre site</li>
<li>Le PDF adopte le design de votre site</li>
<li>C&#8217;est totalement la classe</li>
</ul>
<p>Voici donc un petit aperçu hautement égocentré de ce que vous pourrez faire:</p>
<p><a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_online.png"><img class="alignnone size-medium wp-image-55" title="CV - version en ligne" src="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_online-280x300.png" alt="" width="280" height="300" /></a>       <a href="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_pdf.png"><img class="alignnone size-medium wp-image-56" title="CV - Version PDF" src="http://lois.di-qual.net/blog/wp-content/uploads/2012/05/cv_pdf-300x290.png" alt="" width="300" height="290" /></a></p>
<p>Comme vous l&#8217;aurez remarqué, divers détails graphiques comme l&#8217;arrière-plan gris ou le ruban bleu ont été effacés afin de proposer une version épurée prête à l&#8217;impression.</p>
<p>Pour parvenir à ce résultat, nous allons utiliser un petit logiciel nommé wkpdf associé à une feuille de style spéciale.</p>
<h2>La feuille de style</h2>
<p>Depuis la <a href="http://www.w3.org/TR/html4/present/styles.html#h-14.2.4">version 4 de la norme HTML</a>, il est possible d&#8217;inclure une feuille de style en précisant le type de périphérique auquel elle est adressée. On peut ainsi inclure une une feuille de style spécifique aux télévisions:</p>
<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tv&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;css/tv.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></td></tr></tbody></table></div>
<p>Il est même possible depuis la version 2 de la norme CSS de déclarer des règles spécifiques à un media directement dans votre feuille de style principale:</p>
<div class="codecolorer-container css twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Avec @import */</span><br />
<span style="color: #a1a100;">@import url(&quot;tv.css&quot;) tv;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Ou avec @media */</span><br />
<span style="color: #a1a100;">@media print {</span><br />
&nbsp; <span style="color: #808080; font-style: italic;">/* Règles spécifiques */</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></tbody></table></div>
<p>Voici la <a href="http://www.w3.org/TR/CSS2/media.html">liste des valeurs</a> de l&#8217;attribut media:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">all &nbsp; &nbsp; &nbsp; &nbsp; Suitable for all devices.<br />
braille &nbsp; &nbsp; Intended for braille tactile feedback devices.<br />
embossed &nbsp; &nbsp;Intended for paged braille printers.<br />
handheld &nbsp; &nbsp;Intended for handheld devices (typically small screen, limited bandwidth).<br />
print &nbsp; &nbsp; &nbsp; Intended for paged material and for documents viewed on screen in print preview mode.<br />
projection &nbsp;Intended for projected presentations, for example projectors.<br />
screen &nbsp; &nbsp; &nbsp;Intended primarily for color computer screens.<br />
speech &nbsp; &nbsp; &nbsp;Intended for speech synthesizers.<br />
tty &nbsp; &nbsp; &nbsp; &nbsp; Intended for media using a fixed-pitch character grid (such as teletypes, terminals, or portable devices with limited display capabilities). <br />
tv &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Intended for television-type devices (low resolution, color, limited-scrollability screens, sound available).</div></td></tr></tbody></table></div>

</pre>
<p>Il est à noter que si vous ne précisez pas de media, la valeur de l&#8217;attribut est &#8220;all&#8221; (pour tous les périphériques).<br />
Nous voyons ici que la valeur &#8220;print&#8221; permet de personnaliser un document destiné à être imprimé, c&#8217;est donc celui-ci que nous allons utiliser:</p>
<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;print&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;css/print.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></td></tr></tbody></table></div>
<p>Dans cette feuille de style, supprimons tout ce qui n&#8217;est plus nécessaire, par exemple:</p>
<div class="codecolorer-container css twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* Suppression d'un élément inutile */</span><br />
<span style="color: #6666ff;">.classe-de-l-element</span> <span style="color: #00AA00;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span><span style="color: #993333;">none</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;">/* Suppression de l'arrière plan */</span><br />
body <span style="color: #00AA00;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span></div></td></tr></tbody></table></div>
<p>Vous pouvez tester ces nouvelles règles en modifiant temporairement l&#8217;attribut media de &#8220;print&#8221; à &#8220;all&#8221;.</p>
<h2>Génération du PDF</h2>
<p>Nous allons utiliser <a href="http://plessl.github.com/wkpdf/">wkpdf</a> pour générer notre fichier. Malheureusement ce dernier n&#8217;est disponible que sur Mac, mais il existe une alternative multiplateforme, <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a>, qui semble fonctionner sur le même principe.</p>
<p>Ces logiciel a un énorme avantage: au lieu de posséder son propre moteur d&#8217;interprétation de la structure HTML, il utilise le fameux Webkit (le moteur de rendu de Chrome et Safari, notamment). Le rendu sera donc fidèle à ce que vous pourrez voir dans un navigateur web conventionnel.</p>
<p>Il vous suffit donc d&#8217;exécuter wkpdf en ligne de commande:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ wkpdf --source http://monsite.com/ --output cv.pdf --margins 0 --stylesheet-media print --print-background</div></td></tr></tbody></table></div>

</pre>
<p>De plus, si votre site met en place des éléments graphiques à l&#8217;aide de Javascript, ajoutez les arguments suivants:</p>
<pre>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--enable-javascript --save-delay [temps_avant_capture_en_secondes]</div></td></tr></tbody></table></div>

</pre>
<p>Vous devriez ainsi obtenir un beau PDF prêt à l&#8217;emploi. Il vous faudra sûrement adapter certaines règles CSS pour que tout tienne sur une page, etc&#8230;</p>
<h2>Bonus: impression directe à partir du site</h2>
<p>La feuille de style &#8220;media=print&#8221; sert également à votre navigateur lors de l&#8217;impression d&#8217;une page. Néanmoins, certaines limitations sont mises en place par la plupart des navigateurs:</p>
<ul>
<li>Les arrières-plans ne sont pas pris en compte. <code class="codecolorer text default"><span class="text">background-color</span></code> et <code class="codecolorer text default"><span class="text">background-image</span></code> ne fonctionneront donc pas.</li>
<li>Le Javascript n&#8217;est pas pris en charge, aucune modification ne pourra être faite dynamiquement avant l&#8217;impression.</li>
</ul>
<blockquote><p>
Note concernant le comportement des navigateurs lors de l&#8217;impression:</p>
<ul>
<li>Aucune référence ou documentation n&#8217;est disponible à ce sujet, du moins pour le moment</li>
<li>Dans certaines versions de Firefox, et sous certains systèmes d&#8217;exploitation, il est possible d&#8217;activer la prise en charge des arrière-plans (couleur et image) ainsi que le Javascript. Là encore, aucune documentation.</li>
<li>Internet Explorer propose un event <code class="codecolorer text default"><span class="text">onbeforeprint</span></code> permettant de modifier le DOM lorsque le navigateur s&#8217;apprête à imprimer. Plus d&#8217;informations <a href="http://msdn.microsoft.com/en-us/library/ie/ms536906(v=vs.85).aspx">par ici</a>.</li>
</ul>
<p>Si vous avez des renseignements supplémentaires concernant les différents comportements adoptés par les navigateurs, n&#8217;hésitez pas à m&#8217;en informer !
</p></blockquote>
<p>Toute l&#8217;astuce consistera donc à remplacer les arrières plans par des images (qui elles seront affichées), ou de tenter de mettre en place une sorte de &#8220;graceful degradation&#8221; afin de simuler certains éléments graphiques. Par exemple, les barres de compétences mises en place sur mon CV ne sont pas pleines lors de leur impression, j&#8217;ai donc dû ajouter un <code class="codecolorer text default"><span class="text">border-color</span></code> pour symboliser les limites de ces dernières.</p>
<h2>Et après ?</h2>
<p>On peut maintenant aisément imaginer un système qui génèrerait automatiquement votre PDF à chaque modification du site web. Si vous utilisez un système de versioning, aucun soucis. Je vous invite à chercher du côté de <code class="codecolorer text default"><span class="text">pre-commit</span></code> si vous gérez tout ça avec svn ou git. Il vous suffira de modifier ces hooks en insérant la commande de génération, et d&#8217;ajouter au commit le fichier PDF ainsi généré.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/un-pdf-a-limage-de-votre-cv-en-ligne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
