<?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>geek scrap &#187; How-tos</title>
	<atom:link href="http://geekscrap.com/categories/how-tos/feed/" rel="self" type="application/rss+xml" />
	<link>http://geekscrap.com</link>
	<description>there is at least one way to do it</description>
	<lastBuildDate>Tue, 12 Apr 2011 10:14:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Multiple IP uplinks with Gentoo</title>
		<link>http://geekscrap.com/2010/02/multiple-ip-uplinks-with-gentoo/</link>
		<comments>http://geekscrap.com/2010/02/multiple-ip-uplinks-with-gentoo/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 08:00:32 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[How-tos]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[iproute2]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[multihoming]]></category>
		<category><![CDATA[policy routing]]></category>
		<category><![CDATA[split access]]></category>
		<category><![CDATA[vlan]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=739</guid>
		<description><![CDATA[When your computer or server has access to multiple LAN segments with different address spaces and different gateways to the Internet, there&#8217;s a nice feature called policy routing that allows you to use all of them simultaneously without having to re-configure your network topology. This is especially useful when you want to increase the bandwidth and [...]]]></description>
			<content:encoded><![CDATA[<p>When your computer or server has access to multiple LAN segments with different address spaces and different gateways to the Internet, there&#8217;s a nice feature called <em>policy routing</em> that allows you to use all of them simultaneously without having to re-configure your network topology. This is especially useful when you want to increase the bandwidth and resilience of a single computer or server without the burden of being an Autonomous System (BGP peering, Internet Registry bureaucracy, etc.).</p>
<p>Here are the steps to setup multiple uplinks through policy routing on Gentoo:</p>
<p><span id="more-739"></span></p>
<ol>
<li>First of all, to access multiple networks, either you have multiple physical NICs or you need to configure your network uplink to let your network ports access multiple VLANs. For more information on VLANs configurations under Gentoo, you can check Gentoo Handbook <a rel="nofollow" href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=4&amp;chap=3#doc_chap10">section on VLANs</a>.</li>
<li>On Linux kernel, you need to enable CONFIG_IP_MULTIPLE_TABLES option (in Linux kernel menuconfig, you find it under <em>Networking support =&gt; Networking options =&gt; IP: policy routing</em>). <a rel="nofollow" href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&amp;chap=7">Recompile and install kernel</a>.</li>
<li>Next, you need to install iproute2 package, which allows editing multiple routing tables:
<pre># emerge -av sys-apps/iproute2</pre>
</li>
<li>Edit <em>/etc/iproute2/rt_tables</em> and add the following route table lines:
<pre>100        T0
101        T1</pre>
</li>
<li>Edit your <em>/etc/conf.d/net</em> file to enable network startup configuration. First add the following lines, modifying addresses and interface names to suit your needs:
<pre lang="bash">config_eth0=( "192.168.0.100/24" )
routes_eth0=(
    "192.168.0.0/24 src 192.168.0.100 table T0"
    "default via 192.168.0.1 table T0"
    "default nexthop via 192.168.0.1 weight 1"
)
rules_eth1=("from 192.168.1.1/32 table T0 priority 100" )

config_eth1=( "192.168.1.200/24" )
routes_eth0=(
    "192.168.1.0/24 src 192.168.1.200 table T1"
    "default via 192.168.1.1 table T1"
    "default nexthop via 192.168.0.1 weight 1"
)
rules_eth1=("from 192.168.1.100/32 table T1 priority 101" )</pre>
<p>Then uncomment the following functions (if you copied your /etc/conf.d/net from /etc/conf.d/net.example, they should be already there in comments):</p>
<pre lang="bash">postup() {
       local x="rules_${IFVAR}[@]"
       local -a rules=( "${!x}" )
       if [[ -n ${rules} ]] ; then
               einfo "Adding IP policy routing rules"
               eindent
               # Ensure that the kernel supports policy routing
               if ! ip rule list | grep -q "^" ; then
                       eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)"
                       eerror "in your kernel to use ip rules"
               else
                       for x in "${rules[@]}" ; do
                               ebegin "${x}"
                               ip rule add ${x} dev "${IFACE}"
                               eend $?
                       done
               fi
               eoutdent
               # Flush the cache
               ip route flush cache dev "${IFACE}"
       fi
}

postdown() {
       # Automatically erase any ip rules created in the example postup above
       if interface_exists "${IFACE}" ; then
               # Remove any rules for this interface
               local rule
               ip rule list | grep " iif ${IFACE}[ ]*" | {
                       while read rule ; do
                               rule="${rule#*:}"
                               ip rule del ${rule}
                       done
               }
               # Flush the route cache
               ip route flush cache dev "${IFACE}"
       fi

       # Return 0 always
       return 0
}</pre>
</li>
<li>Finally, reboot with your new kernel. My advice is to proceed with this step while you can access your machine locally, just in case anything goes wrong.</li>
</ol>
<p>Some in-depth on what I described above: with policy routing you can insert additional routing tables and configure your system to use a set of rules to decide which table to apply for each IP packet. So if you create T0 and T1 tables, you can set your host to respond to requests from each interface back to the same interface and load balance routes going to outer network by giving the same <em>weight</em> to both gateways in generic route table.</p>
<p>If you use this setup to publish your server on multiple public networks, you will probably need to configure multiple DNS A records in round-robin over your IPs.</p>
<p>If you&#8217;re interested in more Gentoo tips, just <a href="http://geekscrap.com/feed/">subscribe</a> to my feed or <a rel="nofollow" href="http://twitter.com/geekscrap">follow me</a> on Twitter.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/02/multiple-ip-uplinks-with-gentoo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Integrate Tornado in Django</title>
		<link>http://geekscrap.com/2010/02/integrate-tornado-in-django/</link>
		<comments>http://geekscrap.com/2010/02/integrate-tornado-in-django/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:32:00 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[supervisord]]></category>
		<category><![CDATA[tornado]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=588</guid>
		<description><![CDATA[Tornado is a nice python WSGI-compliant web server developed by guys at FriendFeed. It&#8217;s primarily thought as application server for python web frameworks and according to FriendFeed benchmarks, it&#8217;s blazing fast thanks to its non-blocking connections. UPDATE: For more performance info, James Abley pointed me to a very complete benchmark of available Python asynchronous webservers. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tornadoweb.org/">Tornado</a> is a nice python WSGI-compliant web server developed by guys at FriendFeed. It&#8217;s primarily thought as application server for python web frameworks and according to FriendFeed benchmarks, it&#8217;s blazing fast thanks to its non-blocking connections.</p>
<p><strong>UPDATE</strong>: For more performance info, James Abley pointed me to a <a rel="nofollow" href="http://nichol.as/asynchronous-servers-in-python">very complete benchmark</a> of available Python asynchronous webservers. It looks like Tornado is a real monster of concurrency.</p>
<p>There are already some how-to&#8217;s on the web on plugging Django web framework into Tornado webserver. A quick recap:</p>
<ol>
<li>A <a rel="nofollow" href="http://www.jeremybowers.com/blog/4/tornado-web-framework-production-django-and-nginx/">tutorial</a> on Tornado, Django and nginx by Jeremy Bowers.</li>
<li>How to <a rel="nofollow" href="http://lincolnloop.com/blog/2009/sep/15/using-django-inside-tornado-web-server/">import django framework</a> inside a Tornado project by Lincoln Loop.</li>
<li>A <a rel="nofollow" href="http://www.djangosnippets.org/snippets/1748/">snippet</a> by lawgon.</li>
</ol>
<p>My approach is slightly different as I wanted to run Tornado using Django management command-line interface.</p>
<p><span id="more-588"></span>The 3 easy steps are:</p>
<ol>
<li>Add Tornado module to your django setup. If you use buildout, add Tornado git checkout to buildout.cfg using <em>minitage.recipe.fetch</em> recipe, like this:
<pre lang="ini">[buildout]
...
parts =
...
    tornado
    django
...

[tornado]
recipe = minitage.recipe.fetch
urls = git://github.com/facebook/tornado.git | git | | ${buildout:parts-directory}/tornado

[django]
recipe = minitage.recipe.scripts
initialization =
    import os
    os.environ['DJANGO_SETTINGS_MODULE']='project.settings.development'
scripts =
    django
eggs =
    Django
    ...
entry-points=
    django=django.core.management:execute_from_command_line
extra-paths =
    ${buildout:directory}
    ${tornado:location}
...</pre>
</li>
<li>Next, create a command-line extension hierarchy in your project&#8217;s main app:
<pre>$ mkdir project/myapp/management
$ touch project/myapp/management/__init__.py
$ mkdir project/myapp/management/commands
$ touch project/myapp/management/commands/__init__.py</pre>
</li>
<li>Last, add a runtornado.py script in project/myapp/management/commands/ folder with the following content:
<pre lang="python">from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
import os
import sys

class Command(BaseCommand):
    option_list = BaseCommand.option_list + ()
    help = "Starts a Tornado Web."
    args = '[optional port number, or ipaddr:port]'

    def handle(self, addrport='', *args, **options):
        import django
        from django.core.handlers.wsgi import WSGIHandler
        from tornado import httpserver, wsgi, ioloop

	sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
	sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)

        if args:
            raise CommandError('Usage is runserver %s' % self.args)
        if not addrport:
            addr = ''
            port = '8000'
        else:
            try:
                addr, port = addrport.split(':')
            except ValueError:
                addr, port = '', addrport
        if not addr:
            addr = '127.0.0.1'

        if not port.isdigit():
            raise CommandError("%r is not a valid port number." % port)

        quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'

        def inner_run():
            from django.conf import settings
            print "Validating models..."
            self.validate(display_num_errors=True)
            print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE)
            print "Server is running at http://%s:%s/" % (addr, port)
            print "Quit the server with %s." % quit_command
            application = WSGIHandler()
            container = wsgi.WSGIContainer(application)
            http_server = httpserver.HTTPServer(container)
            http_server.listen(int(port), address=addr)
            ioloop.IOLoop.instance().start()

        inner_run()</pre>
</li>
</ol>
<p>To run your tornado webserver, you just need to call your usual management program like manage.py with runtornado command, with the same syntax as runserver. In my case, I just run production server using <a rel="nofollow" href="http://supervisord.org/">supervisord</a>, with a command like this:</p>
<pre>$ ./bin/django runtornado --settings=project.settings.production 8000</pre>
<p>If you found this quick how-to useful, remember to follow me on <a rel="nofollow" href="http://twitter.com/geekscrap">Twitter</a> or subscribe to my feed for more django tips.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/02/integrate-tornado-in-django/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Pre-processing Audio and Video capture to Flash in Mac OS X</title>
		<link>http://geekscrap.com/2010/02/pre-processing-audio-and-video-capture-to-flash-in-mac-os-x/</link>
		<comments>http://geekscrap.com/2010/02/pre-processing-audio-and-video-capture-to-flash-in-mac-os-x/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 23:08:54 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[camtwist]]></category>
		<category><![CDATA[clock]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[jack]]></category>
		<category><![CDATA[livestream]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[mogulus]]></category>
		<category><![CDATA[multi-track]]></category>
		<category><![CDATA[recording]]></category>
		<category><![CDATA[ustream]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=504</guid>
		<description><![CDATA[Web streaming services like UStream.tv and Livestream (previously known as Mogulus) use a Flash applet to capture audio and video signals on source computer. Media stream is encoded by Flash and sent over to broadcasting server. Currently this approach has two shortcomings: Flash applet audio capture is very limited: only one device a time, only one [...]]]></description>
			<content:encoded><![CDATA[<p>Web streaming services like <a rel="nofollow" href="http://www.ustream.tv/">UStream.tv</a> and <a rel="nofollow" href="http://www.livestream.com/">Livestream</a> (previously known as <em>Mogulus</em>) use a Flash applet to capture audio and video signals on source computer. Media stream is encoded by Flash and sent over to broadcasting server. Currently this approach has two shortcomings:</p>
<ol>
<li>Flash applet audio capture is very limited: only one device a time, only one stereo channel pair and doesn&#8217;t support devices without volume level mixer. It doesn&#8217;t allow any advanced setup like multi-channel digital mixers.</li>
<li>Audio and video are encoded on the fly and no local copy is recorded. Streaming services offer server-side recording, but after downsampling and packet loss, quality is very low. Even worse: any connection fault will interrupt your recording.</li>
</ol>
<p><span id="more-504"></span>To achieve multi-channel audio capture and client-side recording, live events media producers traditionally have few options:</p>
<ol>
<li>Process audio and video signals with external mixer and recording tools and then acquire analog output signals with an AD capture card. This makes multi-channel recording more expensive. Furthermore, if signal processing passes through analog components, streaming quality is degraded and HD video must be downscaled.</li>
<li>Record your audio-video using your camera and then use camera Firewire or analog output to stream to computer. To do this, you need to have audio inputs on your camera. This has three downsides: your recorded session may have lower video quality (miniDV or miniHDV tape recording quality may be lower than firewire output quality), you cannot record multitrack audio and you need to connect your audio mixer to your camera.</li>
<li>Use a digital mixer coupled with Flash Media Encoder software, which is only available on Windows, so if you&#8217;re a Mac OS X or Linux user, you&#8217;re out of luck. Also, you cannot record high quality encoded files but only FLV as they&#8217;re sent over to the broadcast.</li>
<li>Use <a rel="nofollow" href="http://www.ustream.tv/producer">UStream Producer Pro</a>, a $199 tool released by UStream.tv for Windows and Mac OS X, that allows multi-camera management, HDV input, PIP and broadcasting output recording, at the same quality of the output stream.</li>
</ol>
<p>For my live streaming setup, I wanted to use my MacBook laptop with Mac OS X, a <a href="http://www.amazon.com/gp/product/B000IF8NNS?ie=UTF8&amp;tag=geekscrap-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B000IF8NNS">Sony HVR-V1</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=geekscrap-20&amp;l=as2&amp;o=1&amp;a=B000IF8NNS" border="0" alt="" width="1" height="1" /> HDV camera connected through Firewire and a <a href="http://www.amazon.com/gp/product/B000OSCHG8?ie=UTF8&amp;tag=geekscrap-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B000OSCHG8">Edirol M-16DX</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=geekscrap-20&amp;l=as2&amp;o=1&amp;a=B000OSCHG8" border="0" alt="" width="1" height="1" /> 16-channel digital audio mixer connected via USB to capture audio from a few condenser microphones. Methods mentioned above aren&#8217;t applicable, because they would require additional hardware and recording quality would be very low, compared to original signal quality.</p>
<p>After some research, I found a way to process audio and video signals before submitting them to Flash applet in Mac OS X. First, the requirements:</p>
<ol>
<li><a href="http://allocinit.com/index.php?title=CamTwist">CamTwist</a>: it&#8217;s a freeware software that creates a loopback video interface and allows multiple client apps to access a single video device at the same time. A number of video effects can be applied to the video stream by CamTwist.</li>
<li><a href="http://jackaudio.org/">Jack audio router</a>: an Open Source application that allows custom routing of audio channels between multiple devices and programs simultaneously with very low latency.</li>
<li>An account on <a href="http://www.ustream.tv/">UStream.tv</a> with an available broadcasting channel setup.</li>
</ol>
<p>Once you&#8217;ve installed the programs and created the account, you can use the following checklist to configure your system to route your advanced audio-video stream both to UStream.tv and to your custom recording tools:</p>
<ol>
<li>Connect your external camera and audio sources and wait until they&#8217;re properly recognised by the system.</li>
<li>Run CamTwist and <strong>select your video input</strong> from the Step 1 column and adjust input settings in the &#8220;Settings&#8221; column on the right. If you want, you can add effects in column Step 2 (check CamTwist documentation for details). If you need a preview, you can use Tools -&gt; Preview menu (close it afterwards, so that it doesn&#8217;t eat up cpu cycles).</li>
<li>Run JackPilot program and <strong>configure access to hardware</strong> device from JackPilot -&gt; Preferences menu (it should open automatically on first use). You need to select your audio driver (typically <em>coreaudio</em>), your hardware interface (select your multi-channel card), your hardware-specific setup (frequency, number input and output of channels) and then set your <em>virtual Jack card</em> channels and untick &#8220;Auto connect with physical ports&#8221;.</li>
<li>Once you&#8217;re done with Jack setup, close Preferences dialog and start Jack audio server by clicking on <strong>Run button</strong> in main dialog.</li>
<li>Open your audio-video recording tool and select <strong>CamTwist</strong> from available video input interfaces and <strong>JackRouter</strong> from audio input interfaces and start a new recording. For instance, if you use QuickTime to record your session, go to QuickTime -&gt; Preferences menu and select Recording tab. In Video Source drop-down menu select CamTwist and in Microphone menu select JackRouter, then close dialog and open a new session with File -&gt; New video recording menu and click on Record button to start recording. <strong>Important</strong>: if you don&#8217;t start recording, your tool may not show up in your Jack router setup, so do as you&#8217;re told <img src='http://geekscrap.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
<li>Open your browser (Firefox is better) and connect to UStream.tv, login with your account and click on <strong>Broadcast now</strong> button. A popup will open and once Flash applet is loaded, you can select your audio and video inputs just below the preview frame. Select CamTwist from Video drop-down menu and JackRouter from Audio menu. Check that you see video from your source in preview frame.</li>
<li>Go back to JackPilot and click on <strong>Routing button</strong> to open Routing panel. The panel contains 3 frames: on the first frame, you have your physical captures and your application audio outputs, on the second frame you have your physical outputs and your application inputs and on the third frame there&#8217;s a list of connection. What you have to do is create <strong>a series of mappings between items</strong> in first frame to items in second frame. To create a mapping, you need to select one item in first frame and double-click on item on second frame. To unbind the mapping, just repeat the same action again. In my setup, I create a mapping between stereo mix-down channels 17 and 18 of my mixer and Flash (Firefox) stereo input channels and then a mapping between the same mix-down channels and QuickTime stereo input. If you use a multi-track recording program like Cubase, you can add more virtual channels to Jack Router (in Preferences) and map each mixer input to its own virtual channel. <strong>Remember</strong>: if you need to change Jack Router settings to add more channels or change interface settings, you have to shut down Jack with Stop button first.</li>
<li>Now you&#8217;re ready to click on Broadcast button on your UStream.tv channel and go live. Check audio level with Flash Vu-meter and adjust volume slider accordingly. For what regards audio and video quality sliders, my advice is to keep audio above 70 and video at least 50: the more bandwith you have, the more you can raise video.</li>
</ol>
<p><strong>Be careful</strong>: audio and video streams are not synchronized, because there&#8217;s no common clock or timecoding between the source peripherals. This means that long audio-video sessions might get slightly out of sync if processing time is different between audio and video. My advice is to check wether your camera and audio mixer support timecoding synchronization in a common format: if they do, then set up a link between the two. If they don&#8217;t (which is probably your situation, if you&#8217;re using consumer devices), avoid running other cpu-intensive or disk-intensive processes during the streaming/recording activity and use a post-production tool like FinalCut Pro or Adobe Premiere Pro to match audio and video on recorded files by shifting and stretching appropriately. I will write more on this later.</p>
<p>That&#8217;s all. Have you found other ways to accomplish the same result? Need some hints for your setup or troubleshooting? Please share your thoughts using the comments box below and remember to subscribe to my feed for additional tips on AV techniques.</p>
<p>P.S.: Special thanks goes out to Maurizio Tognoni, who shared the hacking and testing efforts.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/02/pre-processing-audio-and-video-capture-to-flash-in-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>.gitignore for Django buildout</title>
		<link>http://geekscrap.com/2010/01/gitignore-for-django-buildout/</link>
		<comments>http://geekscrap.com/2010/01/gitignore-for-django-buildout/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 07:30:37 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[.gitignore]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[minitage]]></category>
		<category><![CDATA[pyc]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=342</guid>
		<description><![CDATA[If you&#8217;re keeping your django buildout installation under git, you may find the following .gitignore list useful to prevent your commits from cluttering with ugly temporary files (of course it also applies to other revision control system ignore files). You may need to adapt folder names to your buildout.cfg setup. *~ *.orig *.pyc *.rej .installed.cfg [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re keeping your django buildout installation under git, you may find the following <em>.gitignore</em> list useful to prevent your commits from cluttering with ugly temporary files (of course it also applies to other revision control system ignore files). You may need to adapt folder names to your buildout.cfg setup.</p>
<p><span id="more-342"></span></p>
<pre>*~
*.orig
*.pyc
*.rej
.installed.cfg
__minitage__*
bin/*
develop-eggs
downloads
eggs
log
parts
project/media/uploads
tmp</pre>
<p>As usual, feel free to post your additions as comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/gitignore-for-django-buildout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gentooize Part 1: colorize console</title>
		<link>http://geekscrap.com/2010/01/gentooize-part-1-colorize-console/</link>
		<comments>http://geekscrap.com/2010/01/gentooize-part-1-colorize-console/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 07:30:40 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[How-tos]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[colors]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ls]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[prompt]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=137</guid>
		<description><![CDATA[One of the best lessons you can learn from Gentoo is you can export most of its juice to other OSes. I&#8217;ve been using Gentoo as main Linux distro since 2001. Currently I have a few setups where drawbacks of migrating to Gentoo would exceed benefits, so I decided to increase affinity by adding some [...]]]></description>
			<content:encoded><![CDATA[<p>One of the best lessons you can learn from Gentoo is you can <em>export</em> most of its juice to other OSes. I&#8217;ve been using Gentoo as main Linux distro since 2001. Currently I have a few setups where drawbacks of migrating to Gentoo would exceed benefits, so I decided to increase affinity by adding some Gentoo look&#8217;n'feel. This week I will post some tips to setup Gentoo console colors on other operating systems.</p>
<p><span id="more-137"></span></p>
<h2>Shell prompt</h2>
<p>First of all, you should check you&#8217;re using <strong>bash</strong> shell:</p>
<pre lang="bash">$ env | grep ^SHELL=
SHELL=/bin/bash</pre>
<p>If not, you should check if bash package is already installed. If it&#8217;s already there, just change your user shell (and possibly root shell) with chsh or consult your OS manual. <strong>Be careful</strong>: if bash is not listed in /etc/shells, you might lock yourself out.</p>
<p>To set Gentoo-like colors on bash prompt, edit ~/.profile (or /etc/profile for system-wide defaults) and add the following:</p>
<pre lang="bash">if [[ ${EUID} == 0 ]] ; then
        PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
else
        PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
fi</pre>
<h2>GNU ls</h2>
<p>If you use GNU ls (use &#8211;version to check) and <strong>dircolors</strong> utility is available (from GNU <a rel="nofollow" href="http://www.gnu.org/software/coreutils/">coreutils</a>), you can have colorful outputs by adding the following snippet to your bash profile (see above):</p>
<pre lang="bash">if type -P dircolors &gt;/dev/null ; then
        if [[ -f ~/.dir_colors ]] ; then
                eval $(dircolors -b ~/.dir_colors)
        elif [[ -f /etc/DIR_COLORS ]] ; then
                eval $(dircolors -b /etc/DIR_COLORS)
        fi
fi
alias ls='ls --color=auto'</pre>
<p>To enable colors, you need to save Gentoo <a href="http://geekscrap.com/wp-content/uploads/2010/01/DIR_COLORS">color defs</a> to ~/.dir_colors (or /etc/DIR_COLORS for system-wide defaults).<br />
Alternatively, if you miss dircolors binary on your system, save output from dircolors on a Gentoo machine and copy&#8217;n'paste it into bash profile:</p>
<pre lang="bash">LS_COLORS='...weird colon-separated string...'
export LS_COLORS
alias ls='ls --color=auto'</pre>
<h2>BSD ls implementation</h2>
<p>A special trick is required for <strong>FreeBSD</strong> and <strong>Mac OS X</strong>: add the following line to your bash profile:</p>
<pre lang="bash">export CLICOLOR=1 LSCOLORS="ExGxFxDxCxDxDxhbhdacEc"</pre>
<p>If you want to further customize colors on your <strong>Mac OS X Terminal</strong>, you can use SIMBL <a rel="nofollow" href="http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal">TerminalColours</a> plugin (<a rel="nofollow" href="http://blog.fallingsnow.net/2009/08/28/fixing-colors-in-terminal-app-on-10-6/">Snow Leopard version</a>).</p>
<h2>GNU grep</h2>
<p>You can enable coloring of the matched part by appending the following alias to your bash profile:</p>
<pre lang="bash">alias grep='grep --colour=auto'</pre>
<p>As usual, if you have any coloring tips&#8217;n'tricks you want to share, please use the comment box below.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/gentooize-part-1-colorize-console/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django dynamic template paths</title>
		<link>http://geekscrap.com/2010/01/django-dynamic-template-paths/</link>
		<comments>http://geekscrap.com/2010/01/django-dynamic-template-paths/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 08:30:38 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pyclbr]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[readmodule_ex]]></category>
		<category><![CDATA[reversion]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=214</guid>
		<description><![CDATA[Several add-on applications for Django bring in their own templates and expect user to hardcopy those files into project&#8217;s template directory. The problem raises when add-on egg is updated and its hardcopied templates are not. Another approach could be to add add-on template directory path to TEMPLATE_DIRS variable in project&#8217;s settings.py. However, once add-on application [...]]]></description>
			<content:encoded><![CDATA[<p>Several add-on applications for Django bring in their own templates and expect user to hardcopy those files into project&#8217;s template directory. The problem raises when add-on egg is updated and its hardcopied templates are not. Another approach could be to add add-on template directory path to TEMPLATE_DIRS variable in project&#8217;s settings.py. However, once add-on application is updated, hardcoded path may not be up-to-date.</p>
<p><strong>UPDATE</strong>: Vinicius Mendes commented on using <a rel="nofollow" href="http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types">django.template.loaders.app_directories.Loader</a> to solve the problem (a similar module exists for eggs, which is named django.template.loaders.eggs.Loader). It&#8217;s definitely the easiest way if you don&#8217;t mind importing all of your applications templates. Instead, if you need to pick only selected directories or non-standard directory names, keep on reading.</p>
<p><span id="more-214"></span></p>
<p>The solution is to add a dynamic path that is resolved at runtime using add-on egg&#8217;s path. Here&#8217;s an example of how I got <a rel="nofollow" href="http://code.google.com/p/django-reversion/">django-reversion</a> templates added:</p>
<pre lang="python">import os
from  pyclbr import readmodule_ex

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), "../templates"),
    os.path.join(os.path.dirname(readmodule_ex('reversion')['__path__'][0]), "templates"),
)</pre>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/django-dynamic-template-paths/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exim ldap lookup multiple DNs</title>
		<link>http://geekscrap.com/2010/01/exim-ldap-lookup-multiple-dns/</link>
		<comments>http://geekscrap.com/2010/01/exim-ldap-lookup-multiple-dns/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 15:52:45 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[How-tos]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[exim]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[mta]]></category>
		<category><![CDATA[powerdns]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=82</guid>
		<description><![CDATA[Exim is one of the most flexible MTAs on the market. Its optional modules for database connectivity and its extensive config syntax allow full customization and use of external data sources. Provided LDAP backend allows three kinds of database query lookups: ldap: This does an LDAP lookup using a query in the form of a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.exim.org/">Exim</a> is one of the most flexible MTAs on the market. Its optional modules for database connectivity and its extensive config syntax allow full customization and use of external data sources. Provided LDAP backend allows three kinds of database <a rel="nofollow" href="http://exim.org/exim-html-current/doc/html/spec_html/index.html#toc0093">query lookups</a>:</p>
<blockquote><p><strong>ldap</strong>: This does an LDAP lookup using a query in the form of a URL, and returns attributes from a single entry. There is a variant called <strong>ldapm</strong> that permits values from multiple entries to be returned. A third variant called <strong>ldapdn</strong> returns the Distinguished Name of a single entry instead of any attribute values.</p></blockquote>
<p>In some situations, it would be interesting to have a fourth query type: a lookup type that returned multiple DNs.</p>
<p><span id="more-82"></span>For instance, if your LDAP database also serves a <a rel="nofollow" href="http://www.powerdns.com/">DNS server</a> with an ldap backend, your DNS subtree entries may look like this:</p>
<pre lang="ldif">dc=mail, dc=example, dc=com, ou=domains, o=MyCompany, c=US</pre>
<p>In this case, you could extract MX records from a list of DNs that match a particular filter like:</p>
<pre lang="ldif">(&amp;(objectClass=dNSDomain)(mXRecord=* $primary_hostname))</pre>
<p>The complete query may look like this:</p>
<pre lang="exim">domainlist local_domains = @ : ${sg{${tr{${sg{${sg{${lookup ldapmdn { \
    ldap:///??sub?(&amp;(objectClass=dNSDomain)(mXRecord=10 $primary_hostname))} { $value } \
    }}{,ou=domains,o=MyCompany,c=US}}}{}}}{dc=}{}}}{,}{.}}}{\n}{ : }}</pre>
<p>To achieve this result, you need a small extension that enables a new query type called <strong>ldapmdn</strong>, whose syntax is similar to ldapdn but allows for multiple DNs. Here&#8217;s the patch for exim 4.69:</p>
<pre lang="patch">--- src/drtables.c.orig
+++ src/drtables.c
@@ -281,6 +281,23 @@
 #endif
   },

+/* LDAP lookup, allowing DN from more than one entry to be returned */
+
+  {
+  US"ldapmdn",                   /* lookup name */
+  lookup_querystyle,             /* query-style lookup */
+#ifdef LOOKUP_LDAP
+  eldap_open,       /* sic */    /* open function */
+  NULL,                          /* check function */
+  eldapmdn_find,                 /* find function */
+  NULL,                          /* no close function */
+  eldap_tidy,       /* sic */    /* tidy function */
+  eldap_quote       /* sic */    /* quoting function */
+#else
+  NULL, NULL, NULL, NULL, NULL, NULL /* lookup not present */
+#endif
+  },
+
 /* Linear search of single file */

   {
--- src/lookups/ldap.c.orig
+++ src/lookups/ldap.c
@@ -83,6 +83,7 @@
 #define SEARCH_LDAP_SINGLE 1         /* Get attributes from one entry only */
 #define SEARCH_LDAP_DN 2             /* Get just the DN from one entry */
 #define SEARCH_LDAP_AUTH 3           /* Just checking for authentication */
+#define SEARCH_LDAP_MULTIPLE_DN 4    /* Get just the DN from multiple entries */

 /* In all 4 cases, the DN is left in $ldap_dn (which post-dates the
 SEARCH_LDAP_DN lookup). */
@@ -185,6 +186,7 @@
     "sizelimit=%d timelimit=%d tcplimit=%d\n",
     (search_type == SEARCH_LDAP_MULTIPLE)? "m" :
     (search_type == SEARCH_LDAP_DN)? "dn" :
+    (search_type == SEARCH_LDAP_MULTIPLE_DN)? "mdn" :
     (search_type == SEARCH_LDAP_AUTH)? "auth" : "",
     ldap_url, server, s_port, sizelimit, timelimit, tcplimit);

@@ -577,7 +579,8 @@
     entries, the DNs will be concatenated, but we test for this case below, as
     for SEARCH_LDAP_SINGLE, and give an error. */

-    if (search_type == SEARCH_LDAP_DN)   /* Do not amalgamate these into one */
+    if (search_type == SEARCH_LDAP_DN ||
+      search_type == SEARCH_LDAP_MULTIPLE_DN) /* Do not amalgamate these into one */
       {                                  /* condition, because of the else */
       if (new_dn != NULL)                /* below, that's for the first only */
         {
@@ -820,7 +823,8 @@

 /* The search succeeded. Check if we have too many results */

-if (search_type != SEARCH_LDAP_MULTIPLE &amp;&amp; rescount &gt; 1)
+if (search_type != SEARCH_LDAP_MULTIPLE &amp;&amp;
+	search_type != SEARCH_LDAP_MULTIPLE_DN &amp;&amp; rescount &gt; 1)
   {
   *errmsg = string_sprintf("LDAP search: more than one entry (%d) was returned "
     "(filter not specific enough?)", rescount);
@@ -1126,6 +1130,14 @@
 return(control_ldap_search(ldap_url, SEARCH_LDAP_AUTH, result, errmsg));
 }

+int
+eldapmdn_find(void *handle, uschar *filename, uschar *ldap_url, int length,
+  uschar **result, uschar **errmsg, BOOL *do_cache)
+{
+/* Keep picky compilers happy */
+do_cache = do_cache;
+return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE_DN, result, errmsg));
+}

 /*************************************************
--- src/lookups/ldap.h.orig
+++ src/lookups/ldap.h
@@ -16,6 +16,8 @@
                  uschar **, BOOL *);
 extern int     eldapm_find(void *, uschar *, uschar *, int, uschar **,
                  uschar **, BOOL *);
+extern int     eldapmdn_find(void *, uschar *, uschar *, int, uschar **,
+                 uschar **, BOOL *);
 extern void    eldap_tidy(void);
 extern uschar *eldap_quote(uschar *, uschar *);</pre>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/exim-ldap-lookup-multiple-dns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django and mysql names</title>
		<link>http://geekscrap.com/2010/01/django-and-mysql-names/</link>
		<comments>http://geekscrap.com/2010/01/django-and-mysql-names/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 17:15:22 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[dmigrations]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=70</guid>
		<description><![CDATA[Using django 1.1.1 framework with dmigrations tool, I&#8217;ve discovered that they don&#8217;t honour mysql naming conventions correctly. In fact, mysql has a limit of 64 characters on table names, index names and column names, but django doesn&#8217;t take it into account when generating tables and indices from models. In vanilla django, using &#8220;manage.py sql&#8221; or [...]]]></description>
			<content:encoded><![CDATA[<p>Using <a rel="nofollow" href="http://www.djangoproject.com/">django</a> 1.1.1 framework with <a rel="nofollow" href="http://code.google.com/p/dmigrations/">dmigrations</a> tool, I&#8217;ve discovered that they don&#8217;t honour mysql naming conventions correctly. In fact, mysql has a limit of 64 characters on table names, index names and column names, but django doesn&#8217;t take it into account when generating tables and indices from models.</p>
<p><span id="more-70"></span>In vanilla django, using &#8220;manage.py sql&#8221; or &#8220;manage.py sqlindexes&#8221; you can generate respectively &#8220;CREATE TABLE&#8221; and &#8220;CREATE INDEX&#8221; sql statements to setup your database schema (if you use manage.py syncdb, generated sql is feeded into your database). Table names are defined in <em>db_table</em> variable in model&#8217;s meta class and default name is generated using the following statement in django.db.models.options:</p>
<pre lang="python">self.db_table = "%s_%s" % (self.app_label, self.module_name)</pre>
<p>Now, if your generated db_table is greater than 64 characters (quite easy if your application name is long), django doesn&#8217;t truncate it and when sql is feeded into mysql, table creation routine will fail. A similar trouble happens for index creation routine (typically used with <em>unique</em> constraints) and using dmigrations tool instead of plain syncdb doesn&#8217;t get any better.</p>
<p>At this point, there are two options for table naming:</p>
<ol>
<li>Renaming tables in models.py by hand (quite boring if your project is big).</li>
<li>Patching django to apply a truncation to db_table.</li>
</ol>
<p>For option 2, here&#8217;s the simple one-liner patch you need for django 1.1.1:</p>
<pre lang="patch">--- django/db/backends/mysql/base.py.orig
+++ django/db/backends/mysql/base.py
@@ -214,6 +214,9 @@
         second = '%s-12-31 23:59:59.99'
         return [first % value, second % value]

+    def max_name_length(self):
+        return 64
+
 class DatabaseWrapper(BaseDatabaseWrapper):

     operators = {</pre>
<p>In dmigrations, index names are defined as:</p>
<pre lang="python">index_name = '%s_%s_%s' % (app, model, column)</pre>
<p>You can fix the length problem in r29 with this simple patch:</p>
<pre lang="patch">--- dmigrations/mysql/migrations.py.orig
+++ dmigrations/mysql/migrations.py
@@ -141,7 +141,7 @@
     def __init__(self, app, model, column):
         model = model.lower()
         self.app, self.model, self.column = app, model, column
-        index_name = '%s_%s_%s' % (app, model, column)
+        index_name = '%s_refs_id_%s' % (column, abs(hash((app, model, column))))
         super(AddIndex, self).__init__(
             sql_up = [self.add_index_sql % (index_name, app, model, column)],
             sql_down = [self.drop_index_sql % (app, model, index_name)],</pre>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/django-and-mysql-names/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Install wxPython in buildout</title>
		<link>http://geekscrap.com/2010/01/install-wxpython-in-buildout/</link>
		<comments>http://geekscrap.com/2010/01/install-wxpython-in-buildout/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 06:40:17 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[easy_install]]></category>
		<category><![CDATA[egg]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[setuptools]]></category>
		<category><![CDATA[wxPython]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=12</guid>
		<description><![CDATA[While completing setup of this blog with WordPress, I&#8217;ve also been working on another task: adding wxPython dependency to a pythonic project of mine. The deployment of this project is done through buildout, a nice piece of software that handles a sandboxed environment for python projects. You can find download and install instructions to start [...]]]></description>
			<content:encoded><![CDATA[<p>While completing setup of this blog with WordPress, I&#8217;ve also been working on another task: adding <a rel="nofollow" href="http://www.wxpython.org/">wxPython</a> dependency to a pythonic project of mine. The deployment of this project is done through <a rel="nofollow" href="http://www.buildout.org/">buildout</a>, a nice piece of software that handles a sandboxed environment for python projects.</p>
<p>You can find download and install instructions to start a buildout barebone <a rel="nofollow" href="http://www.buildout.org/install.html">here</a>, however I will do a small recap:</p>
<p><span id="more-12"></span>First, check that your python installation has <a rel="nofollow" href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a> installed (platform-specific install instructions <a rel="nofollow" href="http://pypi.python.org/pypi/setuptools">here</a>).</p>
<p>Then run the following commands to create your new project and fetch bootstrapping script:</p>
<pre lang="Bash">$ mkdir projectdir
$ cd projectdir
$ wget http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py
$ mkdir downloads # this is needed, as buildout won't create it by itself.</pre>
<p>Next step is writing buildout.cfg, an ini-style configuration file that specifies the setup for your deployment. The generic section is named &#8220;buildout&#8221; and its &#8220;parts&#8221; attribute refers to other sections that must be evaluated. I&#8217;ve created two parts: an example named &#8220;myproject&#8221;, which downloads, builds and installs a couple of fake eggs with wxPython in PYTHONPATH and a &#8220;wxPython&#8221; part, which downloads, builds and installs wxPython inside &#8220;parts&#8221; directory.</p>
<p>Each part is evaluated using a recipe, which is a plugin that is dynamically download from <a rel="nofollow" href="http://pypi.python.org/pypi">eggs repository</a> or any other repository you pass through a find-links attribute. For my purposes I&#8217;ve employed two recipes from <a rel="nofollow" href="http://www.minitage.org/">minitage project</a>, a software deployment project developed by a nice french dude called kiorky (you can chat with him and obtain support at #minitage on irc.freenode.net).</p>
<pre lang="INI">[buildout]
download-cache = downloads
parts =
    wxPython
    myproject

[myproject]
recipe = minitage.recipe.egg
eggs =
    myegg
    myotheregg
extra_paths = ${wxPython:location}/lib/python

[wxPython]
recipe = minitage.recipe.cmmi
url = http://downloads.sourceforge.net/wxpython/wxPython-src-2.8.10.1.tar.bz2
post-make-hook = ${buildout:directory}/hooks.py:wxpython_post_make_hook
configure-options =
    --enable-debug --enable-debug_gdb # replace with --enable-optimize in production code
    --enable-display
    --enable-geometry
    --enable-graphics_ctx
    --enable-mediactrl
    --enable-sound
    --enable-unicode
    --with-libjpeg=builtin
    --with-libpng=builtin
    --with-libtiff=builtin
    --with-opengl
    --with-sdl
    --with-zlib=builtin
# Platform-dependent options, add as needed. Platform names are from sys.platform.lower().
configure-options-darwin = --with-mac --enable-monolithic
configure-options-linux2 = --with-gtk2</pre>
<p>Configure-make-make-install recipe, namely minitage.recipe.cmmi, has a series of special options called &#8220;hooks&#8221; that allow extending the building process with non-standard actions through python code. I&#8217;ve added a call to wxpython_post_make_hook in hooks.py to deal with special post-install code:</p>
<pre lang="python">import os
import sys
import subprocess

def wxpython_post_make_hook(o, b):
    return subprocess.call([sys.executable, 'setup.py',
        'WX_CONFIG=%s' % os.path.join(o['location'], 'bin', 'wx-config'),
        'BUILD_GIZMOS=0', 'BUILD_STC=0',
        'install', '--home=%s' % o['location'],
        ], cwd=os.path.join(o['compile-directory'], 'wxPython'))</pre>
<p>Please note that I&#8217;ve disabled gizmos and stc support from wxPython, because I don&#8217;t need them and  they would require additional building in contrib.</p>
<p>Finally, launch the bootstrapping code:</p>
<pre lang="bash">$ python2.6 ./bootstrap.py</pre>
<p>Of course, if you have a different version of python installed, adjust the command accordingly.</p>
<p>Now buildout is ready to be executed with:</p>
<pre lang="bash">$ ./bin/buildout</pre>
<p>That&#8217;s all folks!</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/01/install-wxpython-in-buildout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
