<?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>LuckyDonkey</title>
	<atom:link href="http://www.luckydonkey.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.luckydonkey.com</link>
	<description>Never knowingly knowing narwhals</description>
	<lastBuildDate>Sat, 19 Mar 2011 13:59:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>MiniTune released</title>
		<link>http://www.luckydonkey.com/2011/03/19/minitune-released/</link>
		<comments>http://www.luckydonkey.com/2011/03/19/minitune-released/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 13:56:52 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ExecutionUnit]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=260</guid>
		<description><![CDATA[Over on my company blog I've written a short blog about the release of MiniTune (with the help of Apple's app store).]]></description>
			<content:encoded><![CDATA[<p>Over on my company blog I've <a href="http://www.executionunit.com/2011/03/18/minitune-released/">written a short blog</a> about the release of MiniTune (with the help of Apple's app store).</p>
<p><a href="http://itunes.apple.com/gb/app/minitune/id420181726"><img src="http://www.luckydonkey.com/wp-content/uploads/2011/03/MiniTune-AvailableInMacAppStore.jpg" alt="MiniTune available on the App Store" title="MiniTune-AvailableInMacAppStore" width="218" height="292" class="aligncenter size-full wp-image-261" /></a></p>
<p><map name='google_ad_map_260_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/260?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_260_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=260&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2011%2F03%2F19%2Fminitune-released%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2011/03/19/minitune-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Project Euler</title>
		<link>http://www.luckydonkey.com/2011/01/02/project-euler/</link>
		<comments>http://www.luckydonkey.com/2011/01/02/project-euler/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 12:59:12 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=256</guid>
		<description><![CDATA[After a LONG hiatus for some reason I started doing Project Euler problems again. I had been keeping my solutions in SVN but my old repository died a few year ago. Luckily I had a local backup. Here is my status I think I'll pop that image in the right hand column Happy New Year.]]></description>
			<content:encoded><![CDATA[<p>After a LONG hiatus for some reason I started doing <a href="http://projecteuler.net/">Project Euler</a> problems again. I had been keeping my solutions in SVN but my old repository died a few year ago. Luckily I had a local backup. </p>
<p>Here is my status<br />
<img src="http://projecteuler.net/profile/dazzawazza.png" alt="dazzawazza's Project Euler Level" /></p>
<p>I think I'll pop that image in the right hand column <img src='http://www.luckydonkey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Happy New Year.</p>
<p><map name='google_ad_map_256_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/256?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_256_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=256&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2011%2F01%2F02%2Fproject-euler%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2011/01/02/project-euler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I made a clone of Spotify</title>
		<link>http://www.luckydonkey.com/2010/09/06/i-made-a-clone-of-spotify/</link>
		<comments>http://www.luckydonkey.com/2010/09/06/i-made-a-clone-of-spotify/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 17:33:31 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=252</guid>
		<description><![CDATA[Over on my company website I've written a blog about how I made clone of Spotify in a week using Qt and Django Read the article here.]]></description>
			<content:encoded><![CDATA[<p>Over on my company website I've written a blog about how I made  clone of Spotify in a week using Qt and Django</p>
<p>Read the article <a href="http://www.executionunit.com/blog/2010/metalify_spotify_clone.html">here</a>.</p>
<p><map name='google_ad_map_252_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/252?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_252_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=252&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2010%2F09%2F06%2Fi-made-a-clone-of-spotify%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2010/09/06/i-made-a-clone-of-spotify/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPad Development</title>
		<link>http://www.luckydonkey.com/2010/03/17/ipad-development/</link>
		<comments>http://www.luckydonkey.com/2010/03/17/ipad-development/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 01:05:54 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=239</guid>
		<description><![CDATA[I've been working on an iPad game for a few weeks and I've started to blog about it over at my companies website http://www.executionunit.com. Hopefully I'll write something interesting along the way.]]></description>
			<content:encoded><![CDATA[<p>I've been working on an iPad game for a few weeks and I've started to blog about it over at my companies website <a href="http://www.executionunit.com">http://www.executionunit.com</a>. Hopefully I'll write something interesting along the way.</p>
<p><map name='google_ad_map_239_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/239?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_239_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=239&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2010%2F03%2F17%2Fipad-development%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2010/03/17/ipad-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Church Attendance Grows by 50%</title>
		<link>http://www.luckydonkey.com/2009/04/12/church-attendance-grows-by-50/</link>
		<comments>http://www.luckydonkey.com/2009/04/12/church-attendance-grows-by-50/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 11:18:33 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Atheism]]></category>
		<category><![CDATA[Funny]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=235</guid>
		<description><![CDATA[Humorous strap line on BBC news a few hours ago..... I couldn't resist.]]></description>
			<content:encoded><![CDATA[<p>Humorous strap line on BBC news a few hours ago..... I couldn't resist.</p>
<p><img src="http://www.luckydonkey.com/wp-content/uploads/2009/04/worshippers-300x166.jpg" alt="worshippers" title="worshippers" width="300" height="166" class="alignnone size-medium wp-image-236" /></p>
<p><map name='google_ad_map_235_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/235?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_235_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=235&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2009%2F04%2F12%2Fchurch-attendance-grows-by-50%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2009/04/12/church-attendance-grows-by-50/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Beep My Stuff enters public Beta</title>
		<link>http://www.luckydonkey.com/2009/04/02/beep-my-stuff-enters-public-beta/</link>
		<comments>http://www.luckydonkey.com/2009/04/02/beep-my-stuff-enters-public-beta/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 23:00:23 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Beep My Stuff]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[SQLAlchemy]]></category>
		<category><![CDATA[TurboGears]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=226</guid>
		<description><![CDATA[After a rather long period in closed beta I've opened Beep My Stuff to a public beta. Beep My Stuff is a web site that makes it FREE and easy to create an online library of your Books, Movies, Video Games and Music. Check it out, all feedback is much appreciated. It's built with Turbogears, [...]]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_232" class="wp-caption aligncenter" style="width: 310px"><img src="http://www.luckydonkey.com/wp-content/uploads/2009/04/bms_logo-300x147.jpg" alt="Beep My Stuff" title="bms_logo" width="300" height="147" class="size-medium wp-image-232" /><p class="wp-caption-text">Beep My Stuff</p></div><br />
After a rather long period in closed beta I've opened <a href="http://www.beepmystuff.com/">Beep My Stuff</a> to a public beta.</p>
<p><a href="http://www.beepmystuff.com/">Beep My Stuff</a> is a web site that makes it FREE and easy to create an online library of your Books, Movies, Video Games and Music. Check it out, all feedback is much appreciated.</p>
<p>It's built with <a href="http://www.turbogears.org/">Turbogears</a>, <a href="http://www.sqlalchemy.org/">SQLAlchemy</a>, <a href="http://genshi.edgewall.org/">Genshi</a> and countless other python modules. It's all sitting on <a href="http://www.python.org/">Python</a>, <a href="http://www.freebsd.org/">FreeBSD</a> and <a href="http://www.postgresql.org/">PostgreSQL</a>.</p>
<p>Just wanted to say thanks to all the pythonista's out there that helped me get this far <img src='http://www.luckydonkey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><map name='google_ad_map_226_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/226?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_226_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=226&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2009%2F04%2F02%2Fbeep-my-stuff-enters-public-beta%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2009/04/02/beep-my-stuff-enters-public-beta/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Update: PKR on VMWare</title>
		<link>http://www.luckydonkey.com/2009/03/29/update-pkr-on-vmware/</link>
		<comments>http://www.luckydonkey.com/2009/03/29/update-pkr-on-vmware/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 15:41:02 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Rant]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=218</guid>
		<description><![CDATA[I'm still getting a lot of people asking me if PKR runs on VMWare. The current release of PKR and VMWare seem to be broadly compatible. Here is a scrappy video of my settings so people can give it a go. I run PKR off of my bootcamp partition but there is no need to [...]]]></description>
			<content:encoded><![CDATA[<p>I'm still getting a lot of people asking me if PKR runs on VMWare. The current release of PKR and VMWare seem to be broadly compatible. Here is a scrappy video of my settings so people can give it a go. I run PKR off of my bootcamp partition but there is no need to use a separate partition. Click through to watch in HD where it is a little better.</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/5UmFSqpZKls&hl=en&fs=1&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/5UmFSqpZKls&hl=en&fs=1&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<p>It's a little grainy but you should be able to see the settings I've been using for DX, VMWare and PKR.</p>
<p>This doesn't mean that future verisons of PKR or VMWare are going to work btw.</p>
<p><map name='google_ad_map_218_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/218?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_218_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=218&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2009%2F03%2F29%2Fupdate-pkr-on-vmware%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2009/03/29/update-pkr-on-vmware/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mutlipart file upload in Turbogears 1.0.x</title>
		<link>http://www.luckydonkey.com/2009/03/16/mutlipart-file-upload-in-turbogears-10x/</link>
		<comments>http://www.luckydonkey.com/2009/03/16/mutlipart-file-upload-in-turbogears-10x/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 15:27:58 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[Beep My Stuff]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TurboGears]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/2009/03/16/mutlipart-file-upload-in-turbogears-10x/</guid>
		<description><![CDATA[When uploading files to Beep My Stuff using SWFUpload I was getting this error: data = self._sock.recv&#40;self._rbufsize&#41; timeout: timed out Uploading files to a TG1.0.x app is easy unless you want to do something nice like use SWFUpload to allow multiple files to be selected for upload. The reason for this is that Flash has [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript"><!--
google_ad_client = "pub-9998980871049158";
//468x60, created 11/22/07
google_ad_slot = "6052810016";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>When uploading files to <a href='http://www.beepmystuff.com'>Beep My Stuff</a> using <a href="http://swfupload.org/">SWFUpload</a> I was getting this error:</p>
<pre class="python">data = <span style="color: #008000;">self</span>._sock.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._rbufsize<span style="color: black;">&#41;</span>
timeout: timed out</pre>
<p>Uploading files to a TG1.0.x app is easy unless you want to do something nice like use <a href="http://swfupload.org/">SWFUpload</a> to allow multiple files to be selected for upload.</p>
<p>The reason for this is that Flash has interpreted <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a> one way and they python libraries/CherryPy interpret it another. Fortunately this is fixed in Turbogears 1.1+ but I am using 1.08 at the moment for <a href='http://www.beepmystuff.com'>Beep My Stuff</a> so I needed a fix.</p>
<p>There is a <a href="http://www.cherrypy.org/attachment/ticket/648/flash8.patch">patch</a> in CherryPy that can be used to fix the problem and Chris Arndt has created a patch for TG1.1. You can easily apply the same code to your TG1.0x app to fix this problem as well.</p>
<p>Visit <a href="http://trac.turbogears.org/attachment/ticket/1953/safemultipart-filter.diff">here</a> and copy the contents of safemutlipart.py into a file in your project. Then you need to install the filter when <a href="http://www.turbogears.org/">Turbogears</a> is starting up. Something like this will do the trick:</p>
<pre class="python"><span style="color: #808080; font-style: italic;">#force the multipart filter to be installed.</span>
<span style="color: #ff7700;font-weight:bold;">def</span> install_safemutlipartfilter<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> cherrypy <span style="color: #ff7700;font-weight:bold;">import</span> root
    root._cp_filters.<span style="color: black;">extend</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>SafeMultipartFilter<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> install_multipart_filter<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> turbogears.<span style="color: black;">startup</span> <span style="color: #ff7700;font-weight:bold;">import</span> call_on_startup
    log.<span style="color: black;">info</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Installing multipart filter&quot;</span><span style="color: black;">&#41;</span>
    call_on_startup.<span style="color: black;">append</span><span style="color: black;">&#40;</span>install_safemutlipartfilter<span style="color: black;">&#41;</span></pre>
<p>Note that the code in SafeMultiPartFilter needs a config change to turn it on so add</p>
<pre>safempfilter.on = True</pre>
<p>to your app.cfg</p>
<p>hope that helps <img src='http://www.luckydonkey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><map name='google_ad_map_215_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/215?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_215_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=215&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2009%2F03%2F16%2Fmutlipart-file-upload-in-turbogears-10x%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2009/03/16/mutlipart-file-upload-in-turbogears-10x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Replaying apache log files with python and twill</title>
		<link>http://www.luckydonkey.com/2008/10/02/replaying-apache-log-files-with-python-and-twill/</link>
		<comments>http://www.luckydonkey.com/2008/10/02/replaying-apache-log-files-with-python-and-twill/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 00:06:19 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[NewMetalArmy]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=211</guid>
		<description><![CDATA[In order to test for a memory leak in New Metal Army I needed to replay my apache log files against my test server. Using Twill this was a doddle. The only slightly icky thing about the script is the regular expression to parse a line from the apache log file (in Combined Log Format). [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript"><!--
google_ad_client = "pub-9998980871049158";
//468x60, created 11/22/07
google_ad_slot = "6052810016";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>In order to test for a memory leak in <a href="http://www.newmetalarmy.com">New Metal Army</a> I needed to replay my apache log files against my test server. Using <a href='http://twill.idyll.org/'>Twill</a> this was a doddle.</p>
<p>The only slightly icky thing about the script is the regular expression to parse a line from the apache log file (in <a href="http://httpd.apache.org/docs/2.2/logs.html">Combined Log Format</a>). I got this from <a href="http://www.regexbuddy.com/">RegExp Buddy</a> (pretty much the only reason I run Windows nowadays) but I am sure you can get similar expressions from other <a href="http://www.google.co.uk/search?q=regular+expression+libraries">regular expression libraries</a>.</p>
<p>Anyway, I'm just chucking this out there incase someone else finds it useful.</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> twill
&nbsp;
test_server=<span style="color: #483d8b;">&quot;my.test.server.com&quot;</span>
&nbsp;
reobj = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^(?P&lt;client&gt;<span style="color: #000099; font-weight: bold;">\S</span>+)<span style="color: #000099; font-weight: bold;">\s</span>+(?P&lt;auth&gt;<span style="color: #000099; font-weight: bold;">\S</span>+<span style="color: #000099; font-weight: bold;">\s</span>+<span style="color: #000099; font-weight: bold;">\S</span>+)<span style="color: #000099; font-weight: bold;">\s</span>+<span style="color: #000099; font-weight: bold;">\[</span>(?P&lt;datetime&gt;[^]]+)<span style="color: #000099; font-weight: bold;">\]</span><span style="color: #000099; font-weight: bold;">\s</span>+&quot;(?:GET|POST|HEAD) (?P&lt;file&gt;[^ ?&quot;]+)<span style="color: #000099; font-weight: bold;">\?</span>?(?P
&lt;parameters&gt;[^ ?&quot;]+)? HTTP/[0-9.]+&quot;<span style="color: #000099; font-weight: bold;">\s</span>+(?P&lt;status&gt;[0-9]+)<span style="color: #000099; font-weight: bold;">\s</span>+(?P&lt;size&gt;[-0-9]+)<span style="color: #000099; font-weight: bold;">\s</span>+&quot;(?P&lt;referrer&gt;[^&quot;]*)&quot;<span style="color: #000099; font-weight: bold;">\s</span>+&quot;(?P&lt;useragent&gt;[^&quot;]*)&quot;$'</span>, <span style="color: #dc143c;">re</span>.<span style="color: black;">MULTILINE</span><span style="color: black;">&#41;</span>
browser = twill.<span style="color: black;">get_browser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> filter_url<span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">False</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;apache.log&quot;</span><span style="color: black;">&#41;</span>:
    match = reobj.<span style="color: black;">search</span><span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> match <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">continue</span>
&nbsp;
    f = match.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;file&quot;</span><span style="color: black;">&#41;</span>
    p = match.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;parameters&quot;</span><span style="color: black;">&#41;</span>
    d = match.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;datetime&quot;</span><span style="color: black;">&#41;</span>
    path = <span style="color: #483d8b;">&quot;?&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>f, p<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> p <span style="color: #ff7700;font-weight:bold;">else</span> f
&nbsp;
    url = test_server+path
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>filter_url<span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">continue</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> d, url
        browser.<span style="color: black;">go</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        <span style="color: #808080; font-style: italic;">#this comes from twill parsing the HTML and it being malformed.</span>
        <span style="color: #808080; font-style: italic;">#I don't really care about that, as long as I get the page.</span>
        <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;</pre>
<p><map name='google_ad_map_211_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/211?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_211_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=211&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2008%2F10%2F02%2Freplaying-apache-log-files-with-python-and-twill%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2008/10/02/replaying-apache-log-files-with-python-and-twill/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQLAlchemy-Migrate upgrade scripts in a transaction</title>
		<link>http://www.luckydonkey.com/2008/07/27/sqlalchemy-migrate-upgrade-scripts-in-a-transaction/</link>
		<comments>http://www.luckydonkey.com/2008/07/27/sqlalchemy-migrate-upgrade-scripts-in-a-transaction/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 23:51:50 +0000</pubDate>
		<dc:creator>dazza</dc:creator>
				<category><![CDATA[NewMetalArmy]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLAlchemy]]></category>
		<category><![CDATA[TurboGears]]></category>

		<guid isPermaLink="false">http://www.luckydonkey.com/?p=210</guid>
		<description><![CDATA[SQLAlchemy Migrate is a really good tool for managing database upgrades for SQLAlchemy centric projects. I've been using it for 6 months on New Metal Army and I haven't had a screwed website upgrade yet! For those that don't know SQLAlchemy-migrate allows you to version control database changes and easily upgrade and downgrade a database. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/sqlalchemy-migrate/">SQLAlchemy Migrate</a> is a really good tool for managing database upgrades for <a href="http://www.sqlalchemy.org/">SQLAlchemy</a> centric projects. I've been using it for 6 months on <a href="http://www.newmetalarmy.com">New Metal Army</a> and I haven't had a screwed website upgrade yet!</p>
<p>For those that don't know SQLAlchemy-migrate allows you to version control database changes and easily upgrade and downgrade a database. Basically you write a python script with two functions: upgrade and downgrade. You test the script against the database, commit it to the SQLAlchemy-migrate version repository (not to be confused with your source control mechanism). Finally you upgrade your development database.</p>
<p>When it the time comes to deploy the new application you simply ask sqlalchemy-migrate to upgrade your database to the current version. sqlalchemy-migrate reads the current version of your schema from the database (via a custom table it inserts) and proceeds to upgrade your schema by running each upgrade script in turn.</p>
<p>Often you want your upgrades and downgrades to run within a transaction. Not because you expect them to fail but because while writing them you don't wont to leave the database partially upgraded or downgraded if your script fails. To do this I wrote a transaction decorator. Here is a template for an upgrade script:</p>
<pre class="python"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #808080; font-style: italic;"># encoding: utf-8</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">datetime</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">datetime</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy <span style="color: #ff7700;font-weight:bold;">import</span> *</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">from</span> migrate <span style="color: #ff7700;font-weight:bold;">import</span> *</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">from</span> migrate.<span style="color: black;">changeset</span> <span style="color: #ff7700;font-weight:bold;">import</span> *</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">metadata = MetaData<span style="color: black;">&#40;</span>migrate_engine<span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">def</span> transaction<span style="color: black;">&#40;</span>f, *args, **kwargs<span style="color: black;">&#41;</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #ff7700;font-weight:bold;">def</span> wrapper<span style="color: black;">&#40;</span>*args, **kwargs<span style="color: black;">&#41;</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">        connection = migrate_engine.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">        transaction = connection.<span style="color: black;">begin</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">        <span style="color: #ff7700;font-weight:bold;">try</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            result = f<span style="color: black;">&#40;</span>*args, **kwargs<span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            transaction.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            <span style="color: #ff7700;font-weight:bold;">return</span> result</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">        <span style="color: #ff7700;font-weight:bold;">except</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            transaction.<span style="color: black;">rollback</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            <span style="color: #ff7700;font-weight:bold;">raise</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">        <span style="color: #ff7700;font-weight:bold;">finally</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">            connection.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    wrapper.__name__ = f.__name__</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    wrapper.<span style="color: #0000cd;">__dict__</span> = f.<span style="color: #0000cd;">__dict__</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    wrapper.__doc__ = f.__doc__</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #ff7700;font-weight:bold;">return</span> wrapper</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">@transaction</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">def</span> upgrade<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #ff7700;font-weight:bold;">pass</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">@transaction</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff7700;font-weight:bold;">def</span> downgrade<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #ff7700;font-weight:bold;">pass</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li></ol></pre>
<p>I fill in the upgrade and downgrade functions and I'm done <img src='http://www.luckydonkey.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I include the decorator in every script as it's good practice to make your scripts as independent as possible. If you imported it from a module you may improve it in the future and inadvertently break your old downgrade scripts.</p>
<p>I hope this  helps you version control your database schema and data.</p>
<p><map name='google_ad_map_210_afea9fcd39d8b84a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/210?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_210_afea9fcd39d8b84a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=210&amp;url= http%3A%2F%2Fwww.luckydonkey.com%2F2008%2F07%2F27%2Fsqlalchemy-migrate-upgrade-scripts-in-a-transaction%2F' /></p>]]></content:encoded>
			<wfw:commentRss>http://www.luckydonkey.com/2008/07/27/sqlalchemy-migrate-upgrade-scripts-in-a-transaction/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

