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

<channel>
	<title>Memory Dump</title>
	<atom:link href="http://www.lorenzogil.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lorenzogil.com/blog</link>
	<description>a brain backup</description>
	<lastBuildDate>Sun, 09 Oct 2011 12:36:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>First impressions with Liferay</title>
		<link>http://www.lorenzogil.com/blog/2011/10/09/first-impressions-with-liferay/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=first-impressions-with-liferay</link>
		<comments>http://www.lorenzogil.com/blog/2011/10/09/first-impressions-with-liferay/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 12:36:12 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Ordenadores]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Yaco]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=344</guid>
		<description><![CDATA[A couple of weekends ago I had my first experience customizing a Liferay site. I wrote a very simple theme to change the standard look &#38; feel and I also wrote some portlets in several differente languages. The goal was to analyze which portlet technology was the best to suit our needs. Writing the theme [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weekends ago I had my first experience customizing a Liferay site. I wrote a very simple theme to change the standard look &amp; feel and I also wrote some portlets in several differente languages. The goal was to analyze which portlet technology was the best to suit our needs.</p>
<p>Writing the theme was not difficult at all. Liferay has an excellent SDK for writing plugins, which include themes. I didn&#8217;t start from scratch but used the <a href="http://liferay-themes.sourceforge.net/2011/09/desktop-and-mobile-liferay-theme/">great HTML5Goodness responsive</a> theme. The main navigation menu was easy to do since there is a method to iterate over first level pages. However, when I tried to do the same with the footer menu I couldn&#8217;t find an easy and clean way to do it. I wanted to put standard links in the footer menu as the Terms of Use, the Privacy Policy and so on in the footer menu but I didn&#8217;t know how to organize this stuff in Liferay CMS so I could retrieve them back easily. I thought about using a portlet for the footer but I think that&#8217;s not the way to do it since that would affect the portlets layout for all the pages. So I added some variables in the XML that describes the theme and hardcoded the links there. At least I don&#8217;t have to change the theme code if we change any of those links.</p>
<p>About the portlets, we needed to write a portlet that pulls the content from an external service via REST calls and render it nicely using some kind of templates. These were the attempts I made and my conclusións:</p>
<ul>
<li><strong>Portlet written in Java</strong>: this was the obvious choice. The advantages was full access to Liferay API and easyness to integrate the portlet with the SDK stanrdard procedures. The disadvantages were, well, it has to be written in Java. We are far less productive in Java that with other languages. Just for making an HTTP request is quite involved. Hopefully Liferay has APIs for making this easier.</li>
<li><strong>Portlet written in Javascript</strong>: This looked promising and was easy to setup, the problem was the importPackage and importClass functions were not available from the Rhino environment. This made Javascript just a toy language in Liferay since the language itself has no useful standard library and it needs to leverage the net or filesystem or any other calls to the runtime it runs on. This make javascript a very integrable language but also a very dependent language. If we can&#8217;t call Liferay API from Javascript and there are no network functions in the language itself we can&#8217;t use it for our purposes.</li>
<li><strong>Portlet written in Python</strong>: Our last try was writting the portlet in Python. First we had to update the Jython jar that was included in Liferay since it was a little bit old. Then we added the <a href="http://opensource.xhaus.com/projects/show/jyson">jyson</a> jar to the jython jar itself to have support for json parsing. We also used Liferay Network APIs since we couldn&#8217;t import urllib2 from Python. Finally we even managed to use the Python debugger (PDB) by running Tomcat in the foreground. (bin/catalina.sh run)</li>
</ul>
<p>One important thing when writing portlets with a scripting language like Python or Javascript is that Liferay will concatenate all your modules into a single big file before running it in the scripting engine (jython or rhino, in our case). This is important to know when reading errors information where the line numbers is not always what we expect. In Python, we can avoid this behavior by changing the PYTHONPATH dinamically at runtime (at the beginning of our script) and then, importing our regular modules will work again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2011/10/09/first-impressions-with-liferay/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PyCON 2011 (Part 3)</title>
		<link>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pycon-2011-part-3</link>
		<comments>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-3/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 02:17:22 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Viajes]]></category>
		<category><![CDATA[Yaco]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=332</guid>
		<description><![CDATA[After the big conference days the sprints days started. I was surprised by how many people actually stayed for the sprints. There were literally docens of people hacking together grouped by projects. It&#8217;s amazing how passionate are some people about programming and how they enjoy sharing this with each other. That includes me, of course. [...]]]></description>
			<content:encoded><![CDATA[<p>After the big conference days the sprints days started. I was surprised by how many people actually stayed for the sprints. There were literally docens of people hacking together grouped by projects. It&#8217;s amazing how passionate are some people about programming and how they enjoy sharing this with each other. That includes me, of course.</p>
<p>I&#8217;ve been at the PySAML2 sprint with Roland Hedberg and a couple of guys from Zeomega: Baiju M and Chris Austin. It has been a real pleasure to work with this gang. During the nights I hanged out with them and also Brad Allen and other guys from the Texas Python group.</p>
<div id="attachment_335" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110314_102929.jpg"><img class="size-medium wp-image-335" title="SAML2 fast course" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110314_102929-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">Roland teaching SAML to the Zeomega guys</p></div>
<p>We managed to clean a lot of stuff at <a href="http://packages.python.org/pysaml2/html/" target="_self">PySAML2</a>, to release a <a href="http://pypi.python.org/pypi/pysaml2/0.2.1" target="_self">new version</a>, to improve the <a href="http://pypi.python.org/pypi/djangosaml2/0.1.0" target="_self">djangosaml2</a> package and to start making a Zope2 product for it.</p>
<div id="attachment_336" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110315_202731.jpg"><img class="size-medium wp-image-336" title="SAML Sprint" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110315_202731-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">Baiju and me are sprinting, don&#39;t you see?</p></div>
<p>One of these nights we went to a place where there were some good jazz music live. Ireally enjoyed the food, the music and the company of Chris and Baiju.</p>
<p>Today I did some tourism with Baiju and we went to the Atlanta Aquarium and the museum about Coca Cola. I did knew Baiju before since I translated his great book about the Zope Component Architecture but I never meet him in real life. He is a very good developer but also a really nice person. I&#8217;m glad I got to spend some time with him.</p>
<p>I&#8217;ve also meet other people here at PyCON. Here is just a brief list, sorry if I miss somebody:</p>
<ul>
<li>Jeff Rush, a consultant and Zope lover. Very nice guy.</li>
<li>Laurens Van Houtven, my roommate and a cool guy that hacks on the Twisted project and has different slepping habbits than me <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
<li>Sylvia Candelaria, a very smart lady who knows about free software, linguistics, Spain, India and a whole lotta more things. I just talked to her during a lunch but she just blowed my mind with her wisdom.</li>
<li>Ralph Bean, a guy who was working on an open goverment website during the sprints. He was interested on my work on SAML stuff</li>
<li>Luke Macken, a Fedora hacker</li>
<li>Jordan Sissel, a guy who works for <a href="http://www.loggly.com/" target="_self">loggly</a>a nice service about logging with very cool stickers.</li>
</ul>
<p>Other people I met but I can&#8217;t recall their names include people from <a href="http://bitbucket.org" target="_self">bitbucket</a>, from <a href="http://eldarion.com/" target="_self">eldarion</a>, from <a href="http://linode.com" target="_self">linode</a>, and many more!</p>
<p>Well, I guess that&#8217;s all I have to say about PyCON 2011 but I&#8217;m probably forgetting lots of things since it has been a very exciting week for me. I hope I can make it next year at <a href="http://us.pycon.org/2012/" target="_self">Santa Clara</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PyCON 2011 (Part 2)</title>
		<link>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pycon-2011-part-2</link>
		<comments>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-2/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 01:41:00 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Viajes]]></category>
		<category><![CDATA[Yaco]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=317</guid>
		<description><![CDATA[The second day of the PyCON conference started with a talk by the Dropbox guys. The first half of it was not really interesting but things go better on the second half when they started to explain the technical bits. Then Guido was interviewed and answered some questions that the community had elaborated for him. [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_321" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_074055.jpg"><img class="size-medium wp-image-321" title="Welcome to PyCON!" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_074055-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">It was 8am and I was ready for more talks!</p></div>
<p>The second day of the PyCON conference started with a talk by the Dropbox guys. The first half of it was not really interesting but things go better on the second half when they started to explain the technical bits. Then Guido was interviewed and answered some questions that the community had elaborated for him. One of the things he said is that Python 3 is closer than you think. I can tell he is right since many sprints at PyCON were about porting existing libraries to Python 3 and there is a general momentum going in that direction. Then they gave him a big cake representing the 20th birthday of the language.</p>
<p><iframe src="http://player.vimeo.com/video/21137176" width="400" height="265" frameborder="0"></iframe></p>
<p>PyCON moment where Guido is given a big cake representing the 20th python birthday</p>
<p>Then <a href="http://us.pycon.org/2011/schedule/presentations/246/" target="_self">I learned</a> about the new Selenium 2 and that it doesn&#8217;t need the ugly selenium-remote-control if you just run it on your own machine so that becomes much easier to use. The speaker was showing how to write tests using the python client library and it looked very very good.</p>
<p>After that talk I went to the <a href="http://us.pycon.org/2011/schedule/presentations/165/" target="_self">zc.buildout talk</a> where Jim Fulton explained how they deploy python projects based on buildout on Redhat based systems. Something very similar to what we do at Yaco. On the reasons they do this is because Zope Corporation hosts their own applications so their sysadmin department and their development department need to play well with each other. He explained how the have two different buidouts for each application: one for the application itself and a different one for its configuration. You can read more about his great talk at <a href="http://www.riversnake.com/pycon2011/full/" target="_self">http://www.riversnake.com/pycon2011/full/</a> or, if you are in a hurry, just check out his <a href="http://www.riversnake.com/pycon2011/" target="_self">slides</a></p>
<div id="attachment_322" class="wp-caption aligncenter" style="width: 234px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_112243.jpg"><img class="size-medium wp-image-322" title="Zope Pope" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_112243-224x300.jpg" alt="" width="224" height="300" /></a><p class="wp-caption-text">Jim Fulton speaking about zc.buildout</p></div>
<p>Then I went to the talk <a href="http://en.wikipedia.org/wiki/Alex_Martelli" target="_self">Alex Martelli</a> gave: <a href="http://us.pycon.org/2011/schedule/presentations/88/" target="_self">API design anti-patterns</a>. and these are some of the things I learned:</p>
<ul>
<li>You better have a API for your software because you are going to need it sooner or later. Otherwise programmers are going to start using your applications in very nasty ways you can&#8217;t even predict.</li>
<li>APIs don&#8217;t just grow up magically, you have to deeply thing about them. It&#8217;s harder to change an API than to change the user interface of your software because the consumers of the former (programms) are so much less flexible than the consumers of the later (humans)</li>
<li>A good way to design an API is to use it by yourself in your own software. This forces you to think what&#8217;s the main thing that my program does and what the absolute minimum amount of features that should go into the core. I believe we are doing the right thing here in <a href="http://www.merengueproject.org/" target="_self">Merengue</a> <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
<p>After that, I went to the <a href="http://us.pycon.org/2011/schedule/presentations/140/" target="_self">talk about http libraries in Python</a>. It was given by a Mercurial guy who did a very good analysis of how bad all Python http libraries are except for pycurl, which is very difficult to use. That&#8217;s why he wrote <a href="http://code.google.com/p/py-nonblocking-http/" target="_self">his own library</a> for this job and I think it is very good if you need some advanced http features and a very fast library.</p>
<p>To finish the day I went to Tarek&#8217;s talk bout <a href="http://us.pycon.org/2011/schedule/presentations/81/" target="_self">distutils 2</a> and I listened exceited about the state of this project and how it is going to make our lifes so much easier. Distutils 2 is going to be part of Python 3.2 and you will be able to use it as a separated module starting with Python 2.4! There are only two problems to be solved: it is not finished yet (this is easy, just help him!) and it won&#8217;t support all the things that setuptools does, like entry_points among other things. We will need some other library for this since there a bunch of us that uses these features. By they way, I&#8217;m the one that ask Tarek about entry_points at the end of his talk. I agree with him that they should not be part of distutils2 but that does not solves the problem. We need a full replacement!</p>
<div id="attachment_327" class="wp-caption aligncenter" style="width: 234px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_165418.jpg"><img class="size-medium wp-image-327" title="Tarek Ziadé" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_165418-224x300.jpg" alt="" width="224" height="300" /></a><p class="wp-caption-text">Tarek is the man behind distutils2</p></div>
<p>That afternoon I went to an open space to talk about the future of the Zope community. After that I got to go for dinner with the Zope guys to a nice mediterranean restaurant. I was invited by <a href="http://www.zeomega.com/" target="_self">Zeomega</a> company and I enjoyed the dinner a lot. I&#8217;ve been reading and following some of these guys for a long time and it was very cool to talk to them face to face. By the way, I talked with Jim Fulton about Spain since he has been there recently and he liked it a lot.</p>
<div id="attachment_323" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_221052.jpg"><img class="size-medium wp-image-323" title="Zope dinner" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110312_221052-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">happiness = getMultiAdapter(zope, dinner)</p></div>
<p>Next day there were some more nice talks. One guy from <a href="http://www.threadless.com/" target="_self">Threadless</a> gave a very funny talk. Unfortunately my english is still not that good and I didn&#8217;t get all the jokes. After that the people from <a href="http://disqus.com/" target="_self">Disqus</a> gave a very interesting talk about their product and how they did it using python tools: celery (for asynchronous tasks), graphite (for monitoring), senty (for exception monitoring), coverage.py, pep8, pyflakes and may more. The only thing they didn&#8217;t like about Python is the current state of packaging, which I have to agree with.</p>
<p>After that I went to see the <a href="http://us.pycon.org/2011/schedule/presentations/154/" target="_self">co-routines</a> talk but I didn&#8217;t quite understand them yet. I&#8217;ll need some more reading because it looks like they are getting pretty big nowadays.</p>
<p>To end the conference days there was the poster session. I have to admit I didn&#8217;t have big expectations on this but I also have to admin that I was nicely surprised. There were lots of good posters and I discovered a bunch of really interesting projects:</p>
<ul>
<li><a href="http://askbot.org/en/questions/" target="_self">askbot.org</a> , a stackoverflow clone written in Python</li>
<li><a href="http://sourceforge.net/p/allura/home/" target="_self">Allura</a> , the code behind Sourceforge</li>
<li><a href="http://farmdev.com/projects/fudge/" target="_self">Fudge</a>, which is very cool for mock testing. For example if you need to test a software that makes http connections but you don&#8217;t really want to make them for testing. It&#8217;s monkey patching done right.</li>
<li><a href="http://openstates.sunlightlabs.com/" target="_self">Open States </a>, and open goverment initiative</li>
<li>There was a guy with a wheel chair doing some astonishing job with a kinect device. Sorry I don&#8217;t remember the name of his project <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </li>
</ul>
<div id="attachment_326" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110313_101058.jpg"><img class="size-medium wp-image-326" title="a11y poster" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110313_101058-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">You would not believe what this guy just did with a kinect and a lot of courage</p></div>
<p>By the way, PyCON does a marvelous job by recording all the talks and puting them online. So, in case you couldn&#8217;t come, <a href="http://pycon.blip.tv/posts?view=archive&amp;nsfw=dc" target="_self">just watch the  talks</a> They are worthy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PyCON 2011 (Part 1)</title>
		<link>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pycon-2011-part-1</link>
		<comments>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-1/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 00:05:11 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Viajes]]></category>
		<category><![CDATA[Yaco]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=295</guid>
		<description><![CDATA[This has been my first PyCON and I have to say it has been loads of fun. I&#8217;ve also learned a lot and meet some very nice guys. In a way or another now I feel like I&#8217;am part of a community I was an outsider before. I arrived to Atlanta last Wednesday and I [...]]]></description>
			<content:encoded><![CDATA[<p>This has been my first <a href="http://us.pycon.org/2011/" target="_self">PyCON</a> and I have to say it has been loads of fun. I&#8217;ve also learned a lot and meet some very nice guys. In a way or another now I feel like I&#8217;am part of a community I was an outsider before.</p>
<p>I arrived to Atlanta last Wednesday and I was impressed of how big the <a href="http://atlantaregency.hyatt.com/hyatt/hotels/index.jsp?null" target="_self">Hyatt</a> hotel was. Almost like a small city on its own.</p>
<p><iframe src="http://player.vimeo.com/video/21134385" width="400" height="265" frameborder="0"></iframe>
<p>This short video shows how huge this hotel is. It&#8217;s filmed from the 12th floor</p>
<p>I&#8217;m not used to this kind of hotels so I really enjoyed details like the elevators or the huge lobby <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  As I arrived quite late due to some issues about getting out of the gigantic airport the only thing I did that night was having dinner in the Hard Rock Cafe a couuple of blocks next to the hotel.</p>
<div id="attachment_310" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110310_173557.jpg"><img class="size-medium wp-image-310" title="Elevator control panel" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110310_173557-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">That&#39;s a bunch of floors!</p></div>
<p>But, anyway, next day I attended to a couple of tutorials, one about Django deployment which was really good and another one about python 3 differences with respect to python 2 which was pretty interesting too.</p>
<div id="attachment_304" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110310_090129.jpg"><img class="size-medium wp-image-304" title="Django tutorial" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110310_090129-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">The Django tutorial is about to start</p></div>
<p>Then next day (friday) the conference started. Very early in the morning my mind was blown away when I saw how many people there were in the keynote.</p>
<p><iframe src="http://player.vimeo.com/video/21134741" width="400" height="265" frameborder="0"></iframe>
<p>Look of the huge room where the PyCon 2011 keynote will take place</p>
<p>This video was shot 10 minutes before the keynote started. During the keynote there was not a single free seat.</p>
<p>The room was pretty big and it was full! Luckily Hilary Mason (bit.ly scientist) did a fantastic job and her talk was really interesting and inspiring. I liked how passionated did she talk about programming and that she believes that programming changes your internal brain structure so you think differently from other non programmers when approaching life&#8217;s problems. For good or for bad I think she&#8217;s right.</p>
<p>Then I went to a talk about distributed tasks with Celery because I though it was given by Celery author. But it was about how a photographer&#8217;s website used Celery to have success. It was nice but not what I expected. Then I moved into &#8220;Javascript for people who known Python&#8221; by Ian Bicking and it was a good talk, quite fast but good since I knew some of the stuff he was talking about. Even so, I learned a bit. After that talk I went to the &#8220;State of pylons/turbogears/repoze&#8221; talk and that was just a sneaky title to present the new big thing: <a href="http://pylonsproject.org/projects/pyramid/about" target="_self">Pyramid</a>. I really believe this is going to be a web framework to follow since it has inherited a big community and it has very well written and tested code and documentation. And by the way, the<a href="http://laflamme.storenvy.com/products/66831-pyramid-not-built-by-aliens-t-shirt" target="_self"> t-shirt is awesome</a> <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Later that day I attended to another not so exciting talk like &#8220;The development of python and you&#8221;. Then I went to couple of talks that I really enjoyed and would say were maybe the best talks of PyCON: &#8220;Pluggable Django Patterns&#8221; and &#8220;Reverse engineering Ian Bicking&#8217;s brain&#8221;. The first one explained how to write your Django application so others (or even you in another project) can reuse it seamlessly. You should look the talk by yourself because it has tons of little gems. Then the other talk was about understanding how virtualenv and pip (tools maed by Ian Bicking) works and was really really good. One of the things I discovered in this talk is the way pip can install regular distutils projects is by monkey patching their setup.py file or that at the end, pip&#8217;s core is just a hack around setuptools <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Then I moved into the PyPy talk which was quite boring to me and finally the lighting talks. Some were better than another but I specially liked the one about Qtile, a tiled window manager written in Python. The guy speaking was just hilarious.</p>
<p>I forgot to menion that I meet some old friends this day like <a href="https://launchpad.net/~salgado" target="_self">Guilherme Salgado</a> (from my days at <a href="http://www.async.com.br/en/" target="_self">Async</a>) and John Ehresman, from <a href="http://www.wingware.com/" target="_self">Wingware</a>. It was really nice to see them again and hear that they are doing pretty well.</p>
<p style="text-align: center;">
<div id="attachment_306" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110311_141059.jpg"><img class="size-medium wp-image-306 " title="John Ehresman and me" src="http://www.lorenzogil.com/blog/wp-content/uploads/2011/03/IMG_20110311_141059-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">The guy on the left is freaking awesome</p></div>
<p>As this post is already quite long I talk more about my PyCON experiences in a following post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2011/03/17/pycon-2011-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Protecting Mercurial repositories with repoze.who and repoze.what</title>
		<link>http://www.lorenzogil.com/blog/2010/11/27/protecting-mercurial-repositories-with-repoze-who-and-repoze-what/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=protecting-mercurial-repositories-with-repoze-who-and-repoze-what</link>
		<comments>http://www.lorenzogil.com/blog/2010/11/27/protecting-mercurial-repositories-with-repoze-who-and-repoze-what/#comments</comments>
		<pubDate>Sat, 27 Nov 2010 20:57:25 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Ordenadores]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=265</guid>
		<description><![CDATA[After months of planning and thinking about it we are starting to adding support for Mercurial at Yaco. It&#8217;s far from finished but it is already tested in a couple of projects. We used and still use Subversion for most of our projects and our workflow is really tied to it. When I started to [...]]]></description>
			<content:encoded><![CDATA[<p>After months of planning and thinking about it we are starting to adding support for <a href="http://mercurial.selenic.com/" target="_self">Mercurial</a> at <a href="http://www.yaco.es" target="_self">Yaco</a>. It&#8217;s far from finished but it is already tested in a couple of projects. We used and still use Subversion for most of our projects and our workflow is really tied to it.</p>
<p>When I started to thing about using Mercurial at Yaco I sketched up a list of things that needed to be done:</p>
<ol>
<li>Migrate to <a href="http://trac.edgewall.org/milestone/0.12" target="_self">Trac 12</a> since it has support for multiple repositories of different types. This is really important not only because you can see your Mercurial repos in Trac but because it allow us to migrate step by step. You can have a Subversion repository for the QA and graphic design people and one or more Mercurial repos for developers. Also it&#8217;s up to the project manager to decide wheter he wants to use Subversion or Mercurial. We don&#8217;t want to impose a technology when Subversion is just fine for many situations.</li>
<li>Add several hooks in different stages of a changeset lifecycle:
<ol>
<li>Before commit, check basic things about the quality of the code (pyflakes, pep8, pdb, &#8230;)</li>
<li>Before commit check that the message mentions one or more Trac tickets</li>
<li>After commit update one or more Trac tickets</li>
</ol>
</li>
<li>Serve the repositories via https and add a web interface to them. This mean adding authentication and authorization for them too.</li>
<li>Train our people to use the new system</li>
<li>Define common workflows for our development patterns</li>
</ol>
<p>Step 1 was done several months ago and we are really happy with Trac 12.</p>
<p>Step 2 was achieved using <a href="http://pypi.python.org/pypi/hghooks/" target="_self">hghooks</a> and <a href="http://pypi.python.org/pypi/yaco.hghooks" target="_self">hghooks.yaco</a>, a couple of python packages I wrote to suite this goal.</p>
<p>Step 3 is the reason of this post. More on this later.</p>
<p>We are between step 4 and 5 and right now and that is causing minor griefs among our developers <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So, let&#8217;s talk about authentication and authorization in the context of Mercurial repositories. Mercurial comes with a WSGI application for serving the repositories via HTTP called <a href="http://mercurial.selenic.com/wiki/HgWebDirStepByStep" target="_self">hgwebdir</a>. It&#8217;s pretty easy to setup and has a nice looking web interface with lots of cool features.</p>
<p>But we have a couple of problems with hgwebdir:</p>
<ul>
<li>It doesn&#8217;t handle autthentication at all. This is actually a feature, but we need to add some bits for this.</li>
<li>It reads authorization from a different file for each repository it handles. This authorization information does not have group support neither. This mean we need to duplicate a lot of information among repositories. Most of our developers have access to most of our repositories, while each customer has (read only) access just to the repositories related to his project.</li>
</ul>
<p>With Subversion we do LDAP authentication with an Apache module and use <a href="http://svnbook.red-bean.com/en/1.2/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authz.perdir" target="_self">mod_authz_svn</a> for authorization purposes. This last module is really good and it allows you to keep all your authorization information in a single file. Really convenient.</p>
<p>Besides that, we would like to experiment with web servers other than Apache like nginx or Cherokee so we don&#8217;t want to depend on Apache for authentication neither.</p>
<p>Our solution involves using <a href="http://docs.repoze.org/who/1.0/" target="_self">repoze.who</a> for authentication and <a href="http://what.repoze.org/docs/1.0/" target="_self">repoze.what</a> for authorization. These are great Python packages that allows you to build really flexible middleware stuff. repoze.who and repoze.what don&#8217;t do anything useful by their own but define a set of rules and components to interact with the users and applications. Then there are plugins for both packages that really do the authorization and authentication stuff. One nice thing about repoze is that it uses the WSGI standard heavily so it&#8217;s easy to integrate them with other WSGI applications like hgwebdir.</p>
<div id="attachment_276" class="wp-caption aligncenter" style="width: 410px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/11/onion.jpg"><img class="size-full wp-image-276 " title="WSGI middleware is like onion layers" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/11/onion.jpg" alt="" width="400" height="298" /></a><p class="wp-caption-text">WSGI middleware is like onion layers</p></div>
<p>We use <a href="http://code.gustavonarea.net/repoze.who.plugins.ldap/Using.html" target="_self">repoze.who.plugins.ldap.LDAPSearchAuthenticatorPlugin</a> for authentication. It connects to our LDAP server and check that the user and password entered by the user matches a user in our directory. The way the user enter his user and password is through authentication basic. repoze.who allows several other mechanisms but that one is fine for us.</p>
<p>Then for authorization we use the <a href="http://www.lorenzogil.com/projects/repoze.what.plugins.hgwebdir/" target="_self">repoze.what.plugins.hgwebdir</a> package that I wrote for our needs but trying to make it general enough so it can be used by other people. This plugin allows the system administrator to write all the repositories authorization information in a single file very similar to the one used by mod_authz_svn.</p>
<p>To put everything together we use a buildout that configures Mercurial, a nginx webserver and all the WSGI middleware and applications to serve the repositories.</p>
<p>Let&#8217;s see how our final WSGI application looks like:</p>
<pre>from optparse import OptionParser
import sys
from wsgiref.simple_server import make_server

import mercurial.util
import mercurial.dispatch

from mercurial.hgweb.hgwebdir_mod import hgwebdir

from repoze.who.plugins.basicauth import BasicAuthPlugin
from repoze.who.plugins.ldap import LDAPSearchAuthenticatorPlugin

from repoze.what.middleware import setup_auth

from repoze.what.plugins.hgwebdir.adapters import HgwebdirGroupsAdapter
from repoze.what.plugins.hgwebdir.adapters import HgwebdirPermissionsAdapter
from repoze.what.plugins.hgwebdir.adapters import get_public_repositories
from repoze.what.plugins.hgwebdir.middleware import protect_repositories

def add_auth(app, authz_file):
   # Defining the group adapters; you may add as much as you need:
   groups = {'all_groups': HgwebdirGroupsAdapter(authz_file)}

   # Defining the permission adapters; you may add as much as you need:
   permissions = {'all_perms': HgwebdirPermissionsAdapter(authz_file)}

   # repoze.who identifiers; you may add as much as you need:
   basicauth = BasicAuthPlugin('Yaco Hg repositories')
   identifiers = [('basicauth', basicauth)]

   # repoze.who authenticators; you may add as much as you need:
   ldap_auth = LDAPSearchAuthenticatorPlugin('ldap://ldap.yaco.es',
                                     'ou=People,dc=yaco,dc=es', returned_id='login')
   authenticators = [('ldap_auth', ldap_auth)]

   # repoze.who challengers; you may add as much as you need:
   challengers = [('basicauth', basicauth)]

   app_with_auth = setup_auth(
                         app,
                         groups,
                         permissions,
                         identifiers=identifiers,
                         authenticators=authenticators,
                         challengers=challengers)
   return app_with_auth

def make_app(hg_config, authz_file):
   original_app = hgwebdir(hg_config)
   secured_app = protect_repositories(original_app,
                         get_public_repositories(authz_file))
   return add_auth(secured_app, authz_file)
</pre>
<p>The main entry point here is the make_app function. It recieves two filenames, one for configuring the repositories themselves and one for the authorization stuff. As you can see we are adding a couple of layers to the hgwebdir application. The inner one deals with authorization and the outer one with authentication. We have to deactivate hgwebdir authorization support to make it work. Otherwise authorization is done by two different modules and it won&#8217;t work. To deactivate it we configure all of our repositories with this option:</p>
<pre>[web]
allow_push = *
</pre>
<p>By default hgwebdir allows read access to everybody and denies write access to everybody. We keep read access as hgwebdir defaults and add write access to everybody. repoze.what.plugins.hgwebdir will handle this stuff for us.</p>
<p>Now, to configure the authorization you just need to write a file like this:</p>
<pre>[groups]
group1 = lgs, mviera
group2 = john, peter

[repo1]
@group1 = rw

[repo2]
@group2 = rw
@group1 = r

[repo3]
* = r
@group1 = rw</pre>
<p>As I mentioned before, the syntax and semantics are very similar to the ones used in mod_authz_svn. One feature that is not possible with repoze.what.hgwebdir is specific authorization rules to some directories inside a repository.</p>
<div id="attachment_279" class="wp-caption aligncenter" style="width: 289px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/11/esquema-hgwebdir.png"><img class="size-medium wp-image-279" title="Final arquitecture" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/11/esquema-hgwebdir-279x300.png" alt="" width="279" height="300" /></a><p class="wp-caption-text">Final arquitecture</p></div>
<p>I hope everything is clearer with this last figure.</p>
<p</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/11/27/protecting-mercurial-repositories-with-repoze-who-and-repoze-what/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python deployment tips</title>
		<link>http://www.lorenzogil.com/blog/2010/10/29/python-deployment-tips/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-deployment-tips</link>
		<comments>http://www.lorenzogil.com/blog/2010/10/29/python-deployment-tips/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 22:07:05 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=239</guid>
		<description><![CDATA[In Yaco we&#8217;ve been working on improving our development and deployment process lately and I think it&#8217;s time we share our achievements and mistakes with everybody. Besides python and Django being our core tools, some of the key technologies that we use are buildout, nginx, uwsgi, rpm, fabric, openvz and proxmox. So it&#8217;s quite clear [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.yaco.es" target="_self">Yaco</a> we&#8217;ve been working on improving our development and deployment process lately and I think it&#8217;s time we share our achievements and mistakes with everybody. Besides <a href="http://www.python.org/" target="_self">python</a> and <a href="http://www.djangoproject.com/" target="_self">Django</a> being our core tools, some of the key technologies that we use are <a href="http://www.buildout.org/" target="_self">buildout</a>, <a href="http://nginx.org/" target="_self">nginx</a>, <a href="http://projects.unbit.it/uwsgi/" target="_self">uwsgi</a>, <a href="http://www.rpm.org/" target="_self">rpm</a>, <a href="http://www.fabfile.org/">fabric</a>, <a href="http://wiki.openvz.org/Main_Page" target="_self">openvz</a> and <a href="http://www.proxmox.com/" target="_self">proxmox</a>. So it&#8217;s quite clear that you need to know a bunch of things to accomplish something powerful. Or maybe not. Let&#8217;s see.</p>
<p>Before I start with the inner details of how all these buzzwords work together, let met introduce you the antisocial python development law:</p>
<h2><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/10/isolation.png"><img class="aligncenter size-medium wp-image-245" title="isolation" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/10/isolation-300x260.png" alt="isolation" width="300" height="260" /></a></h2>
<h2>isolation = k * repeatability</h2>
<p>Where k is a constant that is inversely proportional to the probability of you saying &#8220;It works on my machine&#8221;.</p>
<p>That&#8217;s it, the more isolate you are from the operating system the more easy is to repeat your environment. As a consequence the more you avoid using your system python and packages the easier your coworkers and deployment engineers will get your system up and runing. Let&#8217;s see why:</p>
<ul>
<li>By not making any assumption of what packages and libraries you have installed on your machine you are democratizing your team. Everybody has the same oportunities to see how the system fails.</li>
<li>Using your system python is a ticket to the deploy-this-on-the-very-old-production-server-nightmare rollercaster. It may work but it will probably not.</li>
<li>If one day is working and the next day is not and you swear your god you didn&#8217;t touch anything you may not be isolated enough and an update on your operating system or your build environment has changed without you noticing it. Reciprocally you will be able to upgrade your operating system more often without worries of breaking your projects.</li>
<li>No more lost hours debugging a crash just to realize that you didn&#8217;t run a service that you were supposed to run but you are not running because there are so many things you need to do by hand and you don&#8217;t have an automated script to do so that your brain collapses.</li>
</ul>
<p>Everybody has experienced the frustration feeling of not being able to reproduce a problem. So follow my advice and isolate yourself as much as you can.</p>
<p><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/10/wetcat.jpg"><img class="aligncenter size-medium wp-image-253" title="wetcat" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/10/wetcat-300x243.jpg" alt="wetcat" width="300" height="243" /></a></p>
<p>So you get it but the question is: how do I isolate myself from the scary, treacherous, evil system? Well, like in hospitals and nuclear stations there are several different levels of isolation, from safe, to super safe, to paranoid.</p>
<h3>Safe level Option A</h3>
<p>Just build your custom python by dowloading the tarball, uncompress it and do the configure, make and make install dance.</p>
<p><strong>Advantages</strong>: you don&#8217;t mess with the system, the system doesn&#8217;t mess with you. No more fear to upgrade your distro, nothing will break. No more fear to update a package you need, your desktop application won&#8217;t break. Another advantage is that you can do the same in the deployment server if its operating system is too old and you are stuck with python 2.4.<br />
<strong>Disadvantages</strong>: be careful when compiling your python or you will get a barebone executable with no support for a bunch of things like ssl, zip, bzip2, readline, &#8230; The solution is to install the development packages from your distro before compiling your python.</p>
<h3>Safe level Option B</h3>
<p>Use virtualenv with &#8211;no-site-packages and you will get a directory completely isolated from you system python.</p>
<p><strong>Advantages</strong>: very fast and cheap to get started since you don&#8217;t need to compile python. It actually uses your system python with all its features but without any of your system packages.<br />
<strong>Disadvantages</strong>: it still uses your system python so when you deploy you may find your server python is different. Deploy soon and you will avoid nasty surprises.</p>
<h3>Safe level Option C</h3>
<p>Use buildout with your system python. Use this option for a recently installed operating system while your site-packages is still clean.</p>
<p><strong>Advantages</strong>: easy to get started<br />
<strong>Disadvantages</strong>: you need to be very disciplinated in orde not to polute your system site-packages. For example, everytime you use easy_install or pip it will get dirty. Always install your dependencies through buildout.</p>
<h3>Super safe level</h3>
<p>Combine Safe level A or B with buildout. Now you can share your custom python or your virtualenv with different Django projects and nothing will get messy since all your dependencies will get installed inside buildout.</p>
<h3>Paranoid level</h3>
<p>Compile your python, use virtualenv and buildout. This is like having sex with two condoms and anticonception pills. Maybe not the most pleasure thing but certainly the safest.</p>
<p style="text-align: center;"><a href="http://www.hollow-hill.com/sabina/2009/04/oh_that_evoso_paranoid_all_the_time.html"><img class="aligncenter" src="http://www.hollow-hill.com/sabina/images/everyone-hates-paranoid.jpg" alt="" width="400" height="400" /></a></p>
<p>I&#8217;ve been pretty well with custom python and buildout, e.g. super safe level but sometimes, under the right circunstances, I&#8217;ve played paranoid level. Some people in my office prefer virtualenv and buildout. It doesn&#8217;t matter as long as you understand the risks and are consistent.</p>
<p>The nice thing about using buildout is that it takes care of your python dependencies and other parts of your build automatically, for you. So having your development environment set up is a matter of minutes and it&#8217;s pretty automated.</p>
<p>So, what does our standard buildout do for us? A bunch of things:</p>
<ol>
<li>Download a specific Django version and put it on your PYTHONPATH</li>
<li>Download all your python dependencies and put them on your PYTHONPATH</li>
<li>Download and compile uwsgi</li>
<li>Download and compile nginx</li>
<li>Set nginx and uwsgi to work together with your Django project</li>
<li>Set supervisord to run and monitor everything</li>
</ol>
<p>And all this stuff is done automatically, with a couple of commands. I think it&#8217;s a pretty advanced deployment that you can have in a few minutes. Our buildout.cfg file looks like this:</p>
<pre>[buildout]
parts =
      python
      django
      uwsgi-download
      uwsgi-compilation
      nginx
      nginx-conf
      yourproject
      zc.sourcerelease
      releaser
      service

develop = .
eggs = yourproject

[python]
recipe = zc.recipe.egg
interpreter = py
eggs = ${buildout:eggs}

[django]
recipe = djangorecipe
version = http://code.djangoproject.com/svn/django/branches/releases/1.2.X
project = yourproject
settings = settings
wsgi = true
eggs = ${buildout:eggs}

[uwsgi-download]
recipe = gocept.download
url = http://projects.unbit.it/downloads/uwsgi-0.9.5.4.tar.gz
strip-top-level-dir = true
md5sum = 822c846484dcd6cc9f6d79118ed7e97a

[uwsgi-compilation]
recipe = yaco.recipe.uwsgi
uwsgi-location = ${uwsgi-download:location}

[uwsgi-conf]
socket-path = ${buildout:directory}/var/run/uwsgi.sock
pid-path = ${buildout:directory}/var/run/uwsgi.pid
log-path = ${buildout:directory}/var/log/uwsgi.log
python-path = ${buildout:directory}/${django:project}/
wsgi-path = ${buildout:bin-directory}/django.wsgi

[nginx]
recipe = zc.recipe.cmmi
url = http://nginx.org/download/nginx-0.8.34.tar.gz
extra_options =
    --conf-path=${buildout:directory}/etc/nginx/nginx.conf
    --error-log-path=${buildout:directory}/var/log/nginx-error.log
    --http-log-path=${buildout:directory}/var/log/nginx-access.log
    --pid-path=${buildout:directory}/var/run/nginx.pid
    --lock-path=${buildout:directory}/var/lock/nginx.lock
    --add-module=${uwsgi-download:location}/nginx/

[nginx-conf]
recipe = collective.recipe.template
input = ${buildout:directory}/templates/nginx.conf.in
output = ${buildout:directory}/etc/nginx/nginx.conf
port = 8080
project_location = ${buildout:directory}/${django:project}
django_location = ${django:location}
uwsgi_sock_path = ${uwsgi-conf:socket-path}
uwsgi_location = ${uwsgi-download:location}

[supervisor]
recipe = collective.recipe.supervisor
port = 9080
user = admin
password = admin
pidfile = ${buildout:directory}/var/run/supervisord.pid
serverurl = http://localhost:${supervisor:port}
plugins = superlance
programs =
    0 nginx (stderr_logfile=NONE stdout_logfile=${buildout:directory}/var/log/nginx-error.log) ${nginx:location}/sbin/nginx [ -c ${buildout:directory}/etc/nginx/nginx.conf ] true
    1 uwsgi (stderr_logfile=NONE stdout_logfile=${uwsgi-conf:log-path}) ${buildout:bin-directory}/uwsgi [ -p 1 -C -A 4 -m -s ${uwsgi-conf:socket-path} --wsgi-file ${uwsgi-conf:wsgi-path} --pythonpath ${uwsgi-conf:python-path} --pidfile ${uwsgi-conf:pid-path} ] true</pre>
<p>Some notes about this file:</p>
<ul>
<li>You should replace the string &#8216;yourproject&#8217; with the name of your Django project</li>
<li>The python part is useful to have a custom python interpreter in bin/py with the PYTHONPATH configured the same as your Django project. I use it to debug import errors.</li>
<li>In the Django part it will create yourproject if it does not already exist</li>
<li>The yaco.recipe.uwsgi recipe is needed in the uwsgi-compilation part because no matter how good uwsgi is, its build system is really bad and hard to integrate with this kind of tools.</li>
<li>Note that the supervisord web interface will be on port 9080 and the nginx serving your Django on port 8080</li>
<li>You still need the nginx.conf.in template that the nginx-conf part uses but it&#8217;s just a simple nginx configuration file with a couple of string substitutions.</li>
</ul>
<p>Alright, before running the bootstrap thing, make sure you are a good Python citizen and you have the common project metadata files like README, CHANGES, LICENSE and more important, the setup.py distutils/setuptools file. Buildout is going to need it. You should put your python dependencies in the install_requires argument of the setup function. Something like this:</p>
<pre>import os
from setuptools import setup, find_packages

def read(*rnames):
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()

setup(
    name='yourproject',
    version='0.1.0',
    url='http://url-to-your-project',
    license='GPL',
    description='...',
    long_description=(read('README') + '\n\n' + read('CHANGES.txt')),
    author='Your Name ',
    classifiers=[
        'Development Status :: early stages',
        'Framework :: Django',
        'Intended Audience :: Developers',
        'License :: GPL',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        ],
    packages=find_packages(yourproject'),
    package_dir={'': yourproject'},
    install_requires=[
        'distribute',
        'django-piston',
        'feedparser',
        'South',
        'MySQL-python',
        'python-dateutil',
        'httplib2',
        'django-celery',
        ],
)</pre>
<p>As you can see I have a bunch of dependencies in my example.</p>
<p>Now do the buildout dance:</p>
<pre>python bootstrap.py --distribute
bin/buildout</pre>
<p>And make sure you are not using your system python in the first command or a kitten will get killed.</p>
<p><a href="http://www.bobpitch.com/anon/Mrs_Grouty_sad%20kitten.jpg"><img class="aligncenter" src="http://www.bobpitch.com/anon/Mrs_Grouty_sad%20kitten.jpg" alt="" width="288" height="384" /></a></p>
<p>After a few minutes you will be able to run the following commands:</p>
<pre>bin/django syncdb     # to create your database tables
bin/django runserver  # to run your development server
bin/supervisord       # to run your production lighting fast server</pre>
<p>And the best thing is that once you have this all setup, your team partners will have all of this for free and all of you will have exactly the same environment. You won&#8217;t hear <em>&#8220;It works on my computer&#8221;</em> again.</p>
<p style="text-align: center;"><a href="http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html"><img class="aligncenter" src="http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128776ff992970c-pi" alt="" width="200" height="193" /></a></p>
<p>All this is good and pretty fast to deploy but we want more. How about creating a source distribution in a tarball that we can copy to our remote server and run with all our dependencies frozen? You asked it, you got it! Add this to your buildout:</p>
<pre>parts += releaser

[releaser]
recipe = zc.recipe.egg:script
eggs = zc.sourcerelease</pre>
<p>Now commit that change and run these commands:</p>
<pre>bin/buildout
bin/buildout-source-release hhttps://your-svn-repository-url/path/to/your/project buildout.cfg --name yourproject-0.1.0</pre>
<p>After a couple of minutes you will have a file called yourproject-0.1.0.tgz with everything your project needs inside. Go to the server, untar it and run these commands:</p>
<pre>python install.py bootstrap
python install.py</pre>
<p>Just make sure the python on your server is the same version as the python you used to create the source release. This will deploy the buildout without connecting to the network to download anything since it has everything it needs.</p>
<p>Pretty neat, huh? Well, we really want more. How about a rpm package or a debian one? Having your project in your server operating system package is good for updates since it will respect the changes that you did to your configuration files and the system administrator will be very happy.</p>
<p>To get the rpm you just need to write a simple spec that pick the yourproject-0.1.0.tgz file and run the install.py in a specific location. I even build a custom python inside the rpm file to avoid server incompatibilities. I starting to think about creating two separate packages, one for the python and one for the project and make the later depends on the former. That would be much cleaner, but for now the first option does the job perfectly. I&#8217;ve never written a spec file before but I must admit it was much easier than I thought. Sadly, I can&#8217;t say the same about Debian packages. But the important thing is that the idea is the same.</p>
<p>So, that&#8217;s how we build and deploy our final solutions to our clients and we and they are very happy with the outcomes. But wait, there is more. How about nighty builds? Building and deploying rpm packages just for the nighty builds is quite heavy so that&#8217;s where we are using Fabric.</p>
<p><a href="http://twitter.com/#!/mviera" target="_self">Manuel Viera</a> has created a system that roughly does the following:</p>
<ol>
<li>Creates a OpenVZ virtual machine programatically from a CentOS 5.5 or Debian 5.0 template</li>
<li>Configure its network programmatically too</li>
<li>Execute a fabric script that:
<ol>
<li>Connects to the fresh virtual machine through ssh</li>
<li>Install a bunch of operating system packages that will be needed to run a buildout. These packages are listed in a file that every project has: deployment.cfg</li>
<li>Creates a user and a group</li>
<li>With that user, fetch, configure, compile and install a custom python. The version of this python is also in the deployment.cfg file.</li>
<li>Copy the project files to the virtual machine or, in some cases, just do a checkout/clone</li>
<li>Run the bootstrap and buildout dance with the python it just compiled.</li>
<li>Run the test suite and fetch the results</li>
<li>Optionally, creates the source distribution and the rpm package</li>
</ol>
</li>
<li>Destroy the virtual machine</li>
</ol>
<p>And we are on the process to run this algorithm for every project, every night. I bet that will give us another point in the <a href="http://www.joelonsoftware.com/articles/fog0000000043.html" target="_blank">Joel Test</a> <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Kudos to Manu and his mighty powers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/10/29/python-deployment-tips/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Managing email, the Unix way</title>
		<link>http://www.lorenzogil.com/blog/2010/08/21/managing-email-the-unix-way/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=managing-email-the-unix-way</link>
		<comments>http://www.lorenzogil.com/blog/2010/08/21/managing-email-the-unix-way/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 15:20:49 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Ordenadores]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=211</guid>
		<description><![CDATA[Introduction I&#8217;ve been using Evolution, the mail client, since 2000. I think it was the first Linux program along with Netscape that I remember using on a daily basis. What can I say about a program I&#8217;ve used for more than 10 years? Well I&#8217;m very grateful to it and I hope its development continues [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>I&#8217;ve been using Evolution, the mail client, since 2000. I think it was the first Linux program along with Netscape that I remember using on a daily basis. What can I say about a program I&#8217;ve used for more than 10 years? Well I&#8217;m very grateful to it and I hope its development continues and it gets better and better every day. But now it&#8217;s time for a change.</p>
<h2>Motivation</h2>
<p>There are two main reasons I wan to switch from Evolution to Mutt:</p>
<ul>
<li><strong>Speed</strong>. Evolution is now much faster than it used to be but when you have 5 Gigabytes of email it starts to behave slowly.</li>
<li><strong>Knowledge</strong>. As an engineer I don&#8217;t feel comfortably using something I don&#8217;t totally understand and I even feel embarrased about my (lack of) understanding of email, something that I use (dammit, sometimes I even depend on) every day. That&#8217;s why switching to Mutt makes sense. Its take on email forces you to do it the Unix way. This mean using several small programs together to accomplish your task and by dividing the task into small pieces you understand the big picture much better. Now I can tell the difference between a MTA, a MUA  and a MDA.</li>
</ul>
<h2>General architecture</h2>
<div id="attachment_216" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/mail-architecture.png"><img class="size-medium wp-image-216" title="Genereal architecture" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/mail-architecture-300x273.png" alt="General architecture" width="300" height="273" /></a></dt>
</dl>
</div>
<p>As you can see in the above figure, there are quite a lot of small programms (blue boxes and red circle) cooperating to deliver my mail for me. I&#8217;ll try to explain what each of these ones do and how to configure them in the following sections.</p>
<p>As there are a lot of configuration files involved I won&#8217;t paste them here but point to the <a href="http://bitbucket.org/lgs/dotfiles/src">Mercurial repository</a> where I keep them versioned.</p>
<h2>Step 1. Fetching email: getmail</h2>
<p><a href="http://pyropus.ca/software/getmail/">getmail</a> is a MRA or Mail Retrieval Agent. Its main task is fetch your email from a POP3 or IMAP server. Unless you have a fixed IP and you run your own SMTP and IMAP/POP3 server you probably have your email delivered to your ISP or company&#8217;s own servers.</p>
<p>Another popular MRA is <a href="http://fetchmail.berlios.de/">fetchmail.</a> I use getmail because it&#8217;s way simpler to configure and whetever I have to decided between two programs and one of them is written in python I go for that one. I&#8217;m very comfortable with Python so if I ever need to change something or go to the source to understand what&#8217;s going on, that way is easier for me.</p>
<p>Anyway, this is <a href="http://bitbucket.org/lgs/dotfiles/src/tip/.getmail/getmailrc">my configuration file for getmail</a>. You have to call the getmail program every time you want to download email from your IMAP/POP3 server. A typical run looks like this:</p>
<pre>[lgs@ticotico ~]$ getmail
getmail version 4.20.0
Copyright (C) 1998-2009 Charles Cazabon.  Licensed under the GNU GPL version 2.
SimpleIMAPSSLRetriever:lgs@correo.yaco.es:993:
Enter password for SimpleIMAPSSLRetriever:lgs@correo.yaco.es:993:  *******
  0 messages (0 bytes) retrieved, 0 skipped</pre>
<p>As this is a very tedious task I have set up a cron task that runs every 5 minutes. Yes, I&#8217;m that anxious about email <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  But the problem is that if I put this in a cron job it will ask for the password every time it runs. One solution is to put the password in the getmailrc configuration file but I don&#8217;t feel like sharing my password with the whole world and I really want to keep my configuration files in Bitbucket. So the other solution is to use <a href="http://en.wikipedia.org/wiki/Expect">expect</a>. This is a common Unix tool for manipulating other programs. This is my getmail-no-password expect script:</p>
<pre>#!/usr/bin/expect -f

set timeout 600
spawn /usr/bin/getmail
expect -exact "Enter password for SimpleIMAPSSLRetriever:lgs@correo.yaco.es:993:  "
send -- "put-your-real-password-here\r"
expect eof
exit</pre>
<p>So expect will call getmail and as soon as the &#8220;Enter password &#8230;&#8221; phrase goes to stdin it will send my real password, followed by the &#8216;\r&#8217; character. One minor issue is I have to give expect a timeout. After this time has passed expect will stop running. 600 seconds (10 minutes) is more than enough for running this script in my cron job but the first time I synchronize with my IMAP server it takes way more time than this so I just run getmail and enter my password manually instead of using the getmail-no-password expect wrapper.</p>
<p>This script is not in my Bitbucket repository for obvious reasons <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>This is my crontab for fetching email:</p>
<pre>*/5 * * * * /home/lgs/bin/getmail-no-password &gt; /dev/null</pre>
<p>Note that I redirect stdout to /dev/null but not stderr so cron will email me if something goes wrong with getmail or the expect wrapper script.</p>
<h2>Step 2. Filtering email: maildrop</h2>
<p>As soon as getmail gets the mail it can save it to the final destination, e.g. my Maildir directory, or we can send it to the MDA (Mail Delivery Agent) to do more powerful things. In my case I went for <a href="http://www.courier-mta.org/maildrop/">dropmail</a> but as always there are other options like <a href="http://www.procmail.org/">procmail</a>. Procmail is more mature in the Unix world but I like dropmail syntax better.</p>
<p>getmail fetches an email message from the server and then run dropmail with the mail message as the argument. As you can see in my <a href="http://bitbucket.org/lgs/dotfiles/src/tip/.mailfilter">dropmail configuration file (called .mailfilter)</a>, I do several things with a mail message:</p>
<ul>
<li>Pipe it to through reformail to add a Lines header, which is useful in Mutt.</li>
<li>Pipe it to spambayes (sb_filter) to add antispam features to my mail system. More on this later</li>
<li>Send a notification to my GNOME desktop in case the message is not spam. More on this later.</li>
<li>Filter the message and store it in one of my mail folders depending on several regular expression rules that match agains some header values of the mail message.</li>
</ul>
<h2>Step 3. Anti spam: spam bayes</h2>
<p>The typical antispam software in Unix system is <a href="http://spamassassin.apache.org/">spamassassin</a> but I use <a href="http://spambayes.sourceforge.net/">Spam Bayes</a> because of several reasons:</p>
<ul>
<li>I setup spambayes in the previous company I worked for and I was very happy with its results.</li>
<li>In my current company, spamassassin is used and it&#8217;s not very effective. This may be a configuration issue.</li>
<li>Spamassassin eats a lot of cpu.</li>
<li>Did I mention that spam bayes is written in python?</li>
</ul>
<p>The way spam bayes work is quite simple: first you need to train it giving a bunch of spam messages and a bunch of ham (ham is the opposite of spam, in other words, good mail) messages. You do it with the following command line:</p>
<pre>sb_mboxtrain.py -g .inbox/ -s .spam/</pre>
<p>This will create a hammie.db database in Berkeley format. Now you should write a configuration file to tell spam bayes where this database file is located so it can use it to filter spam messages when called from dropmail. Here is <a href="http://bitbucket.org/lgs/dotfiles/src/tip/.spambayesrc">my spambayes configuration file</a>.</p>
<p>If you remember my maildrop configuration file this was the line that calls spam bayes:</p>
<pre>xfilter "python -W ignore:::: /usr/bin/sb_filter.py -d ~/.hammie.db"</pre>
<p>What&#8217;s that -W ignore::: argument to Python? Well spam bayes spit some warnings when run under python 2.5 or 2.6 and that&#8217;s not good for maildrop because python writes the warnings to stderr and maildrop thinks there is a problem with that process and aborts the mail delivery. So by calling python with the -W ignore::::: argument we tell it to keep the warnings quiet and don&#8217;t write them to stderr. I hope spam bayes get updated soon and I can remove this hack.</p>
<p>The good thing about spam bayes is that it can learn with your help. Any time it fails when filtering a message you can retrain it fix its behaviour. By the way, all that spam bayes does is adding some headers to the message and then you need to add some rules to your maildrop configuration file to put the message where it belongs. The interesting thing is that sometimes a message is not spam or ham because spam bayes is not sure. You can store these messages in a folder different than the spam folder so you can look it more frequently and teach spam bayes with them.</p>
<h2>Step 4. Reading and composing emails: mutt</h2>
<p>From all text based email clients mutt is the most popular. <a href="https://twitter.com/herraiz">Israel Herraiz</a> told me about <a href="http://sup.rubyforge.org/">Sup</a> and it looks very promising. I think I&#8217;ll give it a try pretty soon. But for now, I&#8217;ll stick to Mutt for a while.</p>
<p>Mutt is the most complex software from all the programs I mentioned in this post, so <a href="http://bitbucket.org/lgs/dotfiles/src/tip/.muttrc">its configuration file</a> is the biggest one. Hopefully I have added enough comments to make it easier to understand the options that I use.</p>
<h2>Step 5. Sending emails: msmtp</h2>
<p>The last step consist in sending emails. Until recently Mutt didn&#8217;t know how to talk SMTP, the protocol for sending emails and due to popular demand that feature has been added. But in keeping the original Mutt spirit and thus, the Unix way of using one program for each task, I decided to go for <a href="http://msmtp.sourceforge.net/">msmtp</a>, a small client for sending emails. As always, there are plenty of options in Linux land but I think msmtp does a very decent job. As usual, you can check my <a href="http://bitbucket.org/lgs/dotfiles/src/tip/.msmtprc">msmtp configuration file</a> in Bitbucket. Remember to set the &#8220;set sendmail=&#8221;/usr/bin/msmtp&#8221; option in Mutt.</p>
<p>In these days full of spam it&#8217;s usual that your SMTP server ask you for authorization information unless you are in the same private network. As in the getmail case I didn&#8217;t want to write my password in plain text in the msmtp configuration file. Fortunately msmtp has support for GNOME (and MacOS X) keyring so you can simple store your password in the safe keyring of your operating system and msmtp will pick it up for you there. The only issue is that you need to be logged in a graphical GNOME session in order have access to the keyring.</p>
<p>Anyway, to store your password in the keyring use the following command changing your username and server for your own values:</p>
<p>./msmtp-gnome-tool.py &#8211;set-password &#8211;username lgs &#8211;server correo.yaco.es</p>
<p>Unfortunately you need the source code of msmtp to use this command since it is not in the msmtp rpm package that I installed in my Fedora system. So go ahead and grab it. Once you untar it, it should be in the msmtp/scripts/msmtp-gnome-tool/msmtp-gnome-tool.py</p>
<h2>Bonus track 1: notifications</h2>
<p>Mutt is great and all but one thing I miss from Evolution is GNOME notifications every time a new mail reaches my inbox. Well, with such flexible system as the one I built, that&#8217;s not difficult to have. Just add this line to the maildrop configuration file:</p>
<pre>xfilter "python /home/lgs/bin/email_notificator.py"</pre>
<p>I added after storing spam in the spam folder since I don&#8217;t want to be notified when spam arrives.</p>
<p>Here is the content of my email_notificator.py script:</p>
<pre>import email
import subprocess
import sys

if __name__ == '__main__':
    data = sys.stdin.read()

    message = email.message_from_string(data)
    from_ = 'Unknown from'
    if 'From' in message:
        from_ = message['From']

    subject = 'Unknown subject'
    if 'Subject' in message:
        subject = message['Subject']

    cmd = ['/usr/bin/notify-send', '-u', 'critical', '-t', '5000',
           '-i', '/usr/share/icons/gnome/48x48/actions/mail_new.png',
           '%s' % from_, '%s' % subject]
    subprocess.call(cmd, env={'DISPLAY': ':0.0'})
    print data</pre>
<p>No rocket science here. In the following screenshot you can see the script in action:</p>
<div class="mceTemp mceIEcenter">
<dl id="attachment_229" class="wp-caption aligncenter" style="width: 458px;">
<dt class="wp-caption-dt"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/email-arriving.png"><img class="size-full wp-image-229 " title="Notification of email arriving" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/email-arriving.png" alt="Notification of email arriving" width="448" height="146" /></a><p class="wp-caption-text">Notification of email arriving</p></div>
<h2>Bonus track 2: logs rotation</h2>
<p>Several programs of my email ecosystem log information to different files. As always you should rotate your logs if you don&#8217;t want your hard disk to become full really fast. Just add a <a href="http://bitbucket.org/lgs/dotfiles/src/tip/logrotate.conf">configuration file for log rotate</a> as mine and add a line to your crontab like this one:</p>
<pre>0 9 * * * /usr/sbin/logrotate /home/lgs/mail_logs/logrotate.conf --state=/home/lgs/mail_logs/logrotate.status</pre>
<h2>Bonus track 3: reading mails from my android device</h2>
<p>One of the nice things of being a text only program is that you can use mutt from any computer that can connect through a ssh link to the computer you have your mail and mutt installed. In Android there is the fantastic <a href="http://code.google.com/p/connectbot/">ConnectBot</a> application which let you do just that. See this screenshot in you don&#8217;t believe it <img src='http://www.lorenzogil.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="attachment_232" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/mutt-in-android.jpg"><img class="size-medium wp-image-232" title="mutt-in-android" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/08/mutt-in-android-300x240.jpg" alt="Mutt in Android" width="300" height="240" /></a><p class="wp-caption-text">Mutt in Android</p></div>
<p>The only gotchas of using Mutt from my Android phone is that the GNOME integration gets in my way: now I can&#8217;t send emails since msmtp will look for the password in the GNOME keyring and there is no such thing in Android. One way to fix this issue is to configure another account in msmtp which doesn&#8217;t use the keyring but ask for the password manually and switch to that account with a key combination when using it from the phone.</p>
<h2>TODO</h2>
<ul>
<li>Mark the spam message as already readed so I don&#8217;t get distracted every time a spam message arrives my spam folder. Then once in a while I can review them looking for false positives.</li>
<li>Addressbook integration.</li>
<li>PGP integration</li>
</ul>
<h2>References</h2>
<ul>
<li><a href="http://www.mutt.org/doc/manual/">Mutt Manual</a></li>
<li><a href="http://wiki.mutt.org/">Mut Wiki</a></li>
<li><a href="http://wiki.mutt.org/index.cgi?MuttGuide">Mutt newbie guide</a></li>
<li><a href="http://mutt.blackfish.org.uk/">Mutt overview for newbies</a></li>
<li><a href="http://www.therandymon.com/papers/using-mutt.pdf">The Woodnotes Guide to the Mutt Email Client</a></li>
<li><a href="http://www.entrian.com/sbwiki/SbFilter">Spam Bayes wiki</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/08/21/managing-email-the-unix-way/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pie charts autopadding</title>
		<link>http://www.lorenzogil.com/blog/2010/07/26/pie-charts-autopadding/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pie-charts-autopadding</link>
		<comments>http://www.lorenzogil.com/blog/2010/07/26/pie-charts-autopadding/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 14:57:55 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Ordenadores]]></category>
		<category><![CDATA[pycha]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=179</guid>
		<description><![CDATA[I&#8217;ve been hacking on the Pycha autopadding feature lately and, as most things I write here, I&#8217;ll try to summarize the tricky parts so I can understand them in a couple of months. As a side effect, I hope you enjoy this post. In current Pycha versions there is a padding option but it is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been hacking on the <a href="http://bitbucket.org/lgs/pycha/" target="_self">Pycha</a> autopadding feature lately and, as most things I write here, I&#8217;ll try to summarize the tricky parts so I can understand them in a couple of months. As a side effect, I hope you enjoy this post.</p>
<p>In current Pycha versions there is a padding option but it is not what you expect. The current padding represents the space between the limit of the graphics area and the chart area. The labels and ticks are drawn in this space. What this means is the programmer has to manually adjust the padding in order to make the labels render correctly. When you are using pycha for drawing one or two charts in an environment under your control this is not a big issue. When you draw lots of charts from wild data sources, autopadding helps a lot.</p>
<div id="attachment_191" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-191" title="Pie Chart with manual padding" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/piechart-manual-padding.png" alt="Figure 1. Pie Chart with manual padding" width="500" height="500" /><p class="wp-caption-text">Figure 1. Pie Chart with manual padding</p></div>
<p>In Figure 1 you can see old style pie charts where we had to manually adjust the padding to make the labels fit. As a side effect the pie was not centered in the graphics area. Here the padding options are: {&#8216;top&#8217;: 0, &#8216;right&#8217;: 10, &#8216;left&#8217;: 70, &#8216;bottom&#8217;: 0}. Imagine what happen if the dataset changes: we would probably need to change the padding.</p>
<p>So, what exactly is autopadding? Well, it&#8217;s the feature that lets pycha compute the labels and ticks area automatically. Now the padding that you specify is real empty space.</p>
<div id="attachment_190" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-190" title="Pie Chart with autopadding" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/piechart.png" alt="Figure 2. Pie chart with autopadding" width="500" height="500" /><p class="wp-caption-text">Figure 2. Pie chart with autopadding</p></div>
<p>For most of the charts that pycha supports this feature is not very difficult. Except for the pie charts. In this case, it took me a while to get it working and the results, while good enough, are not perfect.</p>
<p>In figure 2 you can see such results. As you can see the pie is smaller now and the slices are ordered in a different way. The order really matters and I will probably add an option in the future to indicate the starting angle (now is 0) so there is a small degree of control left to the programmer. Note that this time the four paddings are equal to zero.</p>
<p>Let&#8217;s describe the problem: given a rectangular area (width and height) and a list of tuples made of a label and an angle, compute the circunference radius and the label positions so that the pie area is maximized and the labels do not override the pie.</p>
<p>For each label the angle associated with it is the angle that split its pie slice into two slices of the same side. If you have the initial and final angle of each slice (as I do) computing this angle is as easier as summing both and dividing by two.</p>
<p><strong>Step 1</strong>. So the first thing I do is compute the center of the area and the bounding boxes of the labels. Any decent graphics library has a function for that and Cairo is no different: <a href="http://cairographics.org/manual/cairo-text.html#cairo-text-extents" target="_self">cairo_text_extents</a>.</p>
<p><strong>Step 2</strong>. Now for each tuple in my label-angle list I draw a ray that starts at the center of the chart and goes into the direction given by the angle. Remember that a rect can be defined with a point and an angle.</p>
<div id="attachment_194" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-194  " title="Pie Chart in debug mode" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/piechart-step3.png" alt="Pie Chart in debug mode" width="500" height="500" /><p class="wp-caption-text">Figure 3. Pie Chart in debug mode showing the rays in red</p></div>
<p><strong>Step 3.</strong> I calculate the intersection of these rays with the rectangle that defines my graphics area (drawn in blue in the Figure 3 because debug mode is enabled). Clipping is not useful here since I want the coordinates for every intersection, the rays are not drawn in the final result unless debug mode is enabled. In order to make this computation easier I divide the area in four parts delimited by the two diagonals of the rectangle. Every ray is defined by an ecuation of the form y = mx + n where m is tan (angle) and I know which of the four sides of the rectangle the ray is going to intersect bases on the angle. As every side of the rectangle is also defined by a very simple ecuation, all I have to do is solve an ecuation system for each ray.</p>
<div id="attachment_200" class="wp-caption aligncenter" style="width: 310px"><img class="size-full wp-image-200" title="Division of the graphics area using the two diagonals" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/first-division.png" alt="Figure 4. Division of the graphics area using the two diagonals" width="300" height="293" /><p class="wp-caption-text">Figure 4. Division of the graphics area using the two diagonals</p></div>
<p>Nice. We have now a center and a bunch of rays and intersection points. We also have bounding boxes for the labels. Now I have to place each bounding box with two constraints:</p>
<ul>
<li>Its center lies on its associated ray</li>
<li>One of its side lies on one of the sides of the big chart rectangle</li>
</ul>
<p><strong>Step 4.</strong> It&#8217;s easy to guess what side of the bounding box matches with which side of the chart rectangle. A little bit of trigonometry will do the rest.</p>
<div id="attachment_201" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-201" title="Initial labels position" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/piechart-step4.png" alt="Figure 5. Initial labels position" width="500" height="500" /><p class="wp-caption-text">Figure 5. Initial labels position</p></div>
<p><strong>Step 5.</strong> Ok, now I have all the labels, or more correctly, their bounding boxes, positioned in the chart rectangle, as far as I can from the center. Now the maximun radius for the pie is the minimum of the distances from the bounding boxes to the center. For every bounding box there is one side that is closer than the others to the center, so the distance we want is the distance from that side to the center. Again, having divided the area in those four parts makes this step this easier. In our example shown in Figure 5 the label that restricts the pie radio is the one that reads &#8220;<em>stackedbar.py (6.9%)</em>&#8220;.</p>
<p>The good news are that we have achieved one of our goals: compute the radius of our pie chart. The bad news are that was the easy part. In the second round of our algorithm we are going to move the labels bounding boxes as close as we can to the pie. Otherwise they don&#8217;t look good and the conection between the slice and its label is lost. As you may guess all the labels can be moved closer to the center except for one. That&#8217;s the label that gave as the radius of the pie circunference.</p>
<p><strong>Step 6</strong>. So let&#8217;s try to move the labels. For this task I will divide the chart rectangle in four sides but this time I&#8217;ll use two perpendicular rects, one horizontal and one vertical. So I&#8217;ll get my circunference divided in four quadrants. For each label I&#8217;ll compute the intersection of its ray and our pie circunference. Remember that now we know its radius.</p>
<div id="attachment_203" class="wp-caption aligncenter" style="width: 310px"><img class="size-full wp-image-203" title="Second division of the graphics area" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/second-division.png" alt="Figure 6. Division by two perpendicular rects that touch the center" width="300" height="293" /><p class="wp-caption-text">Figure 6. Division by two perpendicular rects that touch the center</p></div>
<p><strong>Step 7</strong>. For each label place one corner of its bounding box in the point computed in step 6. For the first quadrant this corner is the left down corner, for the second quadrant it&#8217;s the right down corner, for the third quadrant it&#8217;s the right top corner and for the fourth quadrant it&#8217;s the left top corner. This is a feasible position but it doesn&#8217;t look very nice so we will try to improve it.</p>
<p><strong>Step 8</strong>. For each label draw another circunference with the same center as the pie circunference and the radius equal to the distance between the center of the bounding box and the center of the circunference. Now let&#8217;s compute the intersection between this second circunference and the ray of the same label. Voilá, that&#8217;s the point where we are going to move the center of the bounding box.</p>
<div id="attachment_205" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-205" title="Detail of label reposition" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/07/piechart-step8.png" alt="Figure 6. Detail of label reposition" width="500" height="500" /><p class="wp-caption-text">Figure 6. Detail of label reposition</p></div>
<p>So that&#8217;s the end of the algorithm, the labels are now positioned closer to the pie circunference but as I said before, it&#8217;s not perfect since for those labels that are near the top and bottom side of the circunference the label could be closer than it is. I may have used a soft computing algorithm that moves the bounding box along its ray until touches the pie circunference but that would be slower.</p>
<p>By the way, I&#8217;m using a <a href="http://bitbucket.org/lgs/pycha/src/b5f51554be84" target="_self">named branch</a> for this feature and hopefullly it will get merged into the main branch for the 0.7.0 release of pycha.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/07/26/pie-charts-autopadding/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>No space left is not a problem anymore</title>
		<link>http://www.lorenzogil.com/blog/2010/05/11/no-space-left-is-not-a-problem-anymore/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=no-space-left-is-not-a-problem-anymore</link>
		<comments>http://www.lorenzogil.com/blog/2010/05/11/no-space-left-is-not-a-problem-anymore/#comments</comments>
		<pubDate>Tue, 11 May 2010 16:49:43 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Ordenadores]]></category>
		<category><![CDATA[lvm]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=176</guid>
		<description><![CDATA[Today I was working with virtual machines and when I tried to install some packages the 2 GB hard disk I configured for this virtual machine reached its limit. By the way, it&#8217;s pretty amazing a vanilla CentOS 5.4 installation needs almost 2 GB. Anyway, this is what I did to increase the hard disk [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was working with virtual machines and when I tried to install some packages the 2 GB hard disk I configured for this virtual machine reached its limit. By the way, it&#8217;s pretty amazing a vanilla CentOS 5.4 installation needs almost 2 GB.</p>
<p>Anyway, this is what I did to increase the hard disk space without reinstalling the whole thing:</p>
<ol>
<li> Create a new hard disk with Virtual Machine Manager. I created it with another 2 GB and selected VirtIO as the disk type.</li>
<li>Start the virtual machine and create a partition in the new disk. /dev/vdb1 is the new disk:
<pre>   Device Boot      Start         End      Blocks   Id  System
/dev/vdb1               1        4063     2047720+  83  Linux</pre>
</li>
<li>Initialize a physical volume on the new disk:
<pre>pvcreate /dev/vdb1</pre>
</li>
<li>Add this physical volume to the logical volume group:
<pre>vgextend VolGroup00 /dev/vdb1</pre>
</li>
<li>Extend the logical volume group:
<pre>lvextend /dev/VolGroup00/LogVol00 -L+1.9G
Rounding up size to full physical extent 1.91 GB
Extending logical volume LogVol00 to 3.84 GB
Logical volume LogVol00 successfully resized</pre>
</li>
<li>Resize the filesystem:
<pre>resize2fs /dev/VolGroup00/LogVol00
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing required
Performing an on-line resize of /dev/VolGroup00/LogVol00 to 1007616 (4k) blocks.
The filesystem on /dev/VolGroup00/LogVol00 is now 1007616 blocks long.</pre>
</li>
</ol>
<p>Thanks to LVM now I have 2 more gigabytes on my virtual disk and no reinstallation was needed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/05/11/no-space-left-is-not-a-problem-anymore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Funda de gafas. The making of.</title>
		<link>http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=funda-de-gafas-the-making-of</link>
		<comments>http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 20:57:43 +0000</pubDate>
		<dc:creator>lgs</dc:creator>
				<category><![CDATA[Tiendas]]></category>

		<guid isPermaLink="false">http://www.lorenzogil.com/blog/?p=150</guid>
		<description><![CDATA[Últimamente ando liado con un proyecto en el trabajo así que el fin de semana pasado, aprovechando que estaba en Granada, con mis padres, decidí desconectar un poco y, con la ayuda de mi madre, fabricar una funda de gafas&#8230;. diferente. Os dejo la secuencia de fotos con el making of de la funda. También [...]]]></description>
			<content:encoded><![CDATA[<p>Últimamente ando liado con un proyecto en el trabajo así que el fin de semana pasado, aprovechando que estaba en Granada, con mis padres, decidí desconectar un poco y, con la ayuda de mi madre, fabricar una funda de gafas&#8230;. diferente.</p>
<p>Os dejo la secuencia de fotos con el making of de la funda.</p>

<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/01/' title='01'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/01-150x150.jpg" class="attachment-thumbnail" alt="01" title="01" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/02/' title='02'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/02-150x150.jpg" class="attachment-thumbnail" alt="02" title="02" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/03/' title='03'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/03-150x150.jpg" class="attachment-thumbnail" alt="03" title="03" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/04/' title='04'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/04-150x150.jpg" class="attachment-thumbnail" alt="04" title="04" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/05/' title='05'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/05-150x150.jpg" class="attachment-thumbnail" alt="05" title="05" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/06/' title='06'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/06-150x150.jpg" class="attachment-thumbnail" alt="06" title="06" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/07/' title='07'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/07-150x150.jpg" class="attachment-thumbnail" alt="07" title="07" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/08/' title='08'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/08-150x150.jpg" class="attachment-thumbnail" alt="08" title="08" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/09/' title='09'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/09-150x150.jpg" class="attachment-thumbnail" alt="09" title="09" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/10/' title='10'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/10-150x150.jpg" class="attachment-thumbnail" alt="10" title="10" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/11/' title='11'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/11-150x150.jpg" class="attachment-thumbnail" alt="11" title="11" /></a>
<a href='http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/attachment/12/' title='12'><img width="150" height="150" src="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/12-150x150.jpg" class="attachment-thumbnail" alt="12" title="12" /></a>

<p>También os dejo <a href="http://www.lorenzogil.com/blog/wp-content/uploads/2010/02/patron-funda-1.svg">los planos en vectorial</a> por si alguno se anima. Estos planos se han mejorado tras la primera funda. Mi madre ya está deseando hacer más para mejorar el resultado.</p>
<p>Nota: la <a href="http://www.wiinintendo.net/2010/01/08/snes-eye-glasses-case-nes-iphone-case/" target="_self">inspiración original es esta</a>. Me gustó tanto que fui a comprarmela pero en aquel momento no tenían en stock así que me puse manos a la obra y seguí el principio punki del &#8220;do it yourself&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lorenzogil.com/blog/2010/02/20/funda-de-gafas-the-making-of/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

