<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.kunxi.org/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Refactor the Life</title>
	
	<link>http://kunxi.org</link>
	<description>Yet another code monkey blog.</description>
	<lastBuildDate>Tue, 08 Sep 2009 17:42:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.kunxi.org/rtl" /><feedburner:info uri="rtl" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>rtl</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item>
		<title>HOWTO setup Trac with Mercurial and Nginx</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/4E5DJHdg8uA/</link>
		<comments>http://kunxi.org/archives/2009/09/howto-setup-trac-with-mercurial-and-nginx/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 23:15:59 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=388</guid>
		<description><![CDATA[&#8220;A goal is a dream with a deadline.&#8221;  &#8212; Napleon Hill
Besides the configuration for Mercurial the preferred DVCS, A bug-tracking and project management tool is required to manage the timeline. Trac is my all-time favorite and it supports the Mercurial via TracMercurial plugin.
Before we move on, we need to rebuild the python-2.6 to get [...]]]></description>
			<content:encoded><![CDATA[<p><em>&#8220;A goal is a dream with a deadline.&#8221;  &#8212; Napleon Hill</em></p>
<p>Besides the configuration for <a href="www.selenic.com/mercurial/">Mercurial</a> the preferred DVCS, A bug-tracking and project management tool is required to manage the timeline. <a href="http://trac.edgewall.org/">Trac</a> is my all-time favorite and it supports the Mercurial via TracMercurial plugin.</p>
<p>Before we move on, we need to rebuild the python-2.6 to get some missing modules with C extensions back:</p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="co0"># Install the following development package to build python modules</span><br />
<span class="kw2">sudo</span> yum <span class="kw2">install</span> bzip2-devel readline-devel gdbm-devel bsddb-devel ncurses-devel db4-devel sqlite-devel<br />
<span class="co0"># Rebuild the Python-2.6</span><br />
.<span class="sy0">/</span>configure <span class="re5">&#8211;prefix</span>=<span class="sy0">/</span>opt<span class="sy0">/</span>python<br />
<span class="kw2">make</span> <span class="sy0">&amp;&amp;</span> <span class="kw2">sudo</span> <span class="kw2">make</span> <span class="kw2">install</span></div>
</div>
<p><strong>Install Trac and MercurialTrac</strong></p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">sudo</span> <span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin<span class="sy0">/</span>easy_install http:<span class="sy0">//</span>svn.edgewall.org<span class="sy0">/</span>repos<span class="sy0">/</span>trac<span class="sy0">/</span>tags<span class="sy0">/</span>trac-0.11<br />
<span class="re2">PATH</span>=<span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin:<span class="re1">$PATH</span> <span class="kw2">sudo</span> trac-admin <span class="sy0">/</span>var<span class="sy0">/</span>trac<span class="sy0">/</span>bloggo<span class="sy0">/</span> initenv</div>
</div>
<p>When repository type is prompted,  use <strong>hg</strong> instead.</p>
<p>Then we install the MercurialTrac plugin globally, so it can be used later for other projects:</p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">svn</span> <span class="kw2">co</span> http:<span class="sy0">//</span>svn.edgewall.com<span class="sy0">/</span>repos<span class="sy0">/</span>trac<span class="sy0">/</span>sandbox<span class="sy0">/</span>mercurial-plugin-0.11 <br />
<span class="kw3">cd</span> mercurial-plugin-0.11 <br />
python setup.py bdist_egg<br />
<span class="kw2">sudo</span> <span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin<span class="sy0">/</span>easy_install dist<span class="sy0">/</span>TracMercurial-0.11.0.7-py2.6.egg</div>
</div>
<p>Now it is time to run Trac in <a href="trac.edgewall.org/wiki/TracStandalone">TracStandalone</a> mode to verify the configuration in Trac side.</p>
<p><strong>Configure Nginx to and FastCGI</strong><br />
The Trac instance is loaded via spawn-fcgi as other web applications using <a href="http://static.kunxi.org/howto-setup-trac-with-mercurial-and-nginx/fcgi-trac">this script</a>. The PATH is overrided to use python-2.6, and  <em>TRAC_ENV_PARENT_DIR</em> is exported explicitly. I doubt this may contaminate other Trac instances, I will fix it later if so.</p>
<p>The multiple Trac instances are located in the <em>/projects/</em> path, and we need HTTP Basic Auth to protect the entry point.</p>
<div class="codesnip-container" >location ~ /projects/[^/]+/login {<br />
            auth_basic &#8220;Trac&#8221;;<br />
            auth_basic_user_file &#8220;/var/trac/devpasswd&#8221;;</p>
<p>            fastcgi_split_path_info ^(/projects)(/.*)$;<br />
            fastcgi_param  PATH_INFO $fastcgi_path_info;<br />
            fastcgi_param  AUTH_USER          $remote_user;<br />
            fastcgi_param  REMOTE_USER        $remote_user;<br />
            include       fastcgi_params;<br />
            fastcgi_pass   127.0.0.1:9004;<br />
        }</p>
<p>        location /projects/ {<br />
            fastcgi_split_path_info ^(/projects)(/.*)$;<br />
            fastcgi_param  PATH_INFO $fastcgi_path_info;<br />
            fastcgi_param  AUTH_USER          $remote_user;<br />
            fastcgi_param  REMOTE_USER        $remote_user;<br />
            include       fastcgi_params;<br />
            fastcgi_pass   127.0.0.1:9004;<br />
        }</p></div>
<p>Any thoughts to refactor the configuration to eliminate the duplication?</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/09/howto-setup-the-mercurial-with-nginx-in-centos-4/" rel="bookmark">HOWTO setup the Mercurial with Nginx in CentOS 4</a></li><li><a href="http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/" rel="bookmark">HOWTO: Serve virtual host with Nginx</a></li><li><a href="http://kunxi.org/archives/2007/04/meet-mr-dtrace-part-1/" rel="bookmark">Meet Mr. DTrace - Part 1</a></li><li><a href="http://kunxi.org/archives/2008/02/howto-deploy-django-in-jumpline/" rel="bookmark">HOWTO deploy Django in Jumpline</a></li><li><a href="http://kunxi.org/archives/2007/04/howto-install-cell-environment-in-gentoo/" rel="bookmark">HOWTO install CELL Environment in Gentoo</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=4E5DJHdg8uA:EmeeStAgVxI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=4E5DJHdg8uA:EmeeStAgVxI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=4E5DJHdg8uA:EmeeStAgVxI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/4E5DJHdg8uA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/09/howto-setup-trac-with-mercurial-and-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/09/howto-setup-trac-with-mercurial-and-nginx/</feedburner:origLink></item>
		<item>
		<title>HOWTO setup the Mercurial with Nginx in CentOS 4</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/dyHFQQdo0yk/</link>
		<comments>http://kunxi.org/archives/2009/09/howto-setup-the-mercurial-with-nginx-in-centos-4/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 19:34:16 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=381</guid>
		<description><![CDATA[As my VPS provider Advantagecom Networks gracefully acknowledged the life-time promotion I enrolled in one year ago, I decided to settle in this ISP. Which also means that I am stuck to the current configuration: python-2.3.4 in CentOS 4.
Unlike Gentoo, there is no shortcut to upgrade CentOS 4 to CentOS 5 seamlessly. Some adventurous pilots [...]]]></description>
			<content:encoded><![CDATA[<p>As my VPS provider <a href="http://www.advantagecom.net/">Advantagecom Networks</a> gracefully acknowledged the life-time promotion I enrolled in one year ago, I decided to settle in this ISP. Which also means that I am stuck to the current configuration: python-2.3.4 in CentOS 4.</p>
<p>Unlike Gentoo, there is no shortcut to upgrade CentOS 4 to CentOS 5 seamlessly. Some adventurous pilots tried and failed miserably, also the customer service disregarded this approach. I wish I could reinstall the OS in SSH session. So we fallback the plan B to update the essential components only.</p>
<p><strong>Update the python</strong></p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">wget</span> http:<span class="sy0">//</span>www.python.org<span class="sy0">/</span>ftp<span class="sy0">/</span>python<span class="sy0">/</span>2.6.2<span class="sy0">/</span>Python-2.6.2.tar.bz2<br />
<span class="kw2">tar</span> xvfj Python-2.6.2.tar.bz2<br />
<span class="kw3">cd</span> Python-2.6.2<br />
.<span class="sy0">/</span>configure <span class="re5">&#8211;prefix</span>=<span class="sy0">/</span>opt<br />
<span class="kw2">make</span> <span class="sy0">&amp;&amp;</span> <span class="kw2">sudo</span> <span class="kw2">make</span> <span class="kw2">install</span></div>
</div>
<p><strong>Update the setuptools for python-2.6</strong><br />
Temporarily override the PATH to use python-2.6:</p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">wget</span> http:<span class="sy0">//</span>pypi.python.org<span class="sy0">/</span>packages<span class="sy0">/</span><span class="nu0">2.6</span><span class="sy0">/</span>s<span class="sy0">/</span>setuptools<span class="sy0">/</span>setuptools-0.6c9-py2.6.egg<span class="co0">#md5=ca37b1ff16fa2ede6e19383e7b59245a</span><br />
<span class="re2">PATH</span>=<span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin:<span class="re1">$PATH</span> <span class="kw2">sudo</span> <span class="kw2">sh</span> build<span class="sy0">/</span>setuptools-0.6c9-py2.6.egg</div>
</div>
<p>By default, easy_install will be installed into <em>/opt/python/bin</em></p>
<p><strong>Install Mercurial and flup</strong></p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="kw2">sudo</span> <span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin<span class="sy0">/</span>easy_install mercurial<br />
<span class="kw2">sudo</span> <span class="sy0">/</span>opt<span class="sy0">/</span>python<span class="sy0">/</span>bin<span class="sy0">/</span>easy_install flup</div>
</div>
<p><strong>Setup the Mercurial repository</strong></p>
<div class="codesnip-container" >
<div class="bash codesnip" style="font-family:monospace;"><span class="co0"># Setup the user privilege</span><br />
<span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>groupadd hg<br />
<span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>useradd <span class="re5">-g</span> hg <span class="re5">-s</span> <span class="sy0">/</span>bin<span class="sy0">/</span><span class="kw2">false</span> hg<br />
<span class="kw2">sudo</span> <span class="kw2">mkdir</span> <span class="sy0">/</span>var<span class="sy0">/</span>hg<br />
<span class="kw2">sudo</span> <span class="kw2">chown</span> hg:hg <span class="sy0">/</span>var<span class="sy0">/</span>hg<br />
<span class="kw2">sudo</span> <span class="kw2">chmod</span> g+<span class="kw2">w</span> <span class="sy0">/</span>var<span class="sy0">/</span>hg<br />
<span class="co0"># Add myself to hg group</span><br />
<span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>usermod <span class="re5">-G</span> hg bookstack<br />
hg init <span class="sy0">/</span>var<span class="sy0">/</span>hg<span class="sy0">/</span>bloggo</div>
</div>
<p><strong>Serve Mercurial via flup</strong><br />
Copy the fastcgi script <em>hgwebdir.fcgi</em> from <em>/usr/share/doc/mercurial-1.3.1/contrib/</em>, and configure the hgweb.config:</p>
<div class="codesnip-container" >[paths]<br />
/ = /var/hg/**</p>
<p>[web]<br />
style = monoblue<br />
allow_push = *<br />
push_ssl = false</p></div>
<p>Spawn the fastcgi script using <a href="http://static.kunxi.org/howto-setup-the-mercurial-with-nginx-in-centos-4/fcgi-hg">this script</a>.<br />
<strong>Note:</strong> the PATH environment variable needs to be overrided by <em>/opt/python/bin</em> to use python-2.6.</p>
<p><strong>Install Nginx</strong><br />
Just follow this <a href="http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/">HOWTO</a>.</p>
<p>Now we need to setup the Nginx to expose the Mercurial repository in <em>nginx.conf</em>:</p>
<div class="codesnip-container" ># HG<br />
    server {<br />
        listen       80;<br />
        server_name dev.kunxi.org;<br />
        root /var/web/$host;<br />
        access_log  logs/$host.access.log  main;<br />
        error_log   logs/$host.error.log;</p>
<p>        location /hg/ {<br />
            fastcgi_split_path_info ^(/hg)(/.*)$;<br />
            fastcgi_param  PATH_INFO $fastcgi_path_info;<br />
            include       fastcgi_params;<br />
            limit_except GET HEAD {<br />
              deny all;<br />
            }<br />
            fastcgi_pass   127.0.0.1:9003;<br />
        }<br />
    }</p></div>
<p>The directive <em>limit_except</em> in Nginx seem not to work as expected. If we add <em>auth_basic</em> in limit_except block, Nginx will ask for the credential first, then tries to server the static content in /hg/project_name instead of passing the request to the underlying fastcgi. I encountered the similar problem in MoinMoin setup, so I just deny all the POST operations, and use SSH instead. This is not the perfect solution for sure, but it works fine for personal source depot.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/09/howto-setup-trac-with-mercurial-and-nginx/" rel="bookmark">HOWTO setup Trac with Mercurial and Nginx</a></li><li><a href="http://kunxi.org/archives/2008/09/howto-server-virtual-host-with-nginx/" rel="bookmark">HOWTO: Serve virtual host with Nginx</a></li><li><a href="http://kunxi.org/archives/2008/02/howto-deploy-django-in-jumpline/" rel="bookmark">HOWTO deploy Django in Jumpline</a></li><li><a href="http://kunxi.org/archives/2008/09/vps-warm-up/" rel="bookmark">Move to the new VPS, Yummy</a></li><li><a href="http://kunxi.org/archives/2008/03/minihowto-deploy-moinmoin-in-jumpline/" rel="bookmark">MiniHOWTO deploy MoinMoin in Jumpline</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=dyHFQQdo0yk:9-5MWj0UVmE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=dyHFQQdo0yk:9-5MWj0UVmE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=dyHFQQdo0yk:9-5MWj0UVmE:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/dyHFQQdo0yk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/09/howto-setup-the-mercurial-with-nginx-in-centos-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/09/howto-setup-the-mercurial-with-nginx-in-centos-4/</feedburner:origLink></item>
		<item>
		<title>Authorize the REST web service</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/91dihafmJvQ/</link>
		<comments>http://kunxi.org/archives/2009/04/authorize-the-rest-web-service/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 22:27:23 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[pattee django REST]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=366</guid>
		<description><![CDATA[Once we step into the REST territory, session-based AuthenticationMiddleware is no longer an option due to the violation of stateless principle. Digest authentication seems one of the very few options left for this situation. The basic concept is that the client and server share a private secret key, the client signs the HTTP request and [...]]]></description>
			<content:encoded><![CDATA[<p>Once we step into the REST territory, session-based AuthenticationMiddleware is no longer an option due to the violation of stateless principle. Digest authentication seems one of the very few options left for this situation. The basic concept is that the client and server share a private secret key, the client signs the HTTP request and the server validates the signature before further operations. </p>
<p>There is no off-the-shelf digest authentication middleware available yet, let&#8217;s roll up sleeves and home-brew our own or more specifically, shameless copy the S3(<a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?RESTAuthentication.html">authentication spec</a>) python library with slightly simplification: </p>
<p>The entities under the radar are cut to five:  <em>HTTP verb</em>, <em>Content-Length</em>, <em>Content-Type</em>, <em>Date</em> and the body. The HTTP verb and content type specify the REST request, the date prevents the man-in-the-middle replay attack. The signature is then digested on the stream, and appended into <em>Authentication</em> header.<br />
<strong>Update</strong>: URL is also essential, the man-in-the-middle may record the REST operation in one entry, and replay in another entry point.</p>
<p>It is also pretty straightforward to wrap up the digest authentication as a middleware: create a new model named as <em>Token</em> and add <em>access_id</em> and <em>acess_key </em>pair, also the <em>User</em> as foreign key. We could just copy <em>AuthenticateMiddleware</em> and override <em>get_user</em> method to integrate the digest validation. You may check the <a href="http://my-trac.assembla.com/pattee/changeset?new=%2F%4022&#038;old=%2F%4021">revision 21 to 22 on pattee</a> for more details if you are interested in.</p>
<p>There is another issue worthy our attention: both digest and session-based authentications are required, the latter is the gate keeper to access admin interface to manages the token used for the former, but they may not play well together: the resource for the cookie management in the server side is totally wasted to handle REST requests, and furthermore, it leaves the door open for security exploit by stolen cookies. We will discuss this issue later, stay tune.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/01/restful-django-practice/" rel="bookmark">RESTful Django practice</a></li><li><a href="http://kunxi.org/archives/2007/09/learning-django-by-example4-first-user-authenticated/" rel="bookmark">Learning Django by Example(4): First user authenticated</a></li><li><a href="http://kunxi.org/archives/2008/09/reverse-mashup/" rel="bookmark">Reverse mashup</a></li><li><a href="http://kunxi.org/archives/2007/03/howto-secure-your-meebo/" rel="bookmark">HOWTO secure your Meebo?</a></li><li><a href="http://kunxi.org/archives/2008/01/pythonsoap-second-encounter/" rel="bookmark">Python/SOAP: second encounter</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=91dihafmJvQ:uTXnt66pPVw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=91dihafmJvQ:uTXnt66pPVw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=91dihafmJvQ:uTXnt66pPVw:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/91dihafmJvQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/04/authorize-the-rest-web-service/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/04/authorize-the-rest-web-service/</feedburner:origLink></item>
		<item>
		<title>Book Review: Django 1.0 Template Development</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/eaiChdzkSYQ/</link>
		<comments>http://kunxi.org/archives/2009/03/book-review-django-10-template-development/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 06:42:02 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=357</guid>
		<description><![CDATA[This is not a paid review, I did not receive a dime from author, publisher or the affiliated; however, I did get a free copy of the book, so some harsh critics may be sugar-coated. Read with caution.
Though I am a die-hard RTFM guy, it never hurt to take the advantage of expertise of the [...]]]></description>
			<content:encoded><![CDATA[<div class="warning">This is <strong>not</strong> a paid review, I did not receive a dime from author, publisher or the affiliated; however, I did get a free copy of the book, so some harsh critics may be sugar-coated. Read with caution.</div>
<p>Though I am a die-hard RTFM guy, it never hurt to take the advantage of expertise of the peers. <a href="http://www.packtpub.com/django-1.0-template-design-practical-guide/book">Django 1.0 Template Development</a> focuses on a relatively narrow topic, the template system of Django. The author puts himself in an dilemma: he expects the target audience to have basic ideas of Django system, but still has to go over all the hassles(not really though) to kick start a new project to make the book self-contained. I think the author did a great job for a beginners, but I still highly recommend the official <a href="http://www.djangobook.com/">DjangoBook</a>, <a href="http://docs.djangoproject.com/en/dev/intro/tutorial01/">tutorial</a> and <a href="http://docs.djangoproject.com/en/dev/">documentation</a>.</p>
<p>After two chapters warm-up, Chapter 3 shows the magic of <em>Context</em> and <em>RequestContext</em>. It is interesting to see how the project evolve from the low-level operation to the shortcuts. Chapter 4 introduces the built-in tags in the toolbox. Chapter 5 and 6 demonstrates the template inheritance and how multiple templates are served. In chapter 7, the developers can extend their toolbox by creating new filter tags. Chapter 9 gives series examples for admin UI customization. Chapter 8 and 10 are about the performance, pagination and cache. Last but not the least, L10N in chapter 11.</p>
<p>The examples in each chapter is atomic for easy understanding, but in my humble opinion, most of them do not impress the readers the power of Django. The framework shines to solve BIG and complex questions. I just wonder what if the author starts a much more ambitious project with complicated specification, and later decompose it to small tasks and address them in each chapter to make the point, just like <a href="www.diveintopython.org/">Dive into Python</a> does.</p>
<p>Furthermore, I would appreciate if the author could share more first-hand experience with readers. Engineering is always about question-solving. The framework is naturally easy to learn, otherwise, why bother? But it may suck in the big time if it does not scale. Any real world case would help to establish the confidence for further acceptance.</p>
<p>The bottom line: a good book for beginners, some chapters are quite beefy for the topic. As Django is a fast-evolving project, I hope the author will bring more juicy examples in the future edition.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/01/restart-the-django-engine/" rel="bookmark">Restart the Django engine</a></li><li><a href="http://kunxi.org/archives/2007/09/learning-django-by-example1-start-the-engine/" rel="bookmark">Learning Django by Example(1): Start the Engine</a></li><li><a href="http://kunxi.org/archives/2008/01/learning-django-by-example7-attach-a-tag/" rel="bookmark">Learning Django by Example(7) Attach a tag</a></li><li><a href="http://kunxi.org/archives/2007/02/c-study-note-3-typename-vs-class/" rel="bookmark">C++ Study Note (3) - typename, class and template</a></li><li><a href="http://kunxi.org/archives/2007/09/learning-django-by-example3-just-works/" rel="bookmark">Learning Django by Example(3): Just works</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=eaiChdzkSYQ:7mvlotvcfTI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=eaiChdzkSYQ:7mvlotvcfTI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=eaiChdzkSYQ:7mvlotvcfTI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/eaiChdzkSYQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/03/book-review-django-10-template-development/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/03/book-review-django-10-template-development/</feedburner:origLink></item>
		<item>
		<title>How to PUT a file in Django</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/9DBqhS6Qx1E/</link>
		<comments>http://kunxi.org/archives/2009/01/how-to-put-a-file-in-django/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 07:38:15 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pattee]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=355</guid>
		<description><![CDATA[Once we decide to go for PUT instead of POST, we step out the comfort zone of django, there is no mapped form filed, no validation, we have to deal with the raw WSGI interface by ourselves. Anyway, we can still use the the django.core.file.File.
If we dig into the source code, the django.core.file.File defines: open, [...]]]></description>
			<content:encoded><![CDATA[<p>Once we decide to go for PUT instead of POST, we step out the comfort zone of django, there is no mapped form filed, no validation, we have to deal with the raw WSGI interface by ourselves. Anyway, we can still use the the <em>django.core.file.File</em>.</p>
<p>If we dig into the source code, the <em>django.core.file.File</em> defines: <em>open</em>, <em>close</em>, <em>read</em>, <em>tell</em>, <em>seek</em>, <em>flush</em> and some other django-specific operations, like <em>chunks</em>, <em>readlines</em>, <em>xreadlines</em> etc. <a href="http://code.djangoproject.com/ticket/8501">Ticket #8501</a> glues <em>File</em> and file object when <em>chunks</em> method is missing.</p>
<p>It is interesting that the interface <em>File</em> exposed explicitly requires that the underlying file object supports random access, which is most likely overqualified for general use. Sometimes, <strong>less is more</strong>. And it implicitly expects <em>read</em> will return EOF, which is also not true for <em>WSGI.input</em>. So we end up to brew our own:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="kw1">class</span> SocketFile<span class="br0">&#40;</span>File<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="co1"># Only forward access is allowed</span><br />
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw3">socket</span>, size<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">super</span><span class="br0">&#40;</span>SocketFile, <span class="kw2">self</span><span class="br0">&#41;</span>.<span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw3">socket</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._size = <span class="kw2">int</span><span class="br0">&#40;</span>size<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pos = 0</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> read<span class="br0">&#40;</span><span class="kw2">self</span>, num_bytes=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> num_bytes <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_bytes = <span class="kw2">self</span>._size &#8211; <span class="kw2">self</span>._pos<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_bytes = <span class="kw2">min</span><span class="br0">&#40;</span>num_bytes, <span class="kw2">self</span>._size &#8211; <span class="kw2">self</span>._pos<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._pos += num_bytes<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>.<span class="kw2">file</span>.<span class="me1">read</span><span class="br0">&#40;</span>num_bytes<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> tell<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">self</span>._pos</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> seek<span class="br0">&#40;</span><span class="kw2">self</span>, position<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span></div>
</div>
<p>The <em>SocketFile</em> object is initialized with the length of the socket file object, aka CONTENT_LENGTH, the <em>read</em> method gatekeeps the operation to return EOF. <em>seek</em> is inherited from <em>File</em>, so just bypass it. Just wrap the raw WSGI.input with <em>SocketFile</em>, and use it as <em>File</em>. Please check <a href="http://my-trac.assembla.com/pattee/browser/trunk/bookshelf/views.py?rev=21">views.py</a> for the usage.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/01/customize-the-django-newform-admin-ui/" rel="bookmark">Customize the Django newform admin UI</a></li><li><a href="http://kunxi.org/archives/2007/10/learning-django-by-example6-ajax-file-upload/" rel="bookmark">Learning Django by Example(6): AJAX File Upload</a></li><li><a href="http://kunxi.org/archives/2008/02/bite-by-memoryerror/" rel="bookmark">Bite by MemoryError</a></li><li><a href="http://kunxi.org/archives/2008/01/learning-django-by-example7-attach-a-tag/" rel="bookmark">Learning Django by Example(7) Attach a tag</a></li><li><a href="http://kunxi.org/archives/2006/07/return-of-lex/" rel="bookmark">Return of the Lex</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=9DBqhS6Qx1E:IHgTbiOyYiE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=9DBqhS6Qx1E:IHgTbiOyYiE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=9DBqhS6Qx1E:IHgTbiOyYiE:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/9DBqhS6Qx1E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/01/how-to-put-a-file-in-django/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/01/how-to-put-a-file-in-django/</feedburner:origLink></item>
		<item>
		<title>Is get lazily evaluated?</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/7tygPRx4K-I/</link>
		<comments>http://kunxi.org/archives/2009/01/is-get-lazily-evaluated/#comments</comments>
		<pubDate>Sun, 25 Jan 2009 07:32:34 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=353</guid>
		<description><![CDATA[What do you think about a dict.get operation does?

d.get&#91;the_key, fall_back&#93;

Something like this?

try:
&#160; &#160; return d&#91;the_key&#93;
except KeyError:
&#160; &#160; return fall_back

That is my intuition, just like C&#8217;s short-circuit evaluation, the fallback is not evaluated until the requested key does not exist. Unfortunately, this not try, for example:

&#62;&#62;&#62; d = &#123;1: 3, 2:4&#125;
&#62;&#62;&#62; def f&#40;&#41;:
&#8230; &#160; &#160; print [...]]]></description>
			<content:encoded><![CDATA[<p>What do you think about a dict.get operation does?</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;">d.<span class="me1">get</span><span class="br0">&#91;</span>the_key, fall_back<span class="br0">&#93;</span></div>
</div>
<p>Something like this?</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="kw1">try</span>:<br />
&nbsp; &nbsp; <span class="kw1">return</span> d<span class="br0">&#91;</span>the_key<span class="br0">&#93;</span><br />
<span class="kw1">except</span> <span class="kw2">KeyError</span>:<br />
&nbsp; &nbsp; <span class="kw1">return</span> fall_back</div>
</div>
<p>That is my intuition, just like C&#8217;s <a href="http://en.wikipedia.org/wiki/Short-circuit_evaluation">short-circuit evaluation</a>, the fallback is not evaluated until the requested key does not exist. Unfortunately, this not try, for example:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="sy0">&gt;&gt;&gt;</span> d = <span class="br0">&#123;</span>1: 3, 2:4<span class="br0">&#125;</span><br />
<span class="sy0">&gt;&gt;&gt;</span> <span class="kw1">def</span> f<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&#8230; &nbsp; &nbsp; <span class="kw1">print</span> <span class="nu0">7</span><br />
&#8230; <br />
<span class="sy0">&gt;&gt;&gt;</span> d.<span class="me1">get</span><span class="br0">&#40;</span><span class="nu0">3</span>, f<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="nu0">7</span><br />
<span class="sy0">&gt;&gt;&gt;</span> d.<span class="me1">get</span><span class="br0">&#40;</span><span class="nu0">1</span>, f<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="nu0">7</span><br />
<span class="nu0">3</span></div>
</div>
<p>f is always evaluated regardless whether the key exists or not. </p>
<p>This is expected behavior from the compiler/interpreter perspective, the fallback value needs to be reduced first <strong>before</strong> <em>get</em> is invoked. It would be nice to evaluate <em>get</em> lazily to avoid the expensive <em>try/except</em> mechanism; or tedious has_key test. </p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2007/11/one-up-to-python-expert-1-decorators/" rel="bookmark">One up to Python expert (1) - Decorators</a></li><li><a href="http://kunxi.org/archives/2008/10/wys-is-not-always-wyg-in-pythonre/" rel="bookmark">WYS is not always WYG in python.re</a></li><li><a href="http://kunxi.org/archives/2006/12/debugging-web2-10-pitfalls-for-the-javascript-developers/" rel="bookmark">Debugging Web(2) -  10 Pitfalls for the JavaScript Developers</a></li><li><a href="http://kunxi.org/archives/2007/02/c-study-note-3-typename-vs-class/" rel="bookmark">C++ Study Note (3) - typename, class and template</a></li><li><a href="http://kunxi.org/archives/2007/05/c-study-note2-cast-the-light-to-the-darkness/" rel="bookmark">C++ Study Note(2): Cast the light to the darkness</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=7tygPRx4K-I:OvLlwpFiXvI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=7tygPRx4K-I:OvLlwpFiXvI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=7tygPRx4K-I:OvLlwpFiXvI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/7tygPRx4K-I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/01/is-get-lazily-evaluated/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/01/is-get-lazily-evaluated/</feedburner:origLink></item>
		<item>
		<title>RESTful Django practice</title>
		<link>http://feeds.kunxi.org/~r/rtl/~3/Q2gvVwfin_4/</link>
		<comments>http://kunxi.org/archives/2009/01/restful-django-practice/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 07:29:21 +0000</pubDate>
		<dc:creator>bookstack</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pattee]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://kunxi.org/?p=343</guid>
		<description><![CDATA[After several rounds reading RESTfull Web Services, I still have feeble confidence on my understanding the hyped REST idea, so please never hesitate to criticize, suggest in the comment.
Expose the resources
A book can be easily be identified by ISBN or EAN, however, it may stand for the specific book other than other books, or it [...]]]></description>
			<content:encoded><![CDATA[<p>After several rounds reading <a href="http://oreilly.com/catalog/9780596529260/">RESTfull Web Services</a>, I still have feeble confidence on my understanding the hyped REST idea, so please never hesitate to criticize, suggest in the comment.</p>
<h1>Expose the resources</h1>
<p>A book can be easily be identified by ISBN or EAN, however, it may stand for the specific book other than other books, or it refers an eBook instance to for content presentation. We use an additional argument, <em>format</em> to differentiate them:</p>
<div class="codesnip-container" >/bookshelf/books/(isbn|ean)?format=(pdf|chm|&#8230;|json)</div>
<p><strong>UPDATE</strong> A better approach is to use the pseudo file:</p>
<div class="codesnip-container" >/bookshelf/books/(isbn|ean)(.(pdf|chm|&#8230;|json))</div>
<p>The default format is JSON, the server will render the meta data and available eBook formats in JSON. </p>
<table class="enum">
<tbody>
<tr>
<th>Client request</th>
<th>Server response</th>
</tr>
<tr>
<td>GET ../isbn(.pdf)</td>
<td>
<p>Book meta data and available formats, or the eBook data.</p>
<p><em>404/Not Found</em> if the book does not exists</p>
</td>
</tr>
<tr>
<td>PUT ../isbn</td>
<td>
<p><em>201/Created</em> if the server create a new Book instance.</p>
<p><em>200/OK</em> if the book exists.</p>
<p><em>400/Bad Request</em> if the ISBN is invalid.</p>
</td>
</tr>
<tr>
<td>PUT ../isbn.pdf</td>
<td>
<p><em>201/Created</em> if the specified format eBook does not exist.</p>
<p><em>200/OK</em> if the eBook exists. The admin needs to moderate later.</p>
<p><em>400/Bad Request</em> if the ISBN is invalid.</p>
</td>
</tr>
<tr>
<td><del datetime="2009-01-16T00:05:57+00:00">HEAD ../isbn</del></td>
<td>
<p><del datetime="2009-01-16T00:05:57+00:00">Available formats.</del></p>
<p><del datetime="2009-01-16T00:05:57+00:00"><em>404/Not Found</em> if the book does not exists.</del></p>
</td>
</tr>
<tr>
<td>HEAD ../isbn.pdf</td>
<td>
<p>The content length and other information about the file.</p>
<p><em>404/Not Found</em> if the book does not exists.</p>
</td>
</tr>
<tr>
<td>DELETE ../isbn</td>
<td>
<p>200/Accepted Remove the Book instance if no related eBook exists.</p>
<p><em>404/Not Found</em> if the book does not exists.</p>
<p><em>409/Conflict</em> if there exist at least one eBook related.</p>
</td>
</tr>
<tr>
<td>DELETE ../isbn.pdf</td>
<td>
<p>200/Accepted Remove the eBook instance, the admin needs to moderate.</p>
<p><em>404/Not Found</em> if the book does not exists.</p>
</td>
</tr>
</tbody>
</table>
<p>Furthermore, the URL representation is supposed to be discoverable. So we add two boring URL:</p>
<table class="enum">
<tbody>
<tr>
<th>Client request</th>
<th>Server response</th>
</tr>
<tr>
<td>GET /bookshelf/</td>
<td>
<p>Available list, currently only books supported.</p>
</td>
</tr>
<tr>
<td>GET /bookshelf/books</td>
<td>
<p>All books with pagination, <em>?page=n</em></p>
</td>
</tr>
</tbody>
</table>
<h1>Serialization</h1>
<p>There exists a generic RESTful Django project,<a href="http://code.google.com/p/django-rest-interface/"> django-rest-interface</a>, no surprise it takes the built-in JSON serializer.</p>
<p>The default JSON serializer is convenient, but from my understanding, it is more or less gears towards the round trip of data serialization, while we favor presentation only:</p>
<ul>
<li>Too much database details exposed to the end users.</li>
<li>ForeignKey and ManyToMany are interpreted as external link using the id field. </li>
</ul>
<p>Furthermore, the JSON serializer is not lazy enough: the data has to be fetched from the database and stored in the memory before it is dumped to the stream. This may result in a serious scaling issue. The side-effect of the writing policy make it impossible to serialize in a recursive fashion, just because the stream has not been flushed until <strong>all</strong> the objects have been addressed. Otherwise, the ForeighKey and ManyToMany can be easily addressed. A better solution is to take the similar approach as SAX does. The tags are emitted recursively once a new object needs to be serialized. </p>
<p>We will discuss the Pattee&#8217;s implementation next time.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://kunxi.org/archives/2009/01/customize-the-django-newform-admin-ui/" rel="bookmark">Customize the Django newform admin UI</a></li><li><a href="http://kunxi.org/archives/2007/09/learning-django-by-example3-just-works/" rel="bookmark">Learning Django by Example(3): Just works</a></li><li><a href="http://kunxi.org/archives/2007/09/learning-django-by-example2-show-me-your-data/" rel="bookmark">Learning Django by Example(2): Show me your data</a></li><li><a href="http://kunxi.org/archives/2009/01/tip-reuse-django-view-in-urlconf/" rel="bookmark">Tip: Reuse Django view in urlconf</a></li><li><a href="http://kunxi.org/archives/2007/10/learning-django-by-example6-ajax-file-upload/" rel="bookmark">Learning Django by Example(6): AJAX File Upload</a></li></ul></div><div class="feedflare">
<a href="http://feeds.kunxi.org/~ff/rtl?a=Q2gvVwfin_4:M1fUMIAzEBk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rtl?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.kunxi.org/~ff/rtl?a=Q2gvVwfin_4:M1fUMIAzEBk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rtl?i=Q2gvVwfin_4:M1fUMIAzEBk:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rtl/~4/Q2gvVwfin_4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://kunxi.org/archives/2009/01/restful-django-practice/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://kunxi.org/archives/2009/01/restful-django-practice/</feedburner:origLink></item>
	</channel>
</rss>
