<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US"><title type="text">Michele Campeotto</title><link rel="alternate" type="text/html" href="http://blog.micampe.it/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/micampe" /><subtitle type="html">I'm not Winston Wolfe.</subtitle><updated>2007-03-28T17:31:18+00:00</updated><generator uri="http://www.typosphere.org">Typo</generator><feedburner:info uri="micampe" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><id>tag:blog.micampe.it,2005:Typo</id><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://micampe.it/micampe-favicon-32.png</logo><feedburner:browserFriendly>(Enter a personal message you would like to have appear at the top of your feed.)</feedburner:browserFriendly><entry><title type="html">Enhanced buftabs Vim Plugin</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/V9iXrQc4Cck/enhanced-buftabs-vim-plugin" /><category term="english" /><category term="vim" /><category term="script" /><category term="plugin" /><author><name>micampe</name></author><updated>2007-03-28T10:31:18-07:00</updated><id>urn:uuid:e444b8a0-7aee-45a9-a71d-7adbd26d0d0a</id><summary type="html">&lt;p&gt;After a couple of days using my &lt;a href="http://blog.micampe.it/articles/2007/03/25/tabs-in-vim-and-my-first-plugin"&gt;bufpos&lt;/a&gt; vim plugin together with &lt;a href="http://www.vim.org/scripts/script.php?script_id=1664"&gt;buftabs&lt;/a&gt;, I realized I didn&amp;#8217;t need the buffer numbers in the status line (I can always get them with &lt;code&gt;:ls&lt;/code&gt;), but their position number would have been very useful.&lt;/p&gt;

&lt;p&gt;So here is my &lt;a href="http://micampe.it/files/buftabs.vim"&gt;modified version&lt;/a&gt; with these three changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the tab numbers indicate the the number you have press to get there instead of the buffer number&lt;/li&gt;
&lt;li&gt;improved &lt;code&gt;autocmd&lt;/code&gt; settings to better synchronize the &lt;code&gt;!&lt;/code&gt; modified flag&lt;/li&gt;
&lt;li&gt;different &lt;a href="http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers"&gt;filename shortening mode&lt;/a&gt;, now it is displayed with a path relative to the current or home directory (don&amp;#8217;t set &lt;code&gt;g:buftabs_only_basename&lt;/code&gt; to get that)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have contacted the &lt;code&gt;buftabs&lt;/code&gt; author and the last two will be in the next &lt;code&gt;buftabs&lt;/code&gt; release too.&lt;/p&gt;</summary><content type="html">&lt;p&gt;After a couple of days using my &lt;a href="http://blog.micampe.it/articles/2007/03/25/tabs-in-vim-and-my-first-plugin"&gt;bufpos&lt;/a&gt; vim plugin together with &lt;a href="http://www.vim.org/scripts/script.php?script_id=1664"&gt;buftabs&lt;/a&gt;, I realized I didn&amp;#8217;t need the buffer numbers in the status line (I can always get them with &lt;code&gt;:ls&lt;/code&gt;), but their position number would have been very useful.&lt;/p&gt;

&lt;p&gt;So here is my &lt;a href="http://micampe.it/files/buftabs.vim"&gt;modified version&lt;/a&gt; with these three changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the tab numbers indicate the the number you have press to get there instead of the buffer number&lt;/li&gt;
&lt;li&gt;improved &lt;code&gt;autocmd&lt;/code&gt; settings to better synchronize the &lt;code&gt;!&lt;/code&gt; modified flag&lt;/li&gt;
&lt;li&gt;different &lt;a href="http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers"&gt;filename shortening mode&lt;/a&gt;, now it is displayed with a path relative to the current or home directory (don&amp;#8217;t set &lt;code&gt;g:buftabs_only_basename&lt;/code&gt; to get that)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have contacted the &lt;code&gt;buftabs&lt;/code&gt; author and the last two will be in the next &lt;code&gt;buftabs&lt;/code&gt; release too.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=V9iXrQc4Cck:4dISkLivsI0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=V9iXrQc4Cck:4dISkLivsI0:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=V9iXrQc4Cck:4dISkLivsI0:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/03/28/enhanced-buftabs-vim-plugin</feedburner:origLink></entry><entry><title type="html">Tabs in Vim and My First Plugin</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/w2UAoso6BbE/tabs-in-vim-and-my-first-plugin" /><category term="english" /><category term="vim" /><category term="script" /><category term="plugin" /><author><name>micampe</name></author><updated>2007-03-26T00:25:47-07:00</updated><id>urn:uuid:162bb42d-555f-4014-a7cf-58c3c8e81ade</id><summary type="html">&lt;p&gt;One of the most talked about features of Vim7 are &lt;a href="http://www.linux.com/article.pl?sid=07/01/11/2141259"&gt;tabs&lt;/a&gt;, but I don&amp;#8217;t like them very much, I think they should have been given a different name. They could have been called &lt;em&gt;layouts&lt;/em&gt;, for example, because they are very different from what most people expect and much more similar to Eclipse&amp;#8217;s perspectives or NetBeans workspaces than to Firefox tabs.&lt;/p&gt;

&lt;p&gt;I find buffers, which have been in Vim since pretty much forever, are a very convenient way to edit multiple files. You just have to tune them a bit.&lt;/p&gt;

&lt;p&gt;First, you absolutely have to set the &lt;code&gt;hidden&lt;/code&gt; option, so you can switch between buffers without being forced to save them, and then you need some key mappings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set hidden
map &amp;lt;C-TAB&amp;gt; :bnext!&amp;lt;CR&amp;gt;
map &amp;lt;C-S-TAB&amp;gt; :bprev!&amp;lt;CR&amp;gt;
map &amp;lt;C-\&amp;gt; :b#&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use &lt;code&gt;Ctrl-Tab&lt;/code&gt; and &lt;code&gt;Ctrl-Shift-Tab&lt;/code&gt; to navigate through the list of open buffers and &lt;code&gt;Ctrl-\&lt;/code&gt; to quickly toggle between two open files.&lt;/p&gt;

&lt;p&gt;After using this setup for quite some time, about a week ago I found &lt;a href="http://www.vim.org/scripts/script.php?script_id=1664"&gt;buftabs&lt;/a&gt;, a simple plugin that displays the open buffers in the status line. I like simple plugins, my rule is that they have to be useful without me having to actually learn to use them or even remember they are there.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set laststatus=2
let g:buftabs_in_statusline=1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I then added two more mappings to navigate through buffers, to better match the visual representation &lt;code&gt;buftabs&lt;/code&gt; provides.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map &amp;lt;C-b&amp;gt; :bprev!&amp;lt;CR&amp;gt;
map &amp;lt;C-n&amp;gt; :bnext!&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With these switching buffers is even easier, as you have a visual indication of which buffer you are going to activate.&lt;/p&gt;

&lt;p&gt;Just one last piece was missing from this picture: most tabs implementations allow you to directly activate a tab by pressing the &lt;code&gt;Alt&lt;/code&gt; key and a number, like Firefox, for example.&lt;/p&gt;

&lt;p&gt;So here comes my first Vim script ever: &lt;a href="http://www.vim.org/scripts/script.php?script_id=1836"&gt;bufpos&lt;/a&gt; is a very simple script that maps &lt;code&gt;Alt-number&lt;/code&gt; keys to activate buffers.&lt;/p&gt;

&lt;p&gt;Note that you don&amp;#8217;t have to use the buffer number &lt;code&gt;buftabs&lt;/code&gt; puts beside the file name, but the position in the buffers list.&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the most talked about features of Vim7 are &lt;a href="http://www.linux.com/article.pl?sid=07/01/11/2141259"&gt;tabs&lt;/a&gt;, but I don&amp;#8217;t like them very much, I think they should have been given a different name. They could have been called &lt;em&gt;layouts&lt;/em&gt;, for example, because they are very different from what most people expect and much more similar to Eclipse&amp;#8217;s perspectives or NetBeans workspaces than to Firefox tabs.&lt;/p&gt;

&lt;p&gt;I find buffers, which have been in Vim since pretty much forever, are a very convenient way to edit multiple files. You just have to tune them a bit.&lt;/p&gt;

&lt;p&gt;First, you absolutely have to set the &lt;code&gt;hidden&lt;/code&gt; option, so you can switch between buffers without being forced to save them, and then you need some key mappings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set hidden
map &amp;lt;C-TAB&amp;gt; :bnext!&amp;lt;CR&amp;gt;
map &amp;lt;C-S-TAB&amp;gt; :bprev!&amp;lt;CR&amp;gt;
map &amp;lt;C-\&amp;gt; :b#&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use &lt;code&gt;Ctrl-Tab&lt;/code&gt; and &lt;code&gt;Ctrl-Shift-Tab&lt;/code&gt; to navigate through the list of open buffers and &lt;code&gt;Ctrl-\&lt;/code&gt; to quickly toggle between two open files.&lt;/p&gt;

&lt;p&gt;After using this setup for quite some time, about a week ago I found &lt;a href="http://www.vim.org/scripts/script.php?script_id=1664"&gt;buftabs&lt;/a&gt;, a simple plugin that displays the open buffers in the status line. I like simple plugins, my rule is that they have to be useful without me having to actually learn to use them or even remember they are there.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set laststatus=2
let g:buftabs_in_statusline=1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I then added two more mappings to navigate through buffers, to better match the visual representation &lt;code&gt;buftabs&lt;/code&gt; provides.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map &amp;lt;C-b&amp;gt; :bprev!&amp;lt;CR&amp;gt;
map &amp;lt;C-n&amp;gt; :bnext!&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With these switching buffers is even easier, as you have a visual indication of which buffer you are going to activate.&lt;/p&gt;

&lt;p&gt;Just one last piece was missing from this picture: most tabs implementations allow you to directly activate a tab by pressing the &lt;code&gt;Alt&lt;/code&gt; key and a number, like Firefox, for example.&lt;/p&gt;

&lt;p&gt;So here comes my first Vim script ever: &lt;a href="http://www.vim.org/scripts/script.php?script_id=1836"&gt;bufpos&lt;/a&gt; is a very simple script that maps &lt;code&gt;Alt-number&lt;/code&gt; keys to activate buffers.&lt;/p&gt;

&lt;p&gt;Note that you don&amp;#8217;t have to use the buffer number &lt;code&gt;buftabs&lt;/code&gt; puts beside the file name, but the position in the buffers list.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=w2UAoso6BbE:X9MVDVYyHRA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=w2UAoso6BbE:X9MVDVYyHRA:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=w2UAoso6BbE:X9MVDVYyHRA:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/03/25/tabs-in-vim-and-my-first-plugin</feedburner:origLink></entry><entry><title type="html">Splicing your feeds with Yahoo! Pipes</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/oKN5QVLp59s/splicing-your-feeds-with-yahoo-pipes" /><category term="english" /><category term="yahoo" /><category term="pipes" /><category term="feeds" /><category term="web" /><category term="mashup" /><author><name>micampe</name></author><updated>2007-03-01T09:42:24-08:00</updated><id>urn:uuid:1244163d-5d64-40b3-97b6-d678cffd7adc</id><summary type="html">&lt;p&gt;One of the services that made me subscribe to &lt;a href="http://feedburner.com/"&gt;FeedBurner&lt;/a&gt; when it has been launched, was the ability to splice my Flickr pictures and my del.icio.us bookmarks together with my blog feed. The problem with doing this with FeedBurner is that it is somewhat limited: I can&amp;#8217;t splice together arbitrary feeds, just the ones from the supported services.&lt;/p&gt;

&lt;p&gt;The easiest solution I could come up with, was using a personal installation of &lt;a href="http://planetplanet.org/"&gt;Planet&lt;/a&gt; where I&amp;#8217;d subscribe my feeds and then take just resulting feed from there, but I never managed to do this, too much grunt work to do on my part: it wasn&amp;#8217;t fun.&lt;/p&gt;

&lt;p&gt;Then, Yahoo! launched &lt;a href="http://pipes.yahoo.com/"&gt;Pipes&lt;/a&gt;. Pipes is a very nice service which allows you to play with feeds and munge them together by applying different kinds of filters. Pipes are fun to play with you drag and drop the building blocks, connect them together, add some magic and you have your new feed.&lt;/p&gt;

&lt;p&gt;Some days ago, Gina Trapani posted an article on lifehacker explaining &lt;a href="http://lifehacker.com/software/feeds/geek-to-live--create-your-master-feed-with-yahoo-pipes-235726.php"&gt;how to build your master feed&lt;/a&gt;, collecting all the feeds you produce on various blogs and services together in a single feed. She also has an example on how to inspect the feed contents to filter some items from the resulting feed.&lt;/p&gt;

&lt;p&gt;In her article, Gina says she&amp;#8217;d like to add a prefix for the feed source to differentiate the item titles. Here I have a demonstration of the power of Yahoo!&amp;#8217;s new toy: you can do that, by &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;using the Regex operator module to change the contents of an item&amp;#8217;s element&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The steps to build a Pipe like this are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use a different Fetch source for each of your feeds&lt;/li&gt;
&lt;li&gt;filter the elements you don&amp;#8217;t want&lt;/li&gt;
&lt;li&gt;apply the Regex operator to the title to replace &amp;#8221;&lt;code&gt;^&lt;/code&gt;&amp;#8221; with &amp;#8221;&lt;code&gt;Source:&lt;/code&gt;&amp;#8221;, which is just Regex-fu for &amp;#8220;put the source name in front of the title&amp;#8221; (you&amp;#8217;ll have to put the actual name you want for the source instead of &amp;#8220;Source&amp;#8221;, see the example &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;pipe&lt;/a&gt; I created). (updated with &lt;a href="http://lifehacker.com/software/yahoo!/yahoo-pipes-master-feed-update-240520.php#c1034919"&gt;hint by muczachan&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;put all the resulting feeds in a Union operator&lt;/li&gt;
&lt;li&gt;sort the Union output feed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optionally, you can limit the number of items in the resulting feed by using the Truncate operator. Also, should you have more feeds than the five input sockets of the Union module provides, you can add more Union modules and then combine them with another one.&lt;/p&gt;

&lt;p&gt;Feel free to clone the &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;pipe&lt;/a&gt; I created and adapt it to your own feeds.&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the services that made me subscribe to &lt;a href="http://feedburner.com/"&gt;FeedBurner&lt;/a&gt; when it has been launched, was the ability to splice my Flickr pictures and my del.icio.us bookmarks together with my blog feed. The problem with doing this with FeedBurner is that it is somewhat limited: I can&amp;#8217;t splice together arbitrary feeds, just the ones from the supported services.&lt;/p&gt;

&lt;p&gt;The easiest solution I could come up with, was using a personal installation of &lt;a href="http://planetplanet.org/"&gt;Planet&lt;/a&gt; where I&amp;#8217;d subscribe my feeds and then take just resulting feed from there, but I never managed to do this, too much grunt work to do on my part: it wasn&amp;#8217;t fun.&lt;/p&gt;

&lt;p&gt;Then, Yahoo! launched &lt;a href="http://pipes.yahoo.com/"&gt;Pipes&lt;/a&gt;. Pipes is a very nice service which allows you to play with feeds and munge them together by applying different kinds of filters. Pipes are fun to play with you drag and drop the building blocks, connect them together, add some magic and you have your new feed.&lt;/p&gt;

&lt;p&gt;Some days ago, Gina Trapani posted an article on lifehacker explaining &lt;a href="http://lifehacker.com/software/feeds/geek-to-live--create-your-master-feed-with-yahoo-pipes-235726.php"&gt;how to build your master feed&lt;/a&gt;, collecting all the feeds you produce on various blogs and services together in a single feed. She also has an example on how to inspect the feed contents to filter some items from the resulting feed.&lt;/p&gt;

&lt;p&gt;In her article, Gina says she&amp;#8217;d like to add a prefix for the feed source to differentiate the item titles. Here I have a demonstration of the power of Yahoo!&amp;#8217;s new toy: you can do that, by &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;using the Regex operator module to change the contents of an item&amp;#8217;s element&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The steps to build a Pipe like this are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use a different Fetch source for each of your feeds&lt;/li&gt;
&lt;li&gt;filter the elements you don&amp;#8217;t want&lt;/li&gt;
&lt;li&gt;apply the Regex operator to the title to replace &amp;#8221;&lt;code&gt;^&lt;/code&gt;&amp;#8221; with &amp;#8221;&lt;code&gt;Source:&lt;/code&gt;&amp;#8221;, which is just Regex-fu for &amp;#8220;put the source name in front of the title&amp;#8221; (you&amp;#8217;ll have to put the actual name you want for the source instead of &amp;#8220;Source&amp;#8221;, see the example &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;pipe&lt;/a&gt; I created). (updated with &lt;a href="http://lifehacker.com/software/yahoo!/yahoo-pipes-master-feed-update-240520.php#c1034919"&gt;hint by muczachan&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;put all the resulting feeds in a Union operator&lt;/li&gt;
&lt;li&gt;sort the Union output feed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optionally, you can limit the number of items in the resulting feed by using the Truncate operator. Also, should you have more feeds than the five input sockets of the Union module provides, you can add more Union modules and then combine them with another one.&lt;/p&gt;

&lt;p&gt;Feel free to clone the &lt;a href="http://pipes.yahoo.com/pipes/qNtovDTH2xGi9LMuJzBjOg/"&gt;pipe&lt;/a&gt; I created and adapt it to your own feeds.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=oKN5QVLp59s:x8R74dt8Oxk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=oKN5QVLp59s:x8R74dt8Oxk:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=oKN5QVLp59s:x8R74dt8Oxk:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/02/28/splicing-your-feeds-with-yahoo-pipes</feedburner:origLink></entry><entry><title type="html">FlickrUploadr is back</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/EToWILWLO6M/flickruploadr-is-back" /><category term="english" /><category term="flickr" /><category term="python" /><category term="uploadr" /><author><name>micampe</name></author><updated>2007-02-26T06:00:23-08:00</updated><id>urn:uuid:ecacb4dc-471f-4bf6-8a80-0e5611268fcd</id><summary type="html">&lt;p&gt;Eighteen months later, &lt;a href="http://www-csag.ucsd.edu/individual/ehw/"&gt;Eric Weigle&lt;/a&gt; sent me a new version of &lt;a href="http://micampe.it/projects/flickruploadr"&gt;FlickrUploadr&lt;/a&gt; wich supports Yahoo!&amp;#8217;s authentication scheme, which is now required even for first-time Flickr users.&lt;/p&gt;

&lt;p&gt;Eric merged my code with &lt;a href="http://berserk.org/uploadr/"&gt;Cameron Mallory&lt;/a&gt;&amp;#8217;s great authentication support and built this new version. Thanks to the new authentication scheme, FlickrUploadr doesn&amp;#8217;t save your password on your disk anymore, so you can now remove the &lt;code&gt;~/.uploadr&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Thanks Eric and Cameron for the very nice work.&lt;/p&gt;

&lt;p&gt;Download &lt;a href="http://micampe.it/files/FlickrUploadr-1.0.0.tar.gz"&gt;FlickrUploadr 1.0&lt;/a&gt;.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Eighteen months later, &lt;a href="http://www-csag.ucsd.edu/individual/ehw/"&gt;Eric Weigle&lt;/a&gt; sent me a new version of &lt;a href="http://micampe.it/projects/flickruploadr"&gt;FlickrUploadr&lt;/a&gt; wich supports Yahoo!&amp;#8217;s authentication scheme, which is now required even for first-time Flickr users.&lt;/p&gt;

&lt;p&gt;Eric merged my code with &lt;a href="http://berserk.org/uploadr/"&gt;Cameron Mallory&lt;/a&gt;&amp;#8217;s great authentication support and built this new version. Thanks to the new authentication scheme, FlickrUploadr doesn&amp;#8217;t save your password on your disk anymore, so you can now remove the &lt;code&gt;~/.uploadr&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Thanks Eric and Cameron for the very nice work.&lt;/p&gt;

&lt;p&gt;Download &lt;a href="http://micampe.it/files/FlickrUploadr-1.0.0.tar.gz"&gt;FlickrUploadr 1.0&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=EToWILWLO6M:QNYNWPsrm9Y:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=EToWILWLO6M:QNYNWPsrm9Y:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=EToWILWLO6M:QNYNWPsrm9Y:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/02/26/flickruploadr-is-back</feedburner:origLink></entry><entry><title type="html">Scala</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/Vp7GeU2unT0/scala" /><category term="english" /><category term="scala" /><category term="java" /><category term="haskell" /><category term="code" /><category term="programming" /><author><name>micampe</name></author><updated>2007-02-23T14:47:41-08:00</updated><id>urn:uuid:8c505b6f-48d4-4916-963f-a9deaa8b1ad1</id><summary type="html">&lt;p&gt;I recently learned about &lt;a href="http://scala-lang.org"&gt;Scala&lt;/a&gt;, a language for the JVM which tries to smoothly integrate object oriented and functional programming features.&lt;/p&gt;

&lt;p&gt;I find it particularly interesting because of two reasons: first it is integrated with the Java platform and thus can use all the Java code already available. Second, it can be used almost as a Java evolution where you can gradually add functional concepts and more advanced features of the type system.&lt;/p&gt;

&lt;p&gt;Scala is a static language, and lately the whole world is excited about dynamic languages, so this might seem a bit backwards, but I think sane static languages have their place in the world. And Scala has some very nice features (pattern matching on objects, flexible syntax) to make it appealing to me. I&amp;#8217;d like to try to use it &lt;a href="http://www.h-care.it/"&gt;at work&lt;/a&gt;, integrating it with the bulk of Java code we already have.&lt;/p&gt;

&lt;p&gt;To experiment a bit with the language I tried translating some &lt;a href="http://en.literateprograms.org/Quicksort_%28Haskell%29"&gt;examples from Haskell&lt;/a&gt;. The result is kinda pointless and probably not a good example of Scala programming, but it helped me get a feeling of the language.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently learned about &lt;a href="http://scala-lang.org"&gt;Scala&lt;/a&gt;, a language for the JVM which tries to smoothly integrate object oriented and functional programming features.&lt;/p&gt;

&lt;p&gt;I find it particularly interesting because of two reasons: first it is integrated with the Java platform and thus can use all the Java code already available. Second, it can be used almost as a Java evolution where you can gradually add functional concepts and more advanced features of the type system.&lt;/p&gt;

&lt;p&gt;Scala is a static language, and lately the whole world is excited about dynamic languages, so this might seem a bit backwards, but I think sane static languages have their place in the world. And Scala has some very nice features (pattern matching on objects, flexible syntax) to make it appealing to me. I&amp;#8217;d like to try to use it &lt;a href="http://www.h-care.it/"&gt;at work&lt;/a&gt;, integrating it with the bulk of Java code we already have.&lt;/p&gt;

&lt;p&gt;To experiment a bit with the language I tried translating some &lt;a href="http://en.literateprograms.org/Quicksort_%28Haskell%29"&gt;examples from Haskell&lt;/a&gt;. The result is kinda pointless and probably not a good example of Scala programming, but it helped me get a feeling of the language.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;package test.sort

object QuickSort {

  def qsort1[A &amp;lt;% Ordered[A]](xs: List[A]): List[A] = xs match {
    case y :: ys =&amp;gt; {
      val lt = for (val i &amp;lt;- ys; i &amp;lt; y) yield i;
      val gt = for (val i &amp;lt;- ys; i &amp;gt;= y) yield i;
      qsort1(lt) ::: List(y) ::: qsort1(gt)
    }
    case Nil =&amp;gt; Nil
  }

  def qsort2[A &amp;lt;% Ordered[A]](xs: List[A]): List[A] = xs match {
    case Nil =&amp;gt; Nil
    case z :: zs =&amp;gt; {
      def part(z: A, zs: List[A], parts: Tuple3[List[A], List[A], List[A]]): Tuple3[List[A], List[A], List[A]] = zs match {
        case Nil =&amp;gt; parts
        case y :: ys =&amp;gt; {
          if (y &amp;gt; z)
            part(z, ys, {parts._1, parts._2, y :: parts._3})
          else if (y &amp;lt; z) 
            part(z, ys, {y :: parts._1, parts._2, parts._3})
          else 
            part(z, ys, {parts._1, y :: parts._2, parts._3})
        }
      }
      val parts = part(z, zs, Tuple3(Nil, List(z), Nil))
      qsort2(parts._1) ::: parts._2 ::: qsort2(parts._3)
    }
  }

  def qsort3[A &amp;lt;% Ordered[A]](xs: List[A]): List[A] = {
    def qsort3b(ys: List[A], acc: List[A]): List[A] = ys match {
      case Nil =&amp;gt; acc
      case List(z) =&amp;gt; z :: acc
      case z :: zs =&amp;gt; {
        def part(ps: List[A], parts: Tuple3[List[A], List[A], List[A]]): List[A] = ps match {
          case Nil =&amp;gt; qsort3b(parts._1, parts._2 ::: qsort3b(parts._3, acc))
          case z :: zs =&amp;gt; {
            if (z &amp;gt; ys.head)
              part(zs, {parts._1, parts._2, z :: parts._3})
            else if (z &amp;lt; ys.head)
              part(zs, {z :: parts._1, parts._2, parts._3})
            else
              part(zs, {parts._1, z :: parts._2, parts._3})
          }
        }
        part(zs, {Nil, List(z), Nil})
      }
    }
    qsort3b(xs, Nil)
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=Vp7GeU2unT0:8eK3Mp2CsTg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=Vp7GeU2unT0:8eK3Mp2CsTg:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=Vp7GeU2unT0:8eK3Mp2CsTg:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/02/21/scala</feedburner:origLink></entry><entry><title type="html">A little Django feature nobody tells you about</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/2_WSL2yoQvw/a-little-django-feature-nobody-tells-you-about" /><category term="english" /><category term="django" /><category term="web" /><category term="python" /><author><name>micampe</name></author><updated>2007-01-06T09:36:20-08:00</updated><id>urn:uuid:f507f9ce-ec95-4420-a60b-845a11c08ef0</id><summary type="html">&lt;p&gt;Recently i got involved in a &lt;a href="http://it.blogbabel.com/"&gt;new project&lt;/a&gt; which uses Django, so I started learning and using it. I won&amp;#8217;t tell you here it merits as those have alread been described at lenght.&lt;/p&gt;

&lt;p&gt;One of the features I like about Django are its pluggable applications: you can build a generic piece of code and that can easily be plugged in other&amp;#8217;s sites to get some new functionality. Great examples of this are found in the &lt;code&gt;django.contrib&lt;/code&gt; package, which include the already famous administrative interface, two comments systems, an authentication/authorization framework and more.&lt;/p&gt;

&lt;p&gt;One problem you&amp;#8217;ll soon find is that some of these are tied to be plugged at a fixed URL prefix. The auth system, for example, expects to be plugged in the &lt;code&gt;/accounts/&lt;/code&gt; directory and plugging it somewhere else leads to some more work for you. The easiest example is the &lt;code&gt;@login_required&lt;/code&gt; decorator, which checks the user that is calling a view and, if it is not authenticated, it redirects to &lt;code&gt;/accounts/login&lt;/code&gt;. If you have used a different URL prefix, you are forced to use the &lt;code&gt;@user_passes_test&lt;/code&gt; decorator, which allows you to set the redirect URL.&lt;/p&gt;

&lt;p&gt;Where is the problem? The problem is that those paths are explicitly hardocded in the views.&lt;/p&gt;

&lt;p&gt;How to solve it? Dynamically build your URLs from your &lt;code&gt;urlconf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How do you do that? With &lt;code&gt;django.core.urlresolvers.reverse()&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently i got involved in a &lt;a href="http://it.blogbabel.com/"&gt;new project&lt;/a&gt; which uses Django, so I started learning and using it. I won&amp;#8217;t tell you here it merits as those have alread been described at lenght.&lt;/p&gt;

&lt;p&gt;One of the features I like about Django are its pluggable applications: you can build a generic piece of code and that can easily be plugged in other&amp;#8217;s sites to get some new functionality. Great examples of this are found in the &lt;code&gt;django.contrib&lt;/code&gt; package, which include the already famous administrative interface, two comments systems, an authentication/authorization framework and more.&lt;/p&gt;

&lt;p&gt;One problem you&amp;#8217;ll soon find is that some of these are tied to be plugged at a fixed URL prefix. The auth system, for example, expects to be plugged in the &lt;code&gt;/accounts/&lt;/code&gt; directory and plugging it somewhere else leads to some more work for you. The easiest example is the &lt;code&gt;@login_required&lt;/code&gt; decorator, which checks the user that is calling a view and, if it is not authenticated, it redirects to &lt;code&gt;/accounts/login&lt;/code&gt;. If you have used a different URL prefix, you are forced to use the &lt;code&gt;@user_passes_test&lt;/code&gt; decorator, which allows you to set the redirect URL.&lt;/p&gt;

&lt;p&gt;Where is the problem? The problem is that those paths are explicitly hardocded in the views.&lt;/p&gt;

&lt;p&gt;How to solve it? Dynamically build your URLs from your &lt;code&gt;urlconf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How do you do that? With &lt;code&gt;django.core.urlresolvers.reverse()&lt;/code&gt;&lt;/p&gt;&lt;p&gt;That little boy helps you by giving you the URL path that would be called given a view and a set of parameters. Here is an example, suppose your urlconf has something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;urlpatterns = patterns('',
    (r'^/blog/(?P&amp;lt;year&amp;gt;\d{4})/(?P&amp;lt;month&amp;gt;\d{2})/(?P&amp;lt;day&amp;gt;\d{2})/(?P&amp;lt;slug&amp;gt;[-\w]+)/$',
        'dlog.blog.views.entry'),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;you could create a function like this to get the URL of an entry:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    def get_absolute_url(self):
        return urlresolvers.reverse('dlog.blog.views.entry',
                kwargs={'year':self.pubdate.year,
                        'month':('%02d' % self.pubdate.month),
                        'day':('%02d' % self.pubdate.day),
                        'slug':self.slug})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;when you then call an entry&amp;#8217;s &lt;code&gt;get_absolute_url()&lt;/code&gt; method, you&amp;#8217;ll get the URL as urlconf expects it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/blog/2007/01/06/your-slug-goes-here
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don&amp;#8217;t know why this isn&amp;#8217;t mentioned anywhere in the docs, I found it by hunting down the source code because I didn&amp;#8217;t like hardcoding paths in my views.&lt;/p&gt;

&lt;p&gt;I can understand it has some problems: it gives you only URLs relative to the root of the Django project, if you need an absolute URL or if you attached the site to a subdirectory of your domain, &lt;code&gt;urlresolvers.reverse()&lt;/code&gt; is not enough, but I still think it should be advertised in the documentation.&lt;/p&gt;

&lt;p&gt;One more thing, as everybody starting to use Django, I wrote a web log with it. But I haven&amp;#8217;t replaced this one, I created a new one, but this time in Italian and that will be more personal and, hopefully, a real blog that I update it more often than monthly and I actually &lt;a href="http://it.blogbabel.com/"&gt;participate&lt;/a&gt;. So, if you can read Italian follow me on &lt;a href="http://michele.campeotto.net/"&gt;my new corner&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=2_WSL2yoQvw:80nzSGECQaY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=2_WSL2yoQvw:80nzSGECQaY:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=2_WSL2yoQvw:80nzSGECQaY:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2007/01/06/a-little-django-feature-nobody-tells-you-about</feedburner:origLink></entry><entry><title type="html">A tale of Pylons, Python and FastCGI on Dreamhost</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/lR_PSmxZVyc/a-tale-of-pylons-python-and-fastcgi-on-dreamhost" /><category term="english" /><category term="python" /><category term="pylons" /><category term="wsgi" /><category term="fastcgi" /><category term="dreamhost" /><category term="django" /><category term="turbogears" /><author><name>micampe</name></author><updated>2006-11-27T03:41:19-08:00</updated><id>urn:uuid:8a140a5f-4804-415f-91f2-b2bd554b87af</id><summary type="html">&lt;p&gt;&lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; is a &lt;a href="http://wsgi.org"&gt;WSGI&lt;/a&gt; based Python Web Framework that tries to combine the
best ideas from other existing frameworks and does so by glueing togheter
existing projects and allowing to swap its components at will and easily extend
its capabilites with other WSGI components.&lt;/p&gt;

&lt;p&gt;I will explain here how I installed it and a demo application on &lt;a href="http://www.dreamhost.com/r.cgi?195290"&gt;Dreamhost&lt;/a&gt;
and how to avoid the single problem I had.&lt;/p&gt;

&lt;p&gt;This procedure isn&amp;#8217;t specific to either Dreamhost or Pylons, it can be used
anywhere and for any WSGI compliant application if you don&amp;#8217;t have root access
to install new modules or if you want to keep the system wide installation
clean and add modules just for a single user.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; is a &lt;a href="http://wsgi.org"&gt;WSGI&lt;/a&gt; based Python Web Framework that tries to combine the
best ideas from other existing frameworks and does so by glueing togheter
existing projects and allowing to swap its components at will and easily extend
its capabilites with other WSGI components.&lt;/p&gt;

&lt;p&gt;I will explain here how I installed it and a demo application on &lt;a href="http://www.dreamhost.com/r.cgi?195290"&gt;Dreamhost&lt;/a&gt;
and how to avoid the single problem I had.&lt;/p&gt;

&lt;p&gt;This procedure isn&amp;#8217;t specific to either Dreamhost or Pylons, it can be used
anywhere and for any WSGI compliant application if you don&amp;#8217;t have root access
to install new modules or if you want to keep the system wide installation
clean and add modules just for a single user.&lt;/p&gt;&lt;p&gt;The installation procedure is quite easy and mostly automated, start by running
these commands from your home directory on the remote shell:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir bin
wget -P bin http://peak.telecommunity.com/dist/virtual-python.py
python2.4 bin/virtual-python
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;#8217;s important that you use &lt;code&gt;python2.4&lt;/code&gt; here, not just &lt;code&gt;python&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This command will create some directories and symlinks on your home directory
that will result in you little private Python environment, where you have the
power to install new packages at will. To make the illusion more real, you
should then add &lt;code&gt;~/bin&lt;/code&gt; in front of your &lt;code&gt;$PATH&lt;/code&gt;, so that you can just type
&lt;code&gt;python&lt;/code&gt; in the shell and the interpreter used will be your private one instead
of the global one.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export PATH="~/bin:$PATH"    # add this to ~/.bash_profile
wget -P bin http://peak.telecommunity.com/dist/ez_setup.py
python bin/ez_setup.py
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will install the &lt;code&gt;easy_install&lt;/code&gt; script that you will use to install Pylons
and other Python modules you can find on the &lt;a href="http://cheeseshop.python.org/pypi"&gt;Cheese Shop&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;easy_install Pylons
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will install the Pylons framework and all its dependencies. To test the
installation we will use the &lt;a href="http://pylonshq.com/docs/quick_wiki.html"&gt;QuickWiki&lt;/a&gt; demo application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;easy_install QuickWiki
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will install the application and some more dependencies. The next step is
creating the configuration file for the application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;paster make-config QuickWiki wiki.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this file you only have to change the database URI, for this test we will
use SQLite:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sqlalchemy.dburi = sqlite:///quickwiki.db
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And setup the application to create the database:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;paster setup-app wiki.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then we need a script to start the application. Pylons, as every WSGI
application can be deployed in a number of different ways, but the only one you
can use on Dreamhost is FastCGI. At this point, every tutorial around the web
will tell you to use &lt;a href="http://www.saddi.com/software/flup/"&gt;flup&lt;/a&gt; and then there will be pain and hair pulling
because you won&amp;#8217;t understand why it&amp;#8217;s not working (unless you ask &lt;a href="http://blogs.flup.org/page/asaddi"&gt;Allan
Saddi&lt;/a&gt; to check your setup, that is. Thank you Allan!).&lt;/p&gt;

&lt;p&gt;The solution is to use the supposed to be obsolete &lt;a href="http://svn.saddi.com/py-lib/trunk/fcgi.py"&gt;fcgi.py&lt;/a&gt; script, so let&amp;#8217;s
install it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget -P lib/python2.4/site-packages http://svn.saddi.com/py-lib/trunk/fcgi.py
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We said we needed a script, so put this in a file named &lt;code&gt;server.fcgi&lt;/code&gt; in your
web directory and make it executable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/home/username/bin/python

from paste.deploy import loadapp
from fcgi import WSGIServer

app = loadapp('config:/home/username/www.yourdomain.net/wiki.ini')
server = WSGIServer(app)
server.run()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will need to correct the paths here, as we need them to be absolute.&lt;/p&gt;

&lt;p&gt;Now when you point at this file in a web browser you should see the QuickWiki
FrontPage.&lt;/p&gt;

&lt;p&gt;The problem with flup (as found by Allan itself) is that it takes too long to start and it seems that FastCGI on Dreamhost will wait for a maximum of 3 seconds. &lt;code&gt;fcgi.py&lt;/code&gt; instead is simpler (doesn&amp;#8217;t do thread pooling for example) and therefore faster to start. This means that when the server is under heavy load there could still be problems, but it has been pretty reliable.&lt;/p&gt;

&lt;p&gt;The best solution to this problem would be &lt;a href="http://www.mems-exchange.org/software/scgi/"&gt;SCGI&lt;/a&gt; support by Dreamhost, if you already are a customer, go &lt;a href="https://panel.dreamhost.com/index.cgi?tree=home.sugg&amp;amp;search=scgi"&gt;vote for it&lt;/a&gt;!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=lR_PSmxZVyc:cW0vgylzGKc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=lR_PSmxZVyc:cW0vgylzGKc:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=lR_PSmxZVyc:cW0vgylzGKc:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2006/11/26/a-tale-of-pylons-python-and-fastcgi-on-dreamhost</feedburner:origLink></entry><entry><title type="html">Ruby and Python: perspectives</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/70zigjKt_r8/ruby-and-python-perspectives" /><category term="english" /><category term="ruby" /><category term="python" /><category term="perspective" /><category term="style" /><category term="philosophy" /><author><name>micampe</name></author><updated>2006-11-28T03:11:55-08:00</updated><id>urn:uuid:db3d233b-525c-4b4f-96af-4079ed77cfcc</id><summary type="html">&lt;p&gt;I just realized something interesting.&lt;/p&gt;

&lt;p&gt;In Ruby you mix in modules that add methods to objects that implement interfaces.&lt;/p&gt;

&lt;p&gt;In Python you have functions that you use on objects that implement interfaces.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I just realized something interesting.&lt;/p&gt;

&lt;p&gt;In Ruby you mix in modules that add methods to objects that implement interfaces.&lt;/p&gt;

&lt;p&gt;In Python you have functions that you use on objects that implement interfaces.&lt;/p&gt;&lt;p&gt;One easy example are enumerables/iterables: in Ruby, an object is enumerable if it implements the &lt;code&gt;each&lt;/code&gt; method. The object can then mix in &lt;a href="http://www.ruby-doc.org/core/classes/Enumerable.html"&gt;Enumerable&lt;/a&gt; to gain some methods that you can use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;f = File.new(".bashrc", "r")
lines = f.find_all { |l| l =~ /^[^#]/ }
# or lines = f.grep(/^[^#]/)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Python, an object is &lt;a href="http://www.python.org/dev/peps/pep-0234/"&gt;iterable&lt;/a&gt; if it implements the &lt;code&gt;__iter__&lt;/code&gt; method, and the language &lt;em&gt;&amp;#8220;knows&amp;#8221;&lt;/em&gt; how to use the iterators:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;f = file(".bashrc", "r")
lines = [ l for l in f if not l.startswith("#") ]
# or lines = filter(lambda l: not l.startswith("#"), f)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;other examples are &lt;code&gt;any&lt;/code&gt; and &lt;code&gt;all&lt;/code&gt;, which incidentally are what started the discussion with &lt;a href="http://fmosca.acx.it"&gt;Francesco&lt;/a&gt; about this:&lt;/p&gt;

&lt;p&gt;In Ruby, the &lt;code&gt;any?&lt;/code&gt; method is added to every enumerable object that mixes in Enumerable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lines.any? { |l| l =~ /^#/ }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Python, &lt;code&gt;any()&lt;/code&gt; is a built-in function (introduced in &lt;a href="http://docs.python.org/whatsnew/whatsnew25.html"&gt;2.5&lt;/a&gt;) which knows how to use any sequence:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;any(l.startswith("#") for l in lines)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So Ruby works from the &lt;em&gt;inside&lt;/em&gt;, and Python from the &lt;em&gt;outside&lt;/em&gt; of objects. I think therefore that the next comparison between the two languages should not be side-by-side, but inside-and-out.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=70zigjKt_r8:VMLOaVTA8Es:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=70zigjKt_r8:VMLOaVTA8Es:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=70zigjKt_r8:VMLOaVTA8Es:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2006/11/10/ruby-and-python-perspectives</feedburner:origLink></entry><entry><title type="html">How I read and backup my mail</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/gKgywpA5nbg/how-i-read-and-backup-my-mail" /><category term="mutt" /><category term="email" /><category term="thunderbird" /><category term="backup" /><category term="ssmtp" /><author><name>micampe</name></author><updated>2006-11-07T12:50:44-08:00</updated><id>urn:uuid:ebb7bb14-0362-427f-ab3e-e74f06f71116</id><summary type="html">&lt;p&gt;I was going to answer &lt;a href="http://www.kryogenix.org/days/2006/11/04/mail-forwarding-smtp-server"&gt;Stuart&lt;/a&gt;&amp;#8217;s question to the Lazyweb in a quick comment, but I figured my email set up, while essentially not really special, is a bit peculiar and might be interesting to somebody out there.&lt;/p&gt;

&lt;p&gt;I have all my personal email on Gmail, but I also download it locally to keep a backup, &lt;a href="http://blog.outer-court.com/forum/22209.html"&gt;just in case&lt;/a&gt;. The problem is that if you read your mail with Thunderbird, it ends up inside a directory with a funny name which in turn contains a funny mix of files of which you don&amp;#8217;t know the purpose, so the backup (and the restore) is a bit unpractical.&lt;/p&gt;

&lt;p&gt;The solution turned out to be quite easy: you retrieve your email and with some magic symlinks you make Thunderbird read that. The only limitations to this are that Thunderbird only supports mbox mailboxes and that it has to update its indexes every time it starts.&lt;/p&gt;

&lt;p&gt;My final set up is that I can retrieve, read and send email with both &lt;a href="http://www.mutt.org"&gt;mutt&lt;/a&gt; and Thunderbird and the mail is in plain mbox files that I can easily rsync around. Here&amp;#8217;s how I did it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I was going to answer &lt;a href="http://www.kryogenix.org/days/2006/11/04/mail-forwarding-smtp-server"&gt;Stuart&lt;/a&gt;&amp;#8217;s question to the Lazyweb in a quick comment, but I figured my email set up, while essentially not really special, is a bit peculiar and might be interesting to somebody out there.&lt;/p&gt;

&lt;p&gt;I have all my personal email on Gmail, but I also download it locally to keep a backup, &lt;a href="http://blog.outer-court.com/forum/22209.html"&gt;just in case&lt;/a&gt;. The problem is that if you read your mail with Thunderbird, it ends up inside a directory with a funny name which in turn contains a funny mix of files of which you don&amp;#8217;t know the purpose, so the backup (and the restore) is a bit unpractical.&lt;/p&gt;

&lt;p&gt;The solution turned out to be quite easy: you retrieve your email and with some magic symlinks you make Thunderbird read that. The only limitations to this are that Thunderbird only supports mbox mailboxes and that it has to update its indexes every time it starts.&lt;/p&gt;

&lt;p&gt;My final set up is that I can retrieve, read and send email with both &lt;a href="http://www.mutt.org"&gt;mutt&lt;/a&gt; and Thunderbird and the mail is in plain mbox files that I can easily rsync around. Here&amp;#8217;s how I did it.&lt;/p&gt;&lt;p&gt;mutt downloads the mail and puts it in &lt;code&gt;~/Mail&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set pop_host = pops://micampe@pop.gmail.com:995
set pop_last = yes

set folder = ~/Mail
set spoolfile = +spool
set postponed = +postponed
set mbox = +inbox
set record = +inbox

set sendmail="~/.mutt/ssmtp"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see I also keep sent and received mail together, to emulate Gmail&amp;#8217;s conversations, which I find very convenient.&lt;/p&gt;

&lt;p&gt;To send mail (and this is my answer to &lt;a href="http://www.kryogenix.org/days/2006/11/04/mail-forwarding-smtp-server"&gt;Stuart&lt;/a&gt;), I use &lt;a href="http://packages.debian.org/stable/mail/ssmtp"&gt;ssmtp&lt;/a&gt;, a very simple SMTP agent which is also flexible and easy to configure. It just connects to an external SMTP server and forwards my email to it. No queuing, no forwards, no nothing it just does that and here&amp;#8217;s how I set it up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mailhub=smtp.gmail.com:465
rewriteDomain=micampe.it
FromLineOverride=YES
UseTLS=YES
AuthUser=micampe@gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is saved in &lt;code&gt;~/.mutt/ssmtp.conf&lt;/code&gt; and is used by the script &lt;code&gt;~/.mutt/ssmtp&lt;/code&gt; which mutt is using to send mail:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
/usr/sbin/ssmtp -C ~/.mutt/ssmtp.conf $@
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One nice thing about ssmtp is that it&amp;#8217;s just a command line program that you run when you want to send a mail, you don&amp;#8217;t need to have a daemon running.&lt;/p&gt;

&lt;p&gt;Now I just have configured mutt to read my mail from Gmail, &amp;#8220;what&amp;#8217;s the deal?&amp;#8221; you say, &amp;#8220;this is easy.&amp;#8221; Well, the next step is where I symlink mutt&amp;#8217;s inbox with Thunderbird&amp;#8217;s:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd ~/.mozilla-thunderbird/*.default/Mail/Local\ Folders/
$ rm Inbox
$ ln -s ~/Mail/inbox Inbox
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now mutt and Thunderbird have access to the same mail messages, and I can use which one I like best in a given moment.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=gKgywpA5nbg:tn_B8K8d504:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=gKgywpA5nbg:tn_B8K8d504:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=gKgywpA5nbg:tn_B8K8d504:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2006/11/05/how-i-read-and-backup-my-mail</feedburner:origLink></entry><entry><title type="html">Vim Tango color scheme</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/micampe/~3/kdO6znziniw/vim-tango-color-scheme" /><category term="english" /><category term="vim" /><category term="tango" /><category term="colorscheme" /><author><name>micampe</name></author><updated>2006-11-28T04:12:01-08:00</updated><id>urn:uuid:83fbead4-0ada-4b00-9bd7-b3338003bbaf</id><summary type="html">&lt;p&gt;Things you do at the airport while waiting for the cute girl to call the boarding&amp;#8230;&lt;/p&gt;

&lt;p&gt;Finding that a &lt;a href="http://uwstopia.nl/blog/2006/07/tango-terminal"&gt;Tango color scheme for my terminal&lt;/a&gt; was a nice idea, I made one for my Vim too.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;a href="http://micampe.it/screenshots/tango-vim.png"&gt;&lt;img src="http://micampe.it/screenshots/tango-vim-thumb.png" alt="screenshot" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;To use the &lt;a href="http://www.vim.org/scripts/script.php?script_id=1686"&gt;Vim Tango color scheme&lt;/a&gt; you have to place the &lt;a href="http://micampe.it/files/tango.vim"&gt;&lt;code&gt;tango.vim&lt;/code&gt;&lt;/a&gt; file in the &lt;code&gt;~/.vim/colors/&lt;/code&gt; directory and &lt;code&gt;colorscheme tango&lt;/code&gt; in your &lt;code&gt;~/.vimrc&lt;/code&gt;.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Things you do at the airport while waiting for the cute girl to call the boarding&amp;#8230;&lt;/p&gt;

&lt;p&gt;Finding that a &lt;a href="http://uwstopia.nl/blog/2006/07/tango-terminal"&gt;Tango color scheme for my terminal&lt;/a&gt; was a nice idea, I made one for my Vim too.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;a href="http://micampe.it/screenshots/tango-vim.png"&gt;&lt;img src="http://micampe.it/screenshots/tango-vim-thumb.png" alt="screenshot" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;To use the &lt;a href="http://www.vim.org/scripts/script.php?script_id=1686"&gt;Vim Tango color scheme&lt;/a&gt; you have to place the &lt;a href="http://micampe.it/files/tango.vim"&gt;&lt;code&gt;tango.vim&lt;/code&gt;&lt;/a&gt; file in the &lt;code&gt;~/.vim/colors/&lt;/code&gt; directory and &lt;code&gt;colorscheme tango&lt;/code&gt; in your &lt;code&gt;~/.vimrc&lt;/code&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/micampe?a=kdO6znziniw:Nnty-I0AgzQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/micampe?a=kdO6znziniw:Nnty-I0AgzQ:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/micampe?i=kdO6znziniw:Nnty-I0AgzQ:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</content><feedburner:origLink>http://blog.micampe.it/articles/2006/10/20/vim-tango-color-scheme</feedburner:origLink></entry></feed>
