<?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>iXce's blog &#187; Python</title>
	<atom:link href="http://guillaume.segu.in/blog/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://guillaume.segu.in/blog</link>
	<description>Stuff that doesn’t matter</description>
	<lastBuildDate>Mon, 28 Feb 2011 22:28:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Use git as your blog data storage backend</title>
		<link>http://guillaume.segu.in/blog/code/298/use-git-as-your-blog-data-storage-backend/</link>
		<comments>http://guillaume.segu.in/blog/code/298/use-git-as-your-blog-data-storage-backend/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 00:18:37 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=298</guid>
		<description><![CDATA[A school friend, namely p4bl0, mentioned the idea of maintaining blog posts with git and a set of hooks which would produce the blog html from the contents of the repo. I loved the idea, but thought I could push it a little further&#160;: a blog engine which would use no other storage than git, [...]]]></description>
			<content:encoded><![CDATA[<p>A school friend, namely <a href="http://pablo.rauzy.name/">p4bl0</a>, mentioned the idea of maintaining blog posts with <tt>git</tt> and a set of hooks which would produce the blog html from the contents of the repo. I loved the idea, but thought I could push it a little further&nbsp;: a blog engine which would use no other storage than <tt>git</tt>, with the post subject and contents being the commit message subject and contents. A post-commit or post-receive hook then produces the html. As simple as that&nbsp;!</p>
<p>You can find the source in <a href="http://guillaume.segu.in/cgit/blogit.git/">BloGit git repo</a>, and see an example at <a href="http://aulo.in/blogit.html">BloGit example</a>. To use the source, you first have to pack it (using the <tt>pack</tt> script), which will merge the <tt>raw_post</tt> and <tt>raw_produce</tt>, producing a single <tt>post</tt> script (which I also included at the end of this post), which you can simply put in an empty directory and run it. It will unpack the other script (<tt>produce</tt>), initialize the git repo, and set the hooks. It&#8217;ll then prompt you for your post title and then open an editor for you to set your post contents. Save the file, and you&#8217;re done with your first post&nbsp;: check the index.html file which has been produced in the same directory. You can write your own stylesheet in the <a href="http://aulo.in/blogit-style.css">blogit-style.css</a> file. Further posts can be done with the same <tt>post</tt> script.</p>
<p>Yet, the best way is probably just to use the usual git workflow. To initialize the repo and all, run <tt>post --unpack</tt>, and to post <tt>post --raw</tt> or <tt>git commit --allow-empty</tt> (when using <tt>git commit</tt>, leave a blank line between the subject line and the rest of the post). You can also amend existing commits (using <tt>git commit --amend</tt>), use the GIT_AUTHOR_* environment variables to change the author, and so on. Since merge commits are skipped by the html generator, it should work just great for multi author blogging !</p>
<p>PS&nbsp;: I know this is JUST a git log pretty printer, and that the whole thing is pretty much trivial. I also know that using versionned files to store the posts would allow a lot of extra bonuses (such as automatically adding &#8220;Updated on &#8230;&#8221; mentions based on the commit log of each single file). I just thought the idea was fun <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/tongue.png' alt=':p' class='wp-smiley' />  There are probably a lot of things to improve, or a lot of smart git features to use there that I overlooked. Feel free to leave a line <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/smile.png' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-298"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #483d8b;">&quot;&quot;&quot;
 bloggit
 Author : Guillaume &quot;iXce&quot; Seguin
 Email  : guillaume@segu.in (or guillaume.seguin@ens.fr)
 Copyright (C) 2010 Guillaume Seguin
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA  02110-1301, USA.
&quot;&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">subprocess</span>, <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">base64</span>, <span style="color: #dc143c;">bz2</span>
CONTENTS_FILE = <span style="color: #483d8b;">&quot;POST_CONTENTS&quot;</span>
repo = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">abspath</span> <span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">os</span>.<span style="color: black;">chdir</span> <span style="color: black;">&#40;</span>repo<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>repo, <span style="color: #483d8b;">&quot;.git&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">call</span> <span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;git&quot;</span>, <span style="color: #483d8b;">&quot;init&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
produce_path = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>repo, <span style="color: #483d8b;">&quot;produce&quot;</span><span style="color: black;">&#41;</span>
produce_script = <span style="color: #dc143c;">bz2</span>.<span style="color: black;">decompress</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">base64</span>.<span style="color: black;">b64decode</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;
QlpoOTFBWSZTWQf3J2wAAV//gFxQAYB6b/p/f+fe7r///+pQBd42u22yaV13O6AGigNBIy
aIp7Sn6DJiSaeSeo00PykD1M1B+inpA03qQDU0AJk0mhqNPRGgAGjQaAGgADTQDQEajUYp
im2RT9U9RkGTQZAZG1DIAAAcaMmRhGIBhNBgE0GgZMmjJkMIDCRQTQmCaJtI1GjT1GmhqA
0yPUNDQbUNDQepWIWGfa4d31kD+Y5Rb4yaILtfQ2R3ruai19rArmVtHwltw/M/SKgVz+HG
mewWVLlaRGi+TgiYISYkD6/fECu/rM0N4r5GtcYW1QTuePdDZ+sPg4zb9+44SCBIOFkkg0
x55udVuK1GAeJhbulbdkEl+jz2G9vfcAh34ns8FhgJwKe1v5KFIdM2Eyyw0GMr3CL7ZNzK
RBUsFKRqwtgoNy9FHvVS66uV+heJbKHRXDHFf4J1zs3cj8oXsMfU5N+644WGdjzvLX1aap
AI6VwBnkLDzalqgjQuC2soFnZlK5GCZb80ra1gw5fh4rnD8GUmm6eUSa5mYoiFgrwmamRK
zCz9yuRcozq5UKJtbq3sBSN1gjHDQ9z2BK7Dw2KcWMHm491MdO2B62ZoUOzKwCqoREREHo
ZjLn2p0HiWYoMBQRP8YCAzIgZUc2PJZaZrY/lODrob1VQg4U9L1ZRXpNBCelwBoEqUbFCs
BJpOCKGs54vnVO1AQDU6v9X0lEnEHuE1nlsy5pNWawCEYImSZc/AdREPAKBrlp73jcCryL
OAdFJcMZqdVjjE5gIfQY4Qjju9UdOBBmuXjz6uZhpsc3LhrDg1BQGoL4GyiDRmpTkImmc9
YlDd26K11qaiVDQ4wwITIEMyxMiLi274jeFlLrj8BpnXU87qMq6z2VQs6RN74sifuXfw7d
bOOm9bexNvdsxPvZDgG0cmUYClTHvcCFAMAdL+/IndGLRmvh7w/Bni8LAUfWdAcRyR4NDu
d49goYEMqHwDJLLa4vSbQRLptFdWVLzfSggKVzGtJIX1laSjr8I2BUTyiovpeiiyNQZu5Y
xresZCItgNp6ArbjFsCdRdgrgsw9tcrCa1Djq7A7ItXvGBWWs9IP0iIEAqnJ8xcH6Do9+1
UNVwkrSI5yC/J0ACce0NqBmWdEXp0KBIBWawoxJI66zSW55iEHoFRC0m8pYQICMFCcrrbT
Lg5yvtsbQNwVvMipGYYYTGs+czVBOZBcoWGD+l1xRtlbVMDwM0OpEVa3YMa1Ax/SosYOB4
WQVhQejJLSsL7hmrQh6V/tgUDTQ1C5tNdUOZckY4G+CyuDeTOgkEyPE+YjKpYtTRnMzumS
KImpjWQIAaLK2djnoVkRq5F+Sglu77bey0552SggnVQj0jKnFwwvhT3Y6oFpO4b8hmb1t7
A3yKE74eX6aqvJ7fP5wjXYonDYwumjqnrlv3obv7WsTxFpxVYpHCErmRUKGvwPUiSRWYMn
FZIzt0eUPDxJrGAamFrkeX3WwB0CmC/Jls/DLFV7uiPSiVaMNxy1GXfqziuzlXVsk2mQw2
AeNj5+QtDUFuUCZKDGMagNGpxIx/46nKSJsbprNPXGqzJVxVcglKGV5VysJDCqgRinuNbX
ChqDzZ6JXB8Rz0VF8aK+NMxXupulQOr1U6XP19can5uVqG7fs6Sa3Kq51jGOK9jDQ6fZf4
zXLr884Wq67SW+YyPk5OB1G0WmA1s8OiKQRBccciEMujm6A2LMvcIDogVk2GRbzgYrapcB
VDXEsgM9FJCQrvwaVw3C6i0FlYbnwXoJqe3bYlAjrGTVnqOSOpUOWcFXUdVlKmeOahYuhi
mEIgcCiiFMPnz5r1hXukd6HApZVuGq1kxn8DgWUiEMcRm+5FDm1Y7cFNuOVzIkcaRHdWGj
vESnObg+IQwh5zNAYUb6CROYdEATsATAW/EnFc9IJTEQfCce8EymZ4uNSNoi3DgvNBNkxt
jAmszFZUqNLNxxkjqWcA+gkju1U2gyzjAujsieBpM9X37TNq17LCRv6ToL1MIOJeWVwUiB
6MrbOTHwIixlYyW5xO7y/+LuSKcKEgD+5O2A==
&quot;&quot;&quot;</span>.<span style="color: black;">strip</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">replace</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span> <span style="color: black;">&#40;</span>produce_path<span style="color: black;">&#41;</span>:
    <span style="color: #008000;">open</span> <span style="color: black;">&#40;</span>produce_path, <span style="color: #483d8b;">&quot;w&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span>produce_script<span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">os</span>.<span style="color: black;">chmod</span> <span style="color: black;">&#40;</span>produce_path, 0755<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> hook <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;post-receive&quot;</span>, <span style="color: #483d8b;">&quot;post-commit&quot;</span><span style="color: black;">&#41;</span>:
    hook_path = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>repo, <span style="color: #483d8b;">&quot;.git&quot;</span>, <span style="color: #483d8b;">&quot;hooks&quot;</span>, hook<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span> <span style="color: black;">&#40;</span>hook_path<span style="color: black;">&#41;</span> \
     <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">realpath</span> <span style="color: black;">&#40;</span>hook_path<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= produce_path:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">lexists</span> <span style="color: black;">&#40;</span>hook_path<span style="color: black;">&#41;</span>: <span style="color: #dc143c;">os</span>.<span style="color: black;">remove</span> <span style="color: black;">&#40;</span>hook_path<span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">os</span>.<span style="color: black;">symlink</span> <span style="color: black;">&#40;</span>produce_path, hook_path<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;--unpack&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Unpack only&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">SystemExit</span>
<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;--raw&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span>:
    p = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span> <span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;git&quot;</span>, <span style="color: #483d8b;">&quot;commit&quot;</span>, <span style="color: #483d8b;">&quot;--allow-empty&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">communicate</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    title = <span style="color: #008000;">raw_input</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Post title ? &quot;</span><span style="color: black;">&#41;</span>
    editor = <span style="color: #483d8b;">&quot;vi&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;VISUAL&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span>:
        editor = <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;VISUAL&quot;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #483d8b;">&quot;EDITOR&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span>:
        editor = <span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;EDITOR&quot;</span><span style="color: black;">&#93;</span>
    contents_path = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>repo, CONTENTS_FILE<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span> <span style="color: black;">&#40;</span>contents_path<span style="color: black;">&#41;</span>:
        <span style="color: #dc143c;">os</span>.<span style="color: black;">remove</span> <span style="color: black;">&#40;</span>contents_path<span style="color: black;">&#41;</span>
    ret = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">call</span> <span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>editor, contents_path<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> ret == <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span> <span style="color: black;">&#40;</span>contents_path<span style="color: black;">&#41;</span>:
        contents = <span style="color: #008000;">open</span> <span style="color: black;">&#40;</span>contents_path<span style="color: black;">&#41;</span>.<span style="color: black;">read</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">os</span>.<span style="color: black;">remove</span> <span style="color: black;">&#40;</span>contents_path<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;A problem occured while editing the contents file&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">SystemExit</span>
    p = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span> <span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;git&quot;</span>, <span style="color: #483d8b;">&quot;commit&quot;</span>, <span style="color: #483d8b;">&quot;--allow-empty&quot;</span>, <span style="color: #483d8b;">&quot;-F&quot;</span>, <span style="color: #483d8b;">&quot;-&quot;</span><span style="color: black;">&#93;</span>,
                          stdin = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: black;">&#41;</span>
    p.<span style="color: black;">communicate</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>title, contents<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">if</span> p.<span style="color: black;">returncode</span> == <span style="color: #ff4500;">0</span>: <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;New post successfully added&quot;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Couldn't add new post&quot;</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/code/298/use-git-as-your-blog-data-storage-backend/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Python packages for Maemo 5</title>
		<link>http://guillaume.segu.in/blog/packaging/244/building-python-packages-for-maemo-5/</link>
		<comments>http://guillaume.segu.in/blog/packaging/244/building-python-packages-for-maemo-5/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 22:29:18 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Maemo]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=244</guid>
		<description><![CDATA[TLDR : directly skip to the last paragraph For a few weeks now a couple of friends and I have been working on a media player for Maemo 5 with some extra bonuses (mostly track scoring and track prediction). Now that we have something pretty much functional, I was willing to produce some .deb packages [...]]]></description>
			<content:encoded><![CDATA[<p><em>TLDR : directly skip to the last paragraph</em></p>
<p>For a few weeks now a couple of friends and I have been working on a media player for Maemo 5 with some extra bonuses (mostly track scoring and track prediction). Now that we have something pretty much functional, I was willing to produce some .deb packages for easy installation. I knew it wouldn&#8217;t be an easy task &#8212; and it definitely wasn&#8217;t.</p>
<p>Since I had no Scratchbox setup in the first place (64 bits distro, etc.), I first tried the <a href="http://wiki.maemo.org/Py2deb">py2deb</a>/<a href="http://wiki.maemo.org/PyPackager">PyPackager</a> approach, which let&#8217;s you create .deb packages directly on the tablet for python apps. Sadly, this approach requires you to sort your source tree in a very strict manner, which is as it will be on the device. Since I plan to rebuild my package often and I don&#8217;t want to work in an uglily organized environment, this is not the solution.</p>
<p>I thus set a debian virtualbox and installed Scratchbox on it, and tried to use a very simple cdbs build system, using python-distutils.mk (I already had a distutils build system working), and then building the .deb with dpkg-buildpackage. Sadly, for an unknown reason (to me) this was putting the python libs into /var/lib/pyshared/, which is definitely not in the n900 PYTHON_PATH, plus the package did not include the empty __init__.py files in the packages (it seems they were removed by python-support which is used by python-distutils.mk and are meant to be reconstructed upon install, though they weren&#8217;t), which lead to a completely broken package.</p>
<p>The next attempt I made was to use <a href="http://wiki.maemo.org/Building_packages_with_sbdmock">sbdmock</a>, which is used by the official maemo.org autobuilder. Sadly, while it was successfully building other packages, it never succeeded at building my package because  &#8220;pyversions&#8221;, which is required by python-distutils.mk, was missing (seems this is a <a href="https://bugs.maemo.org/show_bug.cgi?id=2741">known problem</a> &#8212; though this might actually be fixed now and I might just be lacking the right builddep).</p>
<p>Instead of try to do it right, I should probably have done it fast. Since I&#8217;m using a debian-based distribution on my laptop, all I had to do was :</p>
<ul>
<li>Install python2.5 in the right prefix (/usr), restore the /usr/bin/python symlink to python2.6</li>
<li>Write a simple homemade debian/rules file which runs distutils and then sorts everything to the right package prefix (this is actually even easier if you only have one package since there is no sorting involved ; I included a sample one at the end of the post)</li>
<li>Specify Architecture: all in debian/control (since this is a full python package, it should run on any platform)</li>
<li>Run dpkg-buildpackage. Enjoy !</li>
</ul>
<p>Let&#8217;s note that there is something called <a href="http://wiki.maemo.org/PyMaemo/Scratchboxless_packaging_guide">stdeb</a> which might be easier than this process. Too bad I only found it now  <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/sad.png' alt=':sad:' class='wp-smiley' />  </p>
<p><span id="more-244"></span></p>
<p>Sample debian/rules :</p>
<blockquote><p>#!/usr/bin/make -f<br />
# -*- makefile -*-<br />
# Sample debian/rules that uses debhelper.<br />
# GNU copyright 1997 to 1999 by Joey Hess.</p>
<p># Uncomment this to turn on verbose mode.<br />
#export DH_VERBOSE=1</p>
<p>ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))<br />
 	INSTALL_PROGRAM += -s<br />
endif</p>
<p>configure: configure-stamp</p>
<p>configure-stamp:<br />
	dh_testdir<br />
	touch configure-stamp</p>
<p>build: build-stamp</p>
<p>build-stamp: configure-stamp<br />
	dh_testdir<br />
	$(MAKE)<br />
	touch build-stamp</p>
<p>clean:<br />
	dh_testdir<br />
	dh_testroot<br />
	rm -f build-stamp configure-stamp<br />
	rm -rf $(CURDIR)/debian/mymediaplayergui<br />
	rm -rf $(CURDIR)/debian/python-mymediaplayer<br />
	-$(MAKE) clean<br />
	dh_clean</p>
<p>install: build<br />
	dh_testdir<br />
	dh_testroot<br />
	dh_clean -k<br />
	dh_installdirs<br />
	$(MAKE) install DESTDIR=$(CURDIR)/debian/python-mymediaplayer<br />
	mkdir -p $(CURDIR)/debian/mymediaplayergui/usr/bin<br />
	mkdir -p $(CURDIR)/debian/mymediaplayergui/usr/lib/python2.5/site-packages<br />
	mkdir -p $(CURDIR)/debian/mymediaplayergui/usr/share<br />
	mkdir -p $(CURDIR)/debian/mymediaplayergui/usr/share/applications/hildon<br />
	mv $(CURDIR)/debian/python-mymediaplayer/usr/bin/maemotunes.py \<br />
			$(CURDIR)/debian/mymediaplayergui/usr/bin/<br />
	mv $(CURDIR)/debian/python-mymediaplayer/usr/bin/mymediaplayergui.py \<br />
			$(CURDIR)/debian/mymediaplayer/usr/bin/<br />
	mv $(CURDIR)/debian/python-mymediaplayer/usr/lib/python2.5/site-packages/mymediaplayergui \<br />
			$(CURDIR)/debian/mymediaplayergui/usr/lib/python2.5/site-packages</p>
<p>binary-indep: build install<br />
	dh_testdir<br />
	dh_testroot<br />
	dh_installchangelogs<br />
	dh_fixperms<br />
	dh_installdeb<br />
	dh_gencontrol<br />
	dh_md5sums<br />
	dh_builddeb</p>
<p>binary-arch: build install</p>
<p>binary: binary-indep binary-arch<br />
.PHONY: build clean binary-indep binary-arch binary install configure
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/packaging/244/building-python-packages-for-maemo-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Useful paralellism with Python</title>
		<link>http://guillaume.segu.in/blog/code/223/useful-paralellism-with-python/</link>
		<comments>http://guillaume.segu.in/blog/code/223/useful-paralellism-with-python/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 19:54:41 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[multiprocessing]]></category>
		<category><![CDATA[parallel]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=223</guid>
		<description><![CDATA[After sorting out my clutter issues and finally producing a video of a clutter animation, I thought I&#8217;d use it on the initial goal, that animation I had written ages ago. What I had sadly forecast occurred, the video dumping awfully slowed down the animation. The whole problem is that, for now at least, I [...]]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://guillaume.segu.in/blog/code/216/doing-videos-of-clutter-animations/">sorting out my clutter issues and finally producing a video of a clutter animation</a>, I thought I&#8217;d use it on the initial goal, that animation I had written ages ago. What I had sadly forecast occurred, the video dumping awfully slowed down the animation.</p>
<p>The whole problem is that, for now at least, I don&#8217;t think it&#8217;s possible to run the animation frame per frame rather than time based. So I thought &#8220;let&#8217;s just defer the whole video generation to after the end of the animation, and bufferize the frames meanwhile&#8221;. Well, this worked&#8230; until oomkiller jumped in and killed my process. Urgh.</p>
<p>So, I can&#8217;t bufferize the whole video, but I can&#8217;t push the frames to gstreamer in real time directly from the animation either. Well, all I need is parallelism then&nbsp;! Push frames to a queue which is consumed by another execution unit (by pushing the frames to gstreamer). And since threading pretty much sucks in Python (well, it would definitely since we need real parallelism), let&#8217;s use the new <a href="http://docs.python.org/library/multiprocessing.html">multiprocessing</a> framework from Python 2.6. Using it is pretty straightforward&nbsp;: create some parallel structures (queues, pipes), spawn a new process with it&#8217;s own main function, push to the structures from one process, read from another, and you&#8217;re done. The only thing I&#8217;m still wondering is why there is a <a href="http://docs.python.org/library/multiprocessing.html#multiprocessing.Queue.close">close()</a> function on Queues when there is no obvious way to detect from the other end that the queue has been closed (which I worked around by pushing a None message).</p>
<p>Well, now I have a smooth animation and a smooth video dump, my two cores being nicely fully used <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/smile.png' alt=':)' class='wp-smiley' /> </p>
<p>The code is available below, with the interesting parts being <tt>StageRecorder.create_pipeline</tt>, <tt>StageRecorder.dump_frame</tt>, <tt>StageRecorder.stop_recording</tt> and  <tt>StageRecorder.process_runner</tt>.</p>
<p><span id="more-223"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> clutter
<span style="color: #ff7700;font-weight:bold;">import</span> gst
<span style="color: #ff7700;font-weight:bold;">import</span> gobject
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> multiprocessing <span style="color: #ff7700;font-weight:bold;">import</span> Process, <span style="color: #dc143c;">Queue</span>
&nbsp;
DEFAULT_OUTPUT = <span style="color: #483d8b;">&quot;stage.ogg&quot;</span>
DEFAULT_PIPELINE_DESC = <span style="color: #483d8b;">&quot;videorate ! theoraenc ! oggmux&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> StageRecorderSrc <span style="color: black;">&#40;</span>gst.<span style="color: black;">Element</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Gstreamer element used to push our buffers into the pipeline&quot;&quot;&quot;</span>
&nbsp;
    __gstdetails__ = <span style="color: black;">&#40;</span>
        <span style="color: #483d8b;">&quot;Clutter Stage Recorder Source plugin&quot;</span>,
        <span style="color: #483d8b;">&quot;stagerecorder.py&quot;</span>,
        <span style="color: #483d8b;">&quot;&quot;</span>,
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    _src_template = gst.<span style="color: black;">PadTemplate</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;src&quot;</span>,
                                     gst.<span style="color: black;">PAD_SRC</span>,
                                     gst.<span style="color: black;">PAD_ALWAYS</span>,
                                     gst.<span style="color: black;">caps_new_any</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    __gsttemplates__ = <span style="color: black;">&#40;</span>_src_template,<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        gst.<span style="color: black;">Element</span>.<span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">src_pad</span> = gst.<span style="color: black;">Pad</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._src_template<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">src_pad</span>.<span style="color: black;">use_fixed_caps</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">add_pad</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">src_pad</span><span style="color: black;">&#41;</span>
&nbsp;
gobject.<span style="color: black;">type_register</span> <span style="color: black;">&#40;</span>StageRecorderSrc<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> StageRecorder <span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Clutter stage recorder which dumps frames into a gstreamer pipeline&quot;&quot;&quot;</span>
&nbsp;
    stage = <span style="color: #008000;">None</span>
    output_filename = <span style="color: #008000;">None</span>
    pipeline_desc = <span style="color: #008000;">None</span>
    parallel = <span style="color: #008000;">False</span>
&nbsp;
    pipeline = <span style="color: #008000;">None</span>
    src = <span style="color: #008000;">None</span>
    buffer_queue = <span style="color: #008000;">None</span>
    process = <span style="color: #008000;">None</span>
&nbsp;
    stage_width = <span style="color: #ff4500;">0</span>
    stage_height = <span style="color: #ff4500;">0</span>
&nbsp;
    clock_start = -<span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>,
                  stage,
                  pipeline_desc = DEFAULT_PIPELINE_DESC,
                  output_filename = DEFAULT_OUTPUT,
                  parallel = <span style="color: #008000;">False</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">stage</span> = stage
        stage.<span style="color: black;">connect</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;destroy&quot;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">stop_recording</span><span style="color: black;">&#41;</span>
        stage.<span style="color: black;">connect_after</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;paint&quot;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">dump_frame</span><span style="color: black;">&#41;</span>
        stage.<span style="color: black;">connect</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;notify::width&quot;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">update_size</span><span style="color: black;">&#41;</span>
        stage.<span style="color: black;">connect</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;notify::height&quot;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">update_size</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline_desc</span> = pipeline_desc
        <span style="color: #008000;">self</span>.<span style="color: black;">output_filename</span> = output_filename
        <span style="color: #008000;">self</span>.<span style="color: black;">dumping</span> = <span style="color: #008000;">False</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span> = <span style="color: #008000;">None</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">src</span> = <span style="color: #008000;">None</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">parallel</span> = parallel
        <span style="color: #008000;">self</span>.<span style="color: black;">clock_start</span> = -<span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> create_pipeline <span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Create the gstreamer pipeline and run it&quot;&quot;&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span> = gst.<span style="color: black;">parse_launch</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">pipeline_desc</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Couldn't create pipeline&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">add_source</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">add_sink</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">set_state</span> <span style="color: black;">&#40;</span>gst.<span style="color: black;">STATE_PLAYING</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">parallel</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">buffer_queue</span> = <span style="color: #dc143c;">Queue</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">process</span> = Process <span style="color: black;">&#40;</span>target = <span style="color: #008000;">self</span>.<span style="color: black;">process_runner</span>,
                                    args = <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">buffer_queue</span>,<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">process</span>.<span style="color: black;">start</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> add_source <span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Add our data source and its filters&quot;&quot;&quot;</span>
        sink_pad = <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">find_unlinked_pad</span> <span style="color: black;">&#40;</span>gst.<span style="color: black;">PAD_SINK</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> sink_pad:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Pipeline has no unlinked sink pad&quot;</span>
&nbsp;
        src_element = StageRecorderSrc <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">add</span> <span style="color: black;">&#40;</span>src_element<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">src</span> = src_element.<span style="color: black;">get_static_pad</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;src&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># The ffmpegcolorspace element is a generic converter; it will convert</span>
        <span style="color: #808080; font-style: italic;"># our supplied fixed format data into whatever the encoder wants</span>
        ffmpegcolorspace = gst.<span style="color: black;">element_factory_make</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ffmpegcolorspace&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> ffmpegcolorspace:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't create ffmpegcolorspace element&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">add</span> <span style="color: black;">&#40;</span>ffmpegcolorspace<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># No need to verticalflip here since clutter_stage_read_pixels did</span>
&nbsp;
        src_element.<span style="color: black;">link</span> <span style="color: black;">&#40;</span>ffmpegcolorspace<span style="color: black;">&#41;</span>
&nbsp;
        src_pad = ffmpegcolorspace.<span style="color: black;">get_static_pad</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;src&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> src_pad:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't get src pad to link into pipeline&quot;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> src_pad.<span style="color: black;">link</span> <span style="color: black;">&#40;</span>sink_pad<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= gst.<span style="color: black;">PAD_LINK_OK</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't link to sink pad&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> add_sink <span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Add the final filesink&quot;&quot;&quot;</span>
        src_pad = <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">find_unlinked_pad</span> <span style="color: black;">&#40;</span>gst.<span style="color: black;">PAD_SRC</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> src_pad:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Pipeline has no unlinked src pad&quot;</span>
        filesink = gst.<span style="color: black;">parse_launch</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;filesink location=%s&quot;</span> \
                                        <span style="color: #66cc66;">%</span> <span style="color: #008000;">self</span>.<span style="color: black;">output_filename</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> filesink:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't create filesink element&quot;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">add</span> <span style="color: black;">&#40;</span>filesink<span style="color: black;">&#41;</span>
&nbsp;
        sink_pad = filesink.<span style="color: black;">get_static_pad</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sink&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> sink_pad:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't get sink pad to link pipeline output&quot;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> src_pad.<span style="color: black;">link</span> <span style="color: black;">&#40;</span>sink_pad<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= gst.<span style="color: black;">PAD_LINK_OK</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Can't link to sink pad&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> dump_frame <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, stage<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Dump a frame to the gstreamer pipeline&quot;&quot;&quot;</span>
        <span style="color: #808080; font-style: italic;"># Prevent an infinite loop (clutter.Stage.read_pixels</span>
        <span style="color: #808080; font-style: italic;"># performs another paint)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">dumping</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">dumping</span> = <span style="color: #008000;">True</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">create_pipeline</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            data = <span style="color: #008000;">self</span>.<span style="color: black;">stage</span>.<span style="color: black;">read_pixels</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>,
                                           <span style="color: #008000;">self</span>.<span style="color: black;">stage_width</span>,
                                           <span style="color: #008000;">self</span>.<span style="color: black;">stage_height</span><span style="color: black;">&#41;</span>
            <span style="color: #808080; font-style: italic;"># Use clutter clock</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">clock_start</span> == -<span style="color: #ff4500;">1</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">clock_start</span> = clutter.<span style="color: black;">get_timestamp</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            timestamp = clutter.<span style="color: black;">get_timestamp</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - <span style="color: #008000;">self</span>.<span style="color: black;">clock_start</span>
            timestamp <span style="color: #66cc66;">*</span>= <span style="color: #ff4500;">1000</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">parallel</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">buffer_queue</span>.<span style="color: black;">put</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>data, timestamp<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                buffer = gst.<span style="color: black;">Buffer</span> <span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                buffer.<span style="color: black;">timestamp</span> = timestamp
                <span style="color: #808080; font-style: italic;"># Don't forget to set the right caps on the buffer</span>
                <span style="color: #008000;">self</span>.<span style="color: black;">set_caps_on</span> <span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>
                status = <span style="color: #008000;">self</span>.<span style="color: black;">src</span>.<span style="color: black;">push</span> <span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> status <span style="color: #66cc66;">!</span>= gst.<span style="color: black;">FLOW_OK</span>:
                    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Error while pushing buffer : &quot;</span> + status
            <span style="color: #008000;">self</span>.<span style="color: black;">dumping</span> = <span style="color: #008000;">False</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> update_size <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, stage = <span style="color: #008000;">None</span>, param = <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Update the size of the gstreamer frames based on the stage size&quot;&quot;&quot;</span>
        x1, y1, x2, y2 = <span style="color: #008000;">self</span>.<span style="color: black;">stage</span>.<span style="color: black;">get_allocation_box</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">stage_width</span> = <span style="color: #008000;">int</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0.5</span> + x2 - x1<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">stage_height</span> = <span style="color: #008000;">int</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0.5</span> + y2 - y1<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> set_caps_on <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, dest<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Set the current frame caps on the specified object&quot;&quot;&quot;</span>
        <span style="color: #808080; font-style: italic;"># The data is always native-endian xRGB; ffmpegcolorspace</span>
        <span style="color: #808080; font-style: italic;"># doesn't support little-endian xRGB, but does support</span>
        <span style="color: #808080; font-style: italic;"># big-endian BGRx.</span>
        caps = gst.<span style="color: black;">caps_from_string</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;video/x-raw-rgb,bpp=32,depth=24,<span style="color: #000099; font-weight: bold;">\</span>
                                      red_mask=0xff000000,<span style="color: #000099; font-weight: bold;">\</span>
                                      green_mask=0x00ff0000,<span style="color: #000099; font-weight: bold;">\</span>
                                      blue_mask=0x0000ff00,<span style="color: #000099; font-weight: bold;">\</span>
                                      endianness=4321,<span style="color: #000099; font-weight: bold;">\</span>
                                      framerate=15/1,<span style="color: #000099; font-weight: bold;">\</span>
                                      width=%d,height=%d&quot;</span> \
                                        <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">stage_width</span>,
                                           <span style="color: #008000;">self</span>.<span style="color: black;">stage_height</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> dest:
            dest.<span style="color: black;">set_caps</span> <span style="color: black;">&#40;</span>caps<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> stop_recording <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, stage<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">parallel</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">buffer_queue</span>.<span style="color: black;">put</span> <span style="color: black;">&#40;</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pipeline</span>.<span style="color: black;">set_state</span> <span style="color: black;">&#40;</span>gst.<span style="color: black;">STATE_NULL</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> process_runner <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, queue<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
            message = queue.<span style="color: black;">get</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> message:
                <span style="color: #ff7700;font-weight:bold;">return</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                data, timestamp = message
                buffer = gst.<span style="color: black;">Buffer</span> <span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                buffer.<span style="color: black;">timestamp</span> = timestamp
                <span style="color: #008000;">self</span>.<span style="color: black;">set_caps_on</span> <span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>
                status = <span style="color: #008000;">self</span>.<span style="color: black;">src</span>.<span style="color: black;">push</span> <span style="color: black;">&#40;</span>buffer<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> status <span style="color: #66cc66;">!</span>= gst.<span style="color: black;">FLOW_OK</span>:
                    <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">RuntimeError</span>, <span style="color: #483d8b;">&quot;Error while pushing buffer : &quot;</span> + status</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/code/223/useful-paralellism-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rant of the day : OpenCV-python 2.0 package on Fedora 13</title>
		<link>http://guillaume.segu.in/blog/code/175/rant-of-the-day-opencv-python-2-0-package-on-fedora-13/</link>
		<comments>http://guillaume.segu.in/blog/code/175/rant-of-the-day-opencv-python-2-0-package-on-fedora-13/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 00:46:08 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[fedora 13]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=175</guid>
		<description><![CDATA[Today I&#8217;ve been looking at opencv-python for a quick project (I&#8217;d like to practice OpenCV a little bit). Installed the opencv-python package on Fedora 13, headed to the samples directory (/usr/share/opencv/samples/python/), started running one of them and&#8230; boum, segfault. Tried another one (the inpainting one), and it worked. A third one&#8230; segfault. Most of the [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve been looking at <a href="http://opencv.willowgarage.com/documentation/python/index.html">opencv-python</a> for a quick project (I&#8217;d like to practice OpenCV a little bit). Installed the opencv-python package on Fedora 13, headed to the samples directory (/usr/share/opencv/samples/python/), started running one of them and&#8230; boum, segfault. Tried another one (the inpainting one), and it worked. A third one&#8230; segfault. Most of the samples in there segfaulted, mostly with SWIG errors about wrong parameters, always mentioning int64 (I&#8217;m using a x86_64 kernel &#038; distribution).</p>
<p>After half an hour of failure on trying to get opencv.i686 work alongside my x86_64 python, I went back to the OpenCV website to check if there was some known heavy problems with x86_64 systems and&#8230; I discovered that&nbsp;:</p>
<blockquote><p>Starting with release 2.0, OpenCV has a new Python interface. (The previous Python interface is described in SwigPythonInterface.)</p></blockquote>
<p>Wait wait wait, you mean that during all this time I was running the OLD, pre-2.0 Python interface&nbsp;? Why the hell does the opencv-python 2.0 package provides both the new and the old interfaces&nbsp;? (well, I know the answer : backwards compatibility). Meh <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/sad.png' alt=':(' class='wp-smiley' />  Anyway, I wish the old samples would get ported to the new interface&#8230; At the moment there&#8217;s no sample using it at all&nbsp;:/</p>
]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/code/175/rant-of-the-day-opencv-python-2-0-package-on-fedora-13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Doing basic UML-like diagrams for Python code</title>
		<link>http://guillaume.segu.in/blog/code/160/doing-basic-uml-like-diagrams-for-python-code/</link>
		<comments>http://guillaume.segu.in/blog/code/160/doing-basic-uml-like-diagrams-for-python-code/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 00:56:15 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[diagram]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=160</guid>
		<description><![CDATA[For a project midterm presentation, we were asked to produce a bunch of slides explaining our project architecture and implementation choices. Apart of the obvious things (libraries in use, network protocol&#8230;), I had no real clue on what I could put in, so I thought I&#8217;d just throw some UML-like diagrams and that it would [...]]]></description>
			<content:encoded><![CDATA[<p>For a project midterm presentation, we were asked to produce a bunch of slides explaining our project architecture and implementation choices. Apart of the obvious things (libraries in use, network protocol&#8230;), I had no real clue on what I could put in, so I thought I&#8217;d just throw some UML-like diagrams and that it would be fine. The only detail was&nbsp;: how to produce these diagrams&nbsp;?</p>
<p>Since the project code was written in Python, all the inheritance relations were already held by the code and could be introspected, so that it was theoretically possible to automatically produce the inheritance diagram. And it actually is, and is implemented by things like the <a href="http://epydoc.sourceforge.net/">Epydoc</a> (a documentation generator for Python code) parser, as well as the diagram generation, which Epydoc also implements. The only thing is that I wasn&#8217;t satisfied by the Epydoc diagrams since they were limited to the inheritance relationships, while I was also willing to include usage relationships and display only the main methods and variables of my objects.</p>
<p>I thus wrote <a href="http://guillaume.segu.in/cgit/umlpy.git/">Umlpy</a>, a UML-like class diagram generator for Python code, which depends on Epydoc (for the parser) and python-graphviz (for the graph generation, it produces nicely spaced graphs and can output jpg, png or pdf files, and probably more). It handles the aforementioned requirements through docstrings parsing and introspection. Check the <a href="http://guillaume.segu.in/cgit/umlpy.git/tree/README">Umlpy README file</a> for more documentation on how to use it. It took me about 10 minutes to get to the result I was expecting (it&#8217;s basically about adding a little docstring for usage relationship, and copy-pasting a docstring on methods or variables you want to see on the diagram.</p>
<p>This wouldn&#8217;t be complete without the mandatory screenshot, and <a href="http://guillaume.segu.in/cgit/umlpy.git/tree/example.py?id=16c34deeb3340aeb470958e2b2278c6c703fc5d5">this example code</a> results into this diagram&nbsp;:<br />
<img src="http://guillaume.segu.in/blog/wp-content/uploads/2010/03/example.png" alt="Umlpy result example" title="Umlpy result example" width="384" height="320" class="aligncenter size-full wp-image-161" /></p>
]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/code/160/doing-basic-uml-like-diagrams-for-python-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python tip of the day: replace pyxml&#8217;s PrettyPrint</title>
		<link>http://guillaume.segu.in/blog/home/119/python-tip-of-the-day-replace-pyxmls-prettyprint/</link>
		<comments>http://guillaume.segu.in/blog/home/119/python-tip-of-the-day-replace-pyxmls-prettyprint/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 07:24:47 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[~home]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=119</guid>
		<description><![CDATA[Ever heard of Gogh? This is a really nice drawing tool for graphic tablets owner (such as those by Wacom). However it stopped working on my Hardy system after some recent update. After some investigation, it appeared that it was due to python-xml being moved away of Python path because it interfered with stuff in [...]]]></description>
			<content:encoded><![CDATA[<p>Ever heard of <a href="http://www.goghproject.com/">Gogh</a>? This is a really nice drawing tool for graphic tablets owner (such as those by Wacom). However it stopped working on my Hardy system after some recent update. After some investigation, it appeared that it was due to python-xml being moved away of Python path because it interfered with stuff in Python core ; the whole python-xml package being scheduled for deprecation as soon as the reverse depends would be cleared. I figured it out and dropped the reference to python-xml package in gogh/settingsmanager.py, using a method provided by Python core xml stuff instead. It seems that quite a bunch of people are currently using xml.doc.ext.PrettyPrint from pyxml to output an XML document to a file, so I figured that posting this little tip might help someone <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/smile.png' alt=':)' class='wp-smiley' /> </p>
<p>So, let&#8217;s say you currently have something like this to output your xml document &#8220;doc&#8221; to a file at path &#8220;path&#8221;, doc being an xml.dom.minidom.Document object (or similar):</p>
<pre><code>        f = open(path, "w")
        xml.dom.ext.PrettyPrint(doc, f)
        f.close()
</code></pre>
<p>All you need to change is PrettyPrint call to make use of the .toxml() method of your document object instead:</p>
<pre><code>        f = open(path, "w")
        f.write(doc.toxml())
        f.close()
</code></pre>
<p>Here you go, hope this might save someone&#8217;s day someday <img src='http://guillaume.segu.in/blog/wp-includes/images/smilies/smile.png' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/home/119/python-tip-of-the-day-replace-pyxmls-prettyprint/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Tip of the day: Dynamic forms with Django newforms</title>
		<link>http://guillaume.segu.in/blog/home/116/tip-of-the-day-dynamic-forms-with-django-newforms/</link>
		<comments>http://guillaume.segu.in/blog/home/116/tip-of-the-day-dynamic-forms-with-django-newforms/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 21:03:57 +0000</pubDate>
		<dc:creator>iXce</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[~home]]></category>

		<guid isPermaLink="false">http://guillaume.segu.in/blog/?p=116</guid>
		<description><![CDATA[Building dynamic forms with Django newforms module is quite undocumented, though it&#8217;s quite easy to do. All you need to do is to hook up the __init__ function of the form, raise the __init__ to the parent forms.Form class and then add your dynamically generated fields to self.fields dict. Here is a quick snippet demonstrating [...]]]></description>
			<content:encoded><![CDATA[<p>Building dynamic forms with Django newforms module is quite undocumented, though it&#8217;s quite easy to do. All you need to do is to hook up the __init__ function of the form, raise the __init__ to the parent forms.Form class and then add your dynamically generated fields to self.fields dict.</p>
<p>Here is a quick snippet demonstrating it, which will create a form with n integer fields named from 0 to (n &#8211; 1), but you will easily be able to heavily extend it.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django <span style="color: #ff7700;font-weight:bold;">import</span> newforms <span style="color: #ff7700;font-weight:bold;">as</span> forms
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> MyForm <span style="color: black;">&#40;</span>forms.<span style="color: black;">Form</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, n, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        forms.<span style="color: black;">Form</span>.<span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, n<span style="color: black;">&#41;</span>:
            field = forms.<span style="color: black;">IntegerField</span> <span style="color: black;">&#40;</span>label = <span style="color: #483d8b;">&quot;%d&quot;</span> <span style="color: #66cc66;">%</span> i, required = <span style="color: #008000;">True</span>,
                                        min_value = <span style="color: #ff4500;">0</span>, max_value = <span style="color: #ff4500;">200</span><span style="color: black;">&#41;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">fields</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;%d&quot;</span> <span style="color: #66cc66;">%</span> i<span style="color: black;">&#93;</span> = field</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://guillaume.segu.in/blog/home/116/tip-of-the-day-dynamic-forms-with-django-newforms/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

