<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Haineault.com / Blog</title><link>http://haineault.com/blog/</link><description>Haineault.com's latest blog entries.</description><language>en</language><lastBuildDate>Sat, 04 Jul 2009 13:27:42 -0000</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Haineaultcom/Blog" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>10-Jun-2009 23:30 - Django-syncr: Synchronizing Subversion commit logs</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/B3yJEgPc7tA/</link><description>&lt;p&gt;Last night I've created a subversion app for &lt;a href="http://code.google.com/p/django-syncr/"&gt;Django-syncr&lt;/a&gt;. It basically allow to mirror SVN logs in a Django database.
&lt;/p&gt;
&lt;p&gt;Why would I want to do that ? 
&lt;/p&gt;
&lt;p&gt;Because I need to show last commits from multiple SVN repositories on a web page. Executing a svn log command on each servers upon each request was not an option, so I needed to cache the log entries in a database with a cron job.
&lt;/p&gt;
&lt;p&gt;That's where Django-syncr shines. It wasn't long before I had a working prototype with which I could browse the SVN commit logs with the Django's rich admin interface.
&lt;/p&gt;
&lt;p&gt;Here's what it looks like;
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/media/blog/syncr-svn.png" alt="" border="" /&gt;&lt;/p&gt;

&lt;p&gt;I've even took the time some sugar coat. I've created a Django management command to sync. So instead of having to creating your own script which import and call this syncr app, you can just do this;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;python manage.py subversion sync
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;Repository to sync and credentials can either be stored in &lt;em&gt;settings.py&lt;/em&gt; or in a provided database table.
&lt;/p&gt;
&lt;p&gt;Full (mostly) documentation is available &lt;a href="http://code.google.com/p/django-syncr/wiki/SyncrSubversion"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;To checkout the source; 
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;svn co http://django-syncr.googlecode.com/svn/branches/haineault/ django-syncr
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;It's licensed under the same license (MIT) than Django-syncr.
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: Consider this Alpha code. I've wrote this code last night, so don't expect it to be perfect.
&lt;/p&gt;
&lt;p&gt;
    0 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gQ9z0sm8pXRc9MC0qiVjBfna-7c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gQ9z0sm8pXRc9MC0qiVjBfna-7c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gQ9z0sm8pXRc9MC0qiVjBfna-7c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gQ9z0sm8pXRc9MC0qiVjBfna-7c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/B3yJEgPc7tA" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/107/</guid><feedburner:origLink>http://www.haineault.com/blog/107/</feedburner:origLink></item><item><title>02-Jun-2009 19:55 - Gnome: tip of the day</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/DXPjvSOoeUg/</link><description>&lt;p&gt;If you right click on the maximize button of a window, it will maximize the window only horizontally. Likewise if you middle click, the window will get maximized only vertically.
&lt;/p&gt;
&lt;p&gt;Bonus: press and hold the &lt;em&gt;Alt&lt;/em&gt; key and Click+Drag a window to move it.
&lt;/p&gt;
&lt;p&gt;I use Compiz, I don't know if this might work without it..
&lt;/p&gt;
&lt;p&gt;
    1 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3SiYRnim9ighMohe6OmqokqqHMc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3SiYRnim9ighMohe6OmqokqqHMc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3SiYRnim9ighMohe6OmqokqqHMc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3SiYRnim9ighMohe6OmqokqqHMc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/DXPjvSOoeUg" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/106/</guid><feedburner:origLink>http://www.haineault.com/blog/106/</feedburner:origLink></item><item><title>28-May-2009 23:30 - jQuery: Inline caching for selectors</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/3zdhYJTFfCE/</link><description>&lt;p&gt;Recently I've watched &lt;a href="http://www.youtube.com/watch?v=lZnaaUoHPhs"&gt;a presentation by Kevin Millikin&lt;/a&gt; about Google Chrome's JavaScript engine.
&lt;/p&gt;
&lt;p&gt;I was really impressed by the clever ways they found to improve speed. One of the technique used was  polymorphic inline caching (the name is more complicated than the technique itself..), a technique I knew for a while, but never found much real life situations which justified its utilization.. until today ago.
&lt;/p&gt;
&lt;p&gt;When taking off the polymorphic aspect, the implementation becomes really simple and is perfect for a primitive caching mechanism. I used something similar for the &lt;a href="http://haineault.com/blog/82/"&gt;$.tpl&lt;/a&gt; plugin.
&lt;/p&gt;
&lt;p&gt;So here's how I implemented it;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="c"&gt;// [key, value, scope]&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ic&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;jquery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_ic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
&lt;span class="p"&gt;}});&lt;/span&gt;

&lt;span class="nx"&gt;_$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sel&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sel&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sel&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;The code can be used as follow;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;// Store and get publicly&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;// Store and get privately&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;_$&lt;/em&gt; function allow caching at selector level, which means you can use it normally like the &lt;em&gt;$&lt;/em&gt; except that the selector engine will process every selection only once.
&lt;/p&gt;
&lt;p&gt;Obviously this is not the kind of behavior we want when HTML nodes are being inserted or deleted dynamically, but in a handful of other situations this might be useful.
&lt;/p&gt;
&lt;p&gt;Here's a simple function to profile it:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;testIC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;selector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Inline caching (global)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Inline caching (global)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Inline caching (scoped)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Inline caching (scoped)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;No caching&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;// get global&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;No caching&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
     Inline caching (global) (2.236ms, 120 calls)
 &lt;/li&gt;
&lt;li&gt;
     Inline caching (scoped) (1.753ms, 120 calls)
 &lt;/li&gt;
&lt;li&gt;
     No caching (95.862ms, 1900 calls)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, basically this technique is almost equate to store the jQuery result object in a variable. However it offers the advantage that you can chose the scope of the variable, make it public or private, without polluting the global object. 
&lt;/p&gt;
&lt;p&gt;And well, I also think that it's syntactically neat.
&lt;/p&gt;
&lt;p&gt;cheers
&lt;/p&gt;
&lt;p&gt;
    2 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/E8UY8lpd_i5HffjDeW0V-AJ2Y34/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E8UY8lpd_i5HffjDeW0V-AJ2Y34/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/E8UY8lpd_i5HffjDeW0V-AJ2Y34/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/E8UY8lpd_i5HffjDeW0V-AJ2Y34/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/3zdhYJTFfCE" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/105/</guid><feedburner:origLink>http://www.haineault.com/blog/105/</feedburner:origLink></item><item><title>25-May-2009 12:40 - Django pluggable: jQuery integration</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/uvz0JdculXw/</link><description>&lt;p&gt;I've created a &lt;a href="http://code.google.com/p/django-jq/"&gt;django app&lt;/a&gt; which integrate jQuery. 
&lt;/p&gt;
&lt;p&gt;It might seems trivial, however bear with me I can assure you there is some goodies bundled in this app.
&lt;/p&gt;
&lt;h2&gt;Serving&lt;/h2&gt;
&lt;p&gt;A template tag was created to easily load any version of jQuery, locally or remotely:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;{% jquery_script %}
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/jq-media/jquery/1.3/jquery.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

{% jquery_script &amp;quot;1.2.6&amp;quot; %}
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/jq-media/jquery/1.2.6/jquery.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

{% jquery_script &amp;quot;1.3&amp;quot; 1 %}
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;h2&gt;URL dispatcher&lt;/h2&gt;
&lt;p&gt;This is my favorite part :)
&lt;/p&gt;
&lt;p&gt;I've included a small JavaScript script which allow to work with Django's named URLs on the client side. It resolve a lot of annoying issues when working with medium to large Django projects which involve lots of JavaScript.
&lt;/p&gt;
&lt;p&gt;As is there is no mechanism to achieve that. It forces us to hardcode our URLs in JavaScript, which of courses leads to unpredictable problems when URLs gets moved around. On the server side, if you used named URLs properly, you can change your URLs like you want without breaking your app, however they will not be updated on the client side.
&lt;/p&gt;
&lt;p&gt;It also becomes a problem when your root URL isn't necessarily &amp;quot;/&amp;quot; in production &lt;em&gt;and&lt;/em&gt; in development.
&lt;/p&gt;
&lt;p&gt;Consider the following URLs:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;myProject.main.views&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^/view/contact/(\d+)/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;view_contact&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;view-contact&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^/calendar/(?P&amp;lt;year&amp;gt;\d{4})/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;view_calendar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;view-calendar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;Now let's forget the parsing bug in my code highlight that puts a &amp;lt;/year&amp;gt; at the end and imagine that you want to access the &lt;em&gt;view-contact&lt;/em&gt; view with an Ajax call. 
&lt;/p&gt;
&lt;p&gt;The conventional way to achieve this would looks something like this;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#contact-div&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/view/contact/&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;If the URL gets changed to let's say *'^/contact/view/(d+)/$'*. This JavaScript code will break.
&lt;/p&gt;
&lt;p&gt;If your root URL is &lt;em&gt;/&lt;/em&gt; in development and &lt;em&gt;/something/&lt;/em&gt; in prod, this JavaScript will not work in production.
&lt;/p&gt;
&lt;p&gt;My script resolve this issue gracefully while being more coherent with Django:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#contact-div&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;view-contact&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;The script also support named arguments:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#calendar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;view-calendar&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2009&lt;/span&gt;&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;To make this work you only have one template tag to add to your &lt;em&gt;base.html&lt;/em&gt;:
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;{% jquery_urls %}
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;h2&gt;Developpment roadmap&lt;/h2&gt;
&lt;p&gt;As now there is still jQuery UI to integrate, beside that the core features I wanted are almost all there.
&lt;/p&gt;
&lt;p&gt;I'm juggling with the idea of creating custom form widgets for jQuery UI widgets, but I'm still not sure it would be a great added value nor that it would be optimal.
&lt;/p&gt;
&lt;p&gt;I'm not sure if I will our should bundle a default jQuery UI theme..
&lt;/p&gt;
&lt;p&gt;Any inputs/feedbacks are welcome.
&lt;/p&gt;
&lt;p&gt;Special thanks to &lt;a href="http://gnuvince.wordpress.com/"&gt;gnuvince&lt;/a&gt; for the help with the URL dispatcher.
&lt;/p&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://code.google.com/p/django-jq/wiki/ProjectDocumentation"&gt;Project documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://code.google.com/p/django-jq/source/checkout"&gt;Project source&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://code.google.com/p/django-jq/"&gt;Project page&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    6 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7vkyNC6TZKhbGQZvrKlxJ4agXuU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7vkyNC6TZKhbGQZvrKlxJ4agXuU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7vkyNC6TZKhbGQZvrKlxJ4agXuU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7vkyNC6TZKhbGQZvrKlxJ4agXuU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/uvz0JdculXw" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/104/</guid><feedburner:origLink>http://www.haineault.com/blog/104/</feedburner:origLink></item><item><title>22-May-2009 19:41 - The Torture Show</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/vvKd_FsuHbc/</link><description>&lt;p&gt;That's it, I'm officially and utterly sick of the US debate over the prosecution for torture.
&lt;/p&gt;
&lt;p&gt;That waterboarding is supposedly not torture seems to be the unique argument of the right against prosecution. 
&lt;/p&gt;
&lt;p&gt;I have a big problem with that. It's not because they re-branded torture with &lt;em&gt;Enhanced Interrogation Techniques&lt;/em&gt; that it suddenly becomes something else.
&lt;/p&gt;
&lt;p&gt;Do they even know what torture is ?
&lt;/p&gt;
&lt;p&gt;A reminder, just in case:
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;...any act by which severe pain or suffering, whether physical or mental, is intentionally inflicted on a person for such purposes as obtaining from him, or a third person, information or a confession, punishing him for an act he or a third person has committed or is suspected of having committed, or intimidating or coercing him or a third person, or for any reason based on discrimination of any kind, when such pain or suffering is inflicted by or at the instigation of or with the consent or acquiescence of a public official or other person acting in an official capacity. It does not include pain or suffering arising only from, inherent in, or incidental to, lawful sanctions.
&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://en.wikipedia.org/wiki/Torture#United_Nations_Convention_Against_Torture"&gt;UN Convention Against Torture&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Arguing that waterboarding does not constitute torture according to this definition is laughable. If you still feel like arguing that it's not, &lt;a href="http://www.theflatearthsociety.org/"&gt;I have the perfect forum for people like you&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;But what about other interrogation techniques ?
&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;According to ABC News, former and current CIA officials have come forward to reveal details of interrogation techniques authorized in the CIA. These include:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Attention Grab: The interrogator forcefully grabs the shirt front of the prisoner and shakes them
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attention Slap: An open-handed slap to the face aimed at causing pain and triggering fear
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Belly Slap: A hard open-handed slap to the abdomen. The aim is to cause pain, but not internal injury. Doctors consulted advised against using a punch, which could cause lasting internal damage
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long Time Standing: This technique is described as among the most effective. Prisoners are forced to stand, handcuffed and with their feet shackled to an eye bolt in the floor, for more than 40 hours
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Cold Cell: The prisoner is left to stand naked in a cell kept near 50 degrees Fahrenheit (10 degrees Celsius)
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Waterboarding: The prisoner is bound to an inclined board, feet raised and head slightly below the feet. Material is wrapped over the prisoner's face and water is poured over them. Unavoidably, the gag reflex kicks in and a terrifying fear of drowning leads to almost instant pleas to bring the treatment to a halt
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Enhanced_interrogation_techniques#The_War_on_Terror"&gt;Wikipedia&lt;/a&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;&lt;p&gt;It's somehow like arguing that you can't prosecute a thief because he did not steal a car.. but a SUV. 
&lt;/p&gt;
&lt;p&gt;Next time I'll get a ticket for speeding I'll try argue that I wasn't speeding but, merely enhancing my velocity.
&lt;/p&gt;
&lt;p&gt;This whole debate over whether or not it constitute torture is just a big show to keep our attention away from the real issues.
&lt;/p&gt;
&lt;p&gt;And the Obama argument ? Bullshit.
&lt;/p&gt;
&lt;p&gt;We can't change the past, we should move on ? Bullshit.
&lt;/p&gt;
&lt;p&gt;We often see in the news that an old man will be tried or deported because he committed war crimes when he was a Nazi officer or prison guard &lt;em&gt;sixty years ago&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;If we can't change the past, why aren't we moving on ?
&lt;/p&gt;
&lt;p&gt;I have only one thing to reply to president Obama;
&lt;/p&gt;
&lt;p&gt;Sure we can't change the past, but your present actions and how you manage this situation is shaping &lt;em&gt;our&lt;/em&gt; future. The next president might see your actions (or inactions) as an open door to escalate this non-sense without fearing eventual repercussions.
&lt;/p&gt;
&lt;p&gt;You can't change the past, but you can make sure it will not happen again. 
&lt;/p&gt;
&lt;p&gt;Just stop the show already.
&lt;/p&gt;
&lt;p&gt;
    0 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FozzIDOXcpC3ZqGL4LfcITzCjMY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FozzIDOXcpC3ZqGL4LfcITzCjMY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FozzIDOXcpC3ZqGL4LfcITzCjMY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FozzIDOXcpC3ZqGL4LfcITzCjMY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/vvKd_FsuHbc" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/103/</guid><feedburner:origLink>http://www.haineault.com/blog/103/</feedburner:origLink></item><item><title>21-May-2009 20:38 - Comparing dates with JavaScript</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/A9iTZWoqrK4/</link><description>&lt;p&gt;I just discovered a neat JavaScript feature that I felt like sharing.
&lt;/p&gt;
&lt;p&gt;While trying to implement a function that would capture key strokes for certain patterns, like some kind of trigger, I had to compare two dates to get the number of seconds elapsed since the last keystroke.
&lt;/p&gt;
&lt;p&gt;I first thought to just create a date object, get the seconds and subtract them. But then I would have a problem with long interruptions, which could lead to unpredictable bugs. I could add minutes, but for hour long interruptions, the bug would remain and so on.. Which eventually leads to nearly full date comparison .. yurk.
&lt;/p&gt;
&lt;p&gt;Then I started missing Python with its awesome ability to compare almost any object types. At this point it hit me, could it be ? .. no ..
&lt;/p&gt;
&lt;p&gt;I opened Firebug;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;Thu&lt;/span&gt; &lt;span class="nx"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="mi"&gt;2009&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="nx"&gt;GMT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0400&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EDT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;Thu&lt;/span&gt; &lt;span class="nx"&gt;May&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="mi"&gt;2009&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="nx"&gt;GMT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0400&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;EDT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;60596&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="mi"&gt;60596&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;I almost cried of joy.
&lt;/p&gt;
&lt;p&gt;After nearly three years of intensive JavaScript programming it still amaze me. Why I didn't knew about this and why I did not saw this being used anywhere else until now is beyond my understanding. 
&lt;/p&gt;
&lt;p&gt;I'm still not quite sure how it process these though ..
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="mf"&gt;1.544930730887957&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="mf"&gt;1.000000048751666&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;Modulo (%) also works but seems to only do a subtraction.
&lt;/p&gt;
&lt;p&gt;
    5 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/k5Rjk52BnY4LrQ-akFJwsd7e9eM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k5Rjk52BnY4LrQ-akFJwsd7e9eM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/k5Rjk52BnY4LrQ-akFJwsd7e9eM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k5Rjk52BnY4LrQ-akFJwsd7e9eM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/A9iTZWoqrK4" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/102/</guid><feedburner:origLink>http://www.haineault.com/blog/102/</feedburner:origLink></item><item><title>14-May-2009 00:29 - Django: Avoiding redundancy with inheritance</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/BPqXOb8AOWM/</link><description>&lt;p&gt;I'm writing a lot of models these time and most of them requires some generic informations, some kind of meta data like who create the object and when, who was the last to modify it and when.
&lt;/p&gt;
&lt;p&gt;I used to add manually those fields to my models, but even when they represented the same data I used different names and it started to bug me. For example, if the model was for storing messages I would probably use &lt;em&gt;sent_by&lt;/em&gt; and when I'm dealing with something else, like a calendar event for example, I would most likely use &lt;em&gt;created_by&lt;/em&gt;. It quickly becomes boring trying to remember how I named those field for each models, especially when semantically they are equivalents.
&lt;/p&gt;
&lt;p&gt;Then I recalled that Django's models support inheritance, which is awesome since it would allow me to reuse those fields and thus normalizing my field names. How pretty.
&lt;/p&gt;
&lt;p&gt;So now instead of;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_by&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;object_creator&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_time&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;modified_by&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;object_modifier&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;modified_time&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;I simply do;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject.myapp.models&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ExtendedModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExtendedModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;My model file is literally cut in half, me really happy.
&lt;/p&gt;
&lt;p&gt;The ExtendedModel looks like this;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtendedModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;created_by&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(class)s&lt;/span&gt;&lt;span class="s"&gt;_creator&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_time&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;modified_by&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%(class)s&lt;/span&gt;&lt;span class="s"&gt;_modifier&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;modified_time&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;&lt;em&gt;UPDATE&lt;/em&gt;: I added &lt;em&gt;abstract = True&lt;/em&gt; because someone pointed out I should use it. He didn't say why but after some digging I found that it makes sense. If I don't use an abstract base class Django will create two tables and keep the relationship using a table join, which is not really bad but not really optimal either. By specifying abstract Django knows it must create only one table and thus avoid table joins.
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;UPDATE 2&lt;/em&gt;: I also replaced &lt;em&gt;'object_modifier'&lt;/em&gt; and &lt;em&gt;'object_creator'&lt;/em&gt; with '%(class)s_modifier' and '%(class)s_creator'. This way related names are created dynamically so they don't clash when multiple models are used.
&lt;/p&gt;
&lt;p&gt;I knew for quite a while about model inheritance in Django so I can't really explain why I didn't do this before, sometime it's just too obvious I guess. However there's one little bit of magic to add in order to make it silky smooth and transparent with the Django admin. 
&lt;/p&gt;
&lt;p&gt;The main problem is that we want those field to auto-populate themselves. It's piece of cake for the DateTime field using auto_now*, but it's not that simple with the user fields. By design Django doesn't allow access to the request object within the model so it's not really possible to get the user who performed the request and bypassing this design decision somewhat defeat a good design decision.
&lt;/p&gt;
&lt;p&gt;We could overload the save method with a custom form, but it would only do the trick for custom views. The Django admin interface would still ask you to fill out manually those fields, which is not really optimal and really easy to cheat or at least, not really reliable.
&lt;/p&gt;
&lt;p&gt;To achieve what we want, we need to overload the save method in an admin object. Fortunately admin objects also support inheritance, so we can do it quite easily without repeating ourselves;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject.myapp.models&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="n"&gt;admin_site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AdminSite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtendedModelAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
        &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;created_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modified_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_m2m&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_formset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;formset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;created_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
            &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modified_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
            &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;formset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;formset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_m2m&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;instances&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;formset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ItemAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExtendedModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;list_display&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;label&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;modified_time&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;modified_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;created_time&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;created_by&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;ordering&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;-created_time&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;label&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;admin_site&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ItemAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;That's it !
&lt;/p&gt;
&lt;p&gt;
    1 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7RrT5C2_sQ9HgC2kp9UwKqKSq1Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7RrT5C2_sQ9HgC2kp9UwKqKSq1Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7RrT5C2_sQ9HgC2kp9UwKqKSq1Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7RrT5C2_sQ9HgC2kp9UwKqKSq1Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/BPqXOb8AOWM" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/101/</guid><feedburner:origLink>http://www.haineault.com/blog/101/</feedburner:origLink></item><item><title>29-Apr-2009 00:12 - Meet Sam</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/BN-4YxtsrR0/</link><description>&lt;p&gt;Today my girlfriend and I adopted a shelter dog, they told us it's a mixed husky. Mixed with what, we don't know (Doberman ?), but she (it's a female) is really beautiful. We had apprehensions since it's not really a small dog and we didn't really know what to expect, we feared she would be too exited or noisy. Fortunately it turns out it's an awesome dog, we love her.
&lt;/p&gt;
&lt;p&gt;She looks pretty intelligent, she understood basic words like sit and give paw. She's supposed to ask for the door, but she still have to prove it.. 
&lt;/p&gt;
&lt;p&gt;I was really surprised by how calm she is when she's inside. Outside that's another story she want to smell everything, but she's still manageable and docile.
&lt;/p&gt;
&lt;p&gt;Here's a picture;
&lt;/p&gt;
&lt;p&gt;&lt;div class="center"&gt;&lt;a href="http://www.flickr.com/photos/haineault/3484497879/" title="Sam is indiferent by Haineault, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3317/3484497879_83d80f8b9d.jpg" width="500" height="334" alt="Sam is indiferent" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;I also uploaded &lt;a href="http://www.flickr.com/photos/haineault/sets/72157617363176287/with/3485310932/"&gt;a set on flickr&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;I think we found a great dog, well I hope.
&lt;/p&gt;
&lt;p&gt;Note: If you think you know the exact race or mix please leave me a comment !
&lt;/p&gt;
&lt;p&gt;
    0 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2OTiKFaN0J5WThviM0huaBJW1ck/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2OTiKFaN0J5WThviM0huaBJW1ck/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2OTiKFaN0J5WThviM0huaBJW1ck/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2OTiKFaN0J5WThviM0huaBJW1ck/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/BN-4YxtsrR0" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/100/</guid><feedburner:origLink>http://www.haineault.com/blog/100/</feedburner:origLink></item><item><title>21-Apr-2009 18:18 - Google unveiled a game changer</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/usPe9vFmgT8/</link><description>&lt;blockquote&gt;&lt;p&gt;O3D is an open-source web API for creating rich, interactive 3D applications in the browser. This API is shared at an early stage as part of a conversation with the broader developer community about establishing an open web standard for 3D graphics.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/apis/o3d/"&gt;http://code.google.com/apis/o3d/&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;I knew Google was going to bring a breeze of fresh air on the web since they dropped the bomb with Chrome, but I didn't expect it to be that fast and impressive.
&lt;/p&gt;
&lt;p&gt;I did not have the time to play with it yet, but if it's half impressive than what it looks, this new toy will singlehandedly change the web &lt;em&gt;and&lt;/em&gt; the gaming industry as we know it, mark my words.
&lt;/p&gt;
&lt;p&gt;What does it mean for the gamers ? 
&lt;/p&gt;
&lt;p&gt;It means that soon you might not have to;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
     install a game on your machine
 &lt;/li&gt;
&lt;li&gt;
     backup your saved games
 &lt;/li&gt;
&lt;li&gt;
     reinstall the said game and restore your backups because you had to reinstall windows
 &lt;/li&gt;
&lt;li&gt;
     keep preciously your serial number
 &lt;/li&gt;
&lt;li&gt;
     connect to a server from within your game
 &lt;/li&gt;
&lt;li&gt;
     buy a boxed game
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And your might be able to;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
     just open a browser, login and start playing..
 &lt;/li&gt;
&lt;li&gt;
     from anywhere, any time, on any computer
 &lt;/li&gt;
&lt;li&gt;
     pay for what you use (micro-payments)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sure there is already plenty of &amp;quot;cool&amp;quot; flash games available, but imagine doing that with World of Warcraft.
&lt;/p&gt;
&lt;p&gt;Why the game industry would want that ? Because if they don't jump in and exploit this new opportunity they might vanish very quickly, because others will find a new niche in it, which will eventually eat significant market shares of the gaming industry. 
&lt;/p&gt;
&lt;p&gt;It might also be good for them to counter piracy since the game's source code would not be distributed at large, but rather kept on their servers. They would have to deal with other types of problems, but software crackers would not be a problem anymore. 
&lt;/p&gt;
&lt;p&gt;Oh, and their games would run on Windows &lt;em&gt;and&lt;/em&gt; Linux, or any other OS supported by Chrome.
&lt;/p&gt;
&lt;p&gt;I really hope this project is promising as it looks,  but I apprehend the day my boss will ask me to create a 3D web page :|
&lt;/p&gt;
&lt;p&gt;Good job Google.
&lt;/p&gt;
&lt;p&gt;
    4 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rSg_4OqggC_432poRC8B97pu8LQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rSg_4OqggC_432poRC8B97pu8LQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rSg_4OqggC_432poRC8B97pu8LQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rSg_4OqggC_432poRC8B97pu8LQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/usPe9vFmgT8" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/99/</guid><feedburner:origLink>http://www.haineault.com/blog/99/</feedburner:origLink></item><item><title>17-Apr-2009 21:12 - Installing Google Chrome on Ubuntu 8.10</title><link>http://feedproxy.google.com/~r/Haineaultcom/Blog/~3/ga6pdW5kOxE/</link><description>&lt;p&gt;I've been waiting for ages to be able to run Chrome on Linux and I just can't wait. I tried to download the 600mb archive and compile it, but it won't compile.. I don't have the courage to do a 600mb SVN checkout with my &lt;strong&gt;shitty Cogeco Cable broadband connection&lt;/strong&gt; which is pathetic enough to not be able to stream a video on Youtube.
&lt;/p&gt;
&lt;p&gt;But rejoice, today I found out that &lt;a href="http://www.playonlinux.com/en/"&gt;PlayOnLinux&lt;/a&gt;;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
     isn't only for games
 &lt;/li&gt;
&lt;li&gt;
     can install Google Chrome
 &lt;/li&gt;
&lt;li&gt;
     works.
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Their website were not updated for intrepid Ibex, I had to manually change the URL, which by chance worked fine. The rest is the same;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;sudo wget http://deb.mulx.net/playonlinux_intrepid.list -O /etc/apt/sources.list.d/playonlinux.list
wget -q http://deb.mulx.net/pol.gpg -O- | sudo apt-key add -
sudo apt-get update
sudo apt-get install playonlinux
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;It won't create a shortcut so you will have to run it from console by typing &lt;em&gt;playonlinux&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;The rest doesn't really require a tutorial, you select the program you want to install and click install.
&lt;/p&gt;
&lt;p&gt;It runs surprisingly smooth, I'd even say that it's a lot faster than Firefox ..
&lt;/p&gt;
&lt;p&gt;Encountered bugs:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
     Didn't work on first launch. The browser would not display web pages.. After shutting down and relaunching the browser from the icon created on my desktop it worked fine.
 &lt;/li&gt;
&lt;li&gt;
     The URL bar font is messed up but legible. 
 &lt;/li&gt;
&lt;li&gt;
     It won't go fullscreen (although I can resize until it's fullscreen)
 &lt;/li&gt;
&lt;li&gt;
     PNG alpha transparency mixed with CSS opacity is IE6 grade (less than shitty)
 &lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;UPDATE&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.reddit.com/r/linux/comments/8deki/installing_google_chrome_on_ubuntu_810/c08xk00"&gt;A commenter&lt;/a&gt; pointed out that it's possible to install the nightly build which are available &lt;a href="https://launchpad.net/~chromium-daily/+archive/ppa"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;The big difference is this way you get the unreleased product, which means more bugs and some things might just not work.
&lt;/p&gt;
&lt;p&gt;I've tried it and for most casual tasks it seems to work pretty well, so if you want to try it you'll have to follow these steps;
&lt;/p&gt;
&lt;p&gt;Get the PGP key &lt;a href="http://keyserver.ubuntu.com:11371/pks/lookup?op=get&amp;search;=0x5A9BF3BB4E5E17B5"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Copy the key, which should look like this;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.0.10

mI0ESaSPtAEEAK1nJtoDZ0ewpOOf0ET6Vp28LqO9mB4ubWjzXyRSbiha5pCvnnSIU1K+7Gzb
t3r0iUV9eKLUmf8pqfF/9kwsoqFqFSCjp+XjUzXsEChcGBWvyfGdTX8ClFfwNxSVLvGSqmdX
gZhs0F8tQB0lPWHGy3VvEt7wG/VHqpcOYpdNYRqxABEBAAG0IExhdW5jaHBhZCBQUEEgZm9y
IGNocm9taXVtLWRhaWx5iEYEEBECAAYFAknOwV0ACgkQ9rPTxuzZSv0f2QCeLjemEkq5tYjI
xtFpw3F11szeakYAoKsBZcl3Az08cYEd9UNZjQE1j4YtiEYEEBECAAYFAknS5Z8ACgkQrZOR
ep7Yx+qZ8wCfZYBABDkYO0Ulrivpxn6hARmgLxEAn0SeWaGjVQ4UE3zpNESguf+t9K1xiLYE
EwECACAFAkmkj7QCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBam/O7Tl4XtV/2BACs
/RTpEWB/NUlluJmp1e6iFoyyfbT+HOD3hg35aQMzbdcmijsAiY9MvIfZ0YKWyqNUdGpDj5n0
bUNO0IcvKBBkOn5o4CiBsMp4DJHdrgJU4S00nAJK00E8I/yAv+x4C9uOacW3yrzSHs7Hv/vG
6Z1Jh+1JrabK13hdhwOL8+aY6Q==
=9P6G
-----END PGP PUBLIC KEY BLOCK-----
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;Save it in a text file on your home directory, let's say &lt;em&gt;~/chrome-pgp&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;Then add the PGP key, update apt-cache and install the browser with the following commands;
&lt;/p&gt;
&lt;p&gt;&lt;div class="code_highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$:&lt;/span&gt; cat ~/chrome-pgp | sudo apt-key add -

&lt;span class="nv"&gt;$:&lt;/span&gt; sudo apt-get update

&lt;span class="nv"&gt;$:&lt;/span&gt; sudo apt-get install chromium-browser
&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;That's all !
&lt;/p&gt;
&lt;p&gt;
    0 comment(s)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ey04Ee5CgjkkzpJVB7QaTuHcm6U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ey04Ee5CgjkkzpJVB7QaTuHcm6U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ey04Ee5CgjkkzpJVB7QaTuHcm6U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ey04Ee5CgjkkzpJVB7QaTuHcm6U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Haineaultcom/Blog/~4/ga6pdW5kOxE" height="1" width="1"/&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">h3</dc:creator><guid isPermaLink="false">http://www.haineault.com/blog/98/</guid><feedburner:origLink>http://www.haineault.com/blog/98/</feedburner:origLink></item></channel></rss>
