<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Route 183</title>
	<atom:link href="http://adamfisk.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://adamfisk.wordpress.com</link>
	<description>P2P, Collaboration, Networks</description>
	<lastBuildDate>Fri, 03 May 2013 03:36:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='adamfisk.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Route 183</title>
		<link>http://adamfisk.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://adamfisk.wordpress.com/osd.xml" title="Route 183" />
	<atom:link rel='hub' href='http://adamfisk.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Lantern Bash Configuration Script on OSX</title>
		<link>http://adamfisk.wordpress.com/2011/09/04/lantern-bash-configuration-script-on-osx/</link>
		<comments>http://adamfisk.wordpress.com/2011/09/04/lantern-bash-configuration-script-on-osx/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 00:54:21 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=193</guid>
		<description><![CDATA[I&#8217;ve been working for awhile on a piece of software called Lantern. It&#8217;s a new censorship circumvention and monitoring-prevention tool built atop the LittleShoot P2P networking layer and also atop LittleProxy, another little project I&#8217;ve completely neglected to mention! You&#8217;ll be finding out a lot more about Lantern soon, but sign up for the mailing [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=193&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been working for awhile on a piece of software called Lantern. It&#8217;s a new censorship circumvention and monitoring-prevention tool built atop the LittleShoot P2P networking layer and also atop <a href="http://www.littleshoot.org/littleproxy/" title="LittleProxy HTTP Proxy Java LittleShoot">LittleProxy</a>, another little project I&#8217;ve completely neglected to mention! You&#8217;ll be finding out a lot more about Lantern soon, but sign up for the mailing list at <a href="http://www.getlantern.org" title="Lantern P2P Censorship Circumvention Tool">http://www.getlantern.org</a> if you want to be notified when you can start playing with it. It&#8217;ll be fun, and ultimately should help people all over the world who don&#8217;t enjoy the relatively unfettered internet most of us take for granted.</p>
<p>I was actually inspired to write this post, because I just added a little bash code snippet for auto-configuring proxies on OSX using networksetup, a pac file, and some nifty for looping to read lines (trickier than you might think!). I thought others might find it useful. Enjoy!</p>
<p><code><br />
#!/usr/bin/env bash</p>
<p>mkdir ~/Library/Logs/Lantern</p>
<p>function log() {<br />
  echo "`date`: $@" &gt;&gt; ~/Library/Logs/Lantern/installer.log<br />
}</p>
<p>log "Configuring network services"<br />
while read s;<br />
do<br />
    log "Configuring network: $s"<br />
    networksetup -setautoproxyurl "$s" file://localhost$HOME/.lantern/proxy.pac || log "Could not set auto proxy URL for $s"<br />
    networksetup -setautoproxystate "$s" "on" || log "Could not turn auto proxy on for $s"<br />
    log "Configured network: $s"<br />
done &lt; &lt;(networksetup -listallnetworkservices | tail +2)<br />
log &quot;Done configuring network services!!&quot;<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/193/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/193/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=193&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2011/09/04/lantern-bash-configuration-script-on-osx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>GData Maven Deploy Script</title>
		<link>http://adamfisk.wordpress.com/2010/07/10/gdata-maven-deploy-script/</link>
		<comments>http://adamfisk.wordpress.com/2010/07/10/gdata-maven-deploy-script/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 22:41:10 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=185</guid>
		<description><![CDATA[I just wrote a quick script to deploy the latest GData versions to the LittleShoot maven repository, and I thought others might find it handy. GData doesn&#8217;t deploy to a maven repo, so you&#8217;ve got to do a little extra work. There are various solutions out there, but this is a little more straightforward. I&#8217;m [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=185&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I just wrote a quick script to deploy the latest GData versions to the <a href="http://www.littleshoot.org">LittleShoot</a> maven repository, and I thought others might find it handy. GData doesn&#8217;t deploy to a maven repo, so you&#8217;ve got to do a little extra work. There are various solutions out there, but this is a little more straightforward. I&#8217;m jumping on board with Google&#8217;s latest 2.2.x alphas of their GData Java clients, as it looks like that&#8217;s where the future action will be. So this only applies to the 2.2.x alphas. The script simply takes the version argument, checks out that version from SVN, and deploys the jar to your repo.</p>
<p>You&#8217;ll want to swap out your repository for the <a href="http://www.littleshoot.org">LittleShoot</a> repository listed at the end &#8212; both the URL and repository ID. If you want to just grab this script from the LittleShoot repository, it&#8217;s <a href="http://svn.littleshoot.org/svn/littleshoot/trunk/bin/deployGData.bash">here</a>.</p>
<p><code><br />
#!/usr/bin/env bash</p>
<p># This is a script for automatically deploying the GData jars to the LittleShoot<br />
# maven repository. </p>
<p>gdataVersion=$1</p>
<p>function die() {<br />
    rm -rf $gdataVersion<br />
    echo $*<br />
    exit 1<br />
}</p>
<p>me=`basename $0`</p>
<p>if [ $# -ne 1 ]<br />
then<br />
  "Should be a single GData version argument, as in './$me 2.2.1-alpha'. For versions, see: <a href="http://gdata-java-client.googlecode.com/svn/tags/" rel="nofollow">http://gdata-java-client.googlecode.com/svn/tags/</a>"<br />
  exit 1<br />
fi</p>
<p>echo "Checking out GData version $gdataVersion"<br />
svn co <a href="http://gdata-java-client.googlecode.com/svn/tags/$gdataVersion" rel="nofollow">http://gdata-java-client.googlecode.com/svn/tags/$gdataVersion</a> || die "Could not checkout SVN"</p>
<p>pushd $gdataVersion/gdata || die "Could not move to gdata base dir"<br />
ant dist || die "Could not build with ant"<br />
cd build-bin/dist/ || die "Could not cd to dist directory"</p>
<p>mvn deploy:deploy-file -DgroupId=com.google.gdata -DartifactId=gdata -Dversion=$gdataVersion -Dfile=gdata-$gdataVersion.jar -Dpackaging=jar -DgeneratePom=true -Durl=scpexe://dev.littleshoot.org/var/maven -DrepositoryId=littleshoot || die "Could not deploy file"</p>
<p>echo "Cleaning up"<br />
popd<br />
rm -rf $gdataVersion<br />
</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/185/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=185&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2010/07/10/gdata-maven-deploy-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Happy Birthday Gnutella!</title>
		<link>http://adamfisk.wordpress.com/2010/03/20/happy-birthday-gnutella/</link>
		<comments>http://adamfisk.wordpress.com/2010/03/20/happy-birthday-gnutella/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 18:32:17 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[gnutella]]></category>
		<category><![CDATA[limewire]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=170</guid>
		<description><![CDATA[OK, I&#8217;ve been severely neglecting the ol&#8217; blog, I know. I&#8217;m breaking the silence to join Janko Roettgers and NewTeeVee in wishing Gnutella a Happy Birthday on the week of its 10 year anniversary. We had some great times at LimeWire and battling it out on the Gnutella Developer&#8217;s Forum back in the day. One [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=170&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>OK, I&#8217;ve been severely neglecting the ol&#8217; blog, I know. I&#8217;m breaking the silence to join <a title="Happy Birthday Gnutella" href="http://newteevee.com/2010/03/20/happy-birthday-gnutella-pioneering-p2p-protocol-turns-ten/">Janko Roettgers</a> and NewTeeVee in wishing Gnutella a Happy Birthday on the week of its 10 year anniversary. We had some great times at LimeWire and battling it out on the <a title="Gnutella Developer's Forum" href="http://groups.yahoo.com/group/the_gdf/messages">Gnutella Developer&#8217;s Forum</a> back in the day.</p>
<p>One of my favorite moments had to be in the summer of 2000 when Vinnie Falco, creator of BearShare, and my fellow LimeWire developer and partner in crime in the old days, Chris Rohrs, would talk about Gnutella architecture decisions. Vinnie&#8217;s an Italian American who was living in Miami Beach at the time. Chris is an MIT grad who grew up one town away from me in Deerfield, MA, one of the oldest towns in the country (close to my beloved Greenfield), and about as culturally far away from Miami Beach as one can get in the US. Chris would give Vinnie some piece of advice about this or that, and Vinnie would respond with the perfect Miami Beach Italian American accent, &#8220;Hey, you&#8217;re talking to the Vin.&#8221; And that&#8217;s how the Gnutella network was built.</p>
<p>Chris has been tearing it up at Google for years now, and Vinnie probably owns some tiny island in the South Pacific where he buried a chest full of BearShare gold back in 2002.</p>
<p>Check out Janko&#8217;s more thorough <a title="Happy Birthday Gnutella Network" href="http://newteevee.com/2010/03/20/happy-birthday-gnutella-pioneering-p2p-protocol-turns-ten/">article</a>, the best and one of the few histories of Gnutella I&#8217;ve seen written down.</p>
<p>I&#8217;ll be writing more here soon &#8212; been hammering out so much code for so many different things (all feeding back in to <a title="P2P File Sharing Browser " href="http://www.littleshoot.org">LittleShoot</a>), it&#8217;s been a struggle to find time to blog about them. Technology&#8217;s progressing so rapidly on so many fronts, it&#8217;s more fun to keep coding! Stay tuned for news about <a title="Java HTTP Proxy" href="http://dev.littleshoot.org:8084/display/proxy/LittleShoot+Java+HTTP+Proxy+-+LittleProxy">LittleProxy</a>, a sweet little HTPP proxy I&#8217;ve been working on using <a href="http://www.jboss.org/netty">Netty</a>. LittleProxy will be a core component of a new system for circumventing censors around the world. Oh yeah, and lots of other stuff too.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/170/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/170/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=170&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2010/03/20/happy-birthday-gnutella/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>MIME API from LittleShoot on Google App Engine</title>
		<link>http://adamfisk.wordpress.com/2009/07/23/mime-api-from-littleshoot-on-google-app-engine/</link>
		<comments>http://adamfisk.wordpress.com/2009/07/23/mime-api-from-littleshoot-on-google-app-engine/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 18:45:06 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=151</guid>
		<description><![CDATA[The other day I needed to add an HTML form to the LittleShoot site to upload files directly to Amazon S3. S3&#8242;s &#8220;browser-based uploads&#8221; allow you to send files directly into S3 using hidden form fields to sign the request as opposed to sending files through your server. Nice and efficient. Everything was going along [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=151&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The other day I needed to add an HTML form to the <a title="P2P BitTorrent Browser Plugin" href="http://www.littleshoot.org">LittleShoot</a> site to upload files directly to <a title="Amazon S3" href="https://s3.amazonaws.com">Amazon S3</a>. S3&#8242;s &#8220;browser-based uploads&#8221; allow you to send files directly into S3 using hidden form fields to sign the request as opposed to sending files through your server. Nice and efficient.</p>
<p>Everything was going along fine until I realized one glaring problem: how the heck could I set the Content-Type on the file? S3 requires you to do this in the initial request, in this case using another hidden form field, but how could I determine the MIME type at all? Cut past 30 minutes of digging around, and it turns out you can, of course do the following:</p>
<ol>
<li>Attach to the form submit event. In JQuery, this is just:
<pre style="outline-width:0;vertical-align:baseline;text-align:left;font-family:monaco,monospace;font-weight:normal;float:none;width:auto;background-color:#f5f4ee!important;font-size:11px!important;line-height:1.6!important;color:#06263c!important;margin:.8em 0 1.2em!important;padding:5px!important;">$("#myForm").<strong>submit</strong>(function() {...});</pre>
</li>
<li> Lookup the MIME type in JavaScript (<strong>somehow &#8211; pay attention to this one</strong>)</li>
<li> Dynamically add a hidden &#8220;Content-Type&#8221; form field just before the upload.</li>
</ol>
<p>The only problem?  To do this, you need to include a full JavaScript library to lookup all MIME types in the submit function above, another 40K+ of JavaScript code. That seems a little excessive for a call you&#8217;ll only make every once in awhile.</p>
<p>Now comes the beauty of <a title="Google App Engine" href="http://code.google.com/appengine/">Google App Engine (GAE)</a>. With App Engine, you can fire up a site in a matter of minutes that will scale to millions. With a little help from my favorite <a title="Google App Engine Patch Python Django" href="http://code.google.com/p/app-engine-patch/">App Engine Patch</a>, you can run it all on Django. The speed and ease of deployment are breathtaking: 1 hour to deploy a REST API for MIME lookups, all for free.</p>
<p>The result is <a title="LittleShoot MIME API" href="http://www.mimeapi.org/">http://www.mimeapi.org/</a>.  It&#8217;s a trivial, ridiculously simple API that basically just exposes the Python &#8220;mimetypes&#8221; module. It&#8217;s the simplest, silliest, and most trivial REST API I&#8217;ve ever seen or written, and that&#8217;s the whole point. Google App Engine annihilates the barrier to creating this type of API on the only two scales that really matter in this case: time and cost.</p>
<p>I predict we&#8217;ll see a lot of similarly trivial services continuing to pop up because they&#8217;re so easy. They seem almost stupid at first. Simple building blocks like these are the secret sauce in building any truly powerful platform, however, and with tools like GAE, the web is getting more powerful by leaps and bounds.</p>
<p>If you ever run into the obscure case where you need to lookup a MIME type via an API, check out <a title="LittleShoot MIME API" href="http://www.mimeapi.org/">mimeapi</a>. I built it because it makes more sense than cramming another JavaScript library down my user&#8217;s pipes. Maybe it&#8217;ll help you too.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/151/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=151&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2009/07/23/mime-api-from-littleshoot-on-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Google App Engine Full Text Search From App Engine Patch Team</title>
		<link>http://adamfisk.wordpress.com/2009/07/01/google-app-engine-full-text-search-from-app-engine-patch-team/</link>
		<comments>http://adamfisk.wordpress.com/2009/07/01/google-app-engine-full-text-search-from-app-engine-patch-team/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 04:16:29 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[LittleShoot]]></category>
		<category><![CDATA[Waldemar Kornewald]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=143</guid>
		<description><![CDATA[Waldemar Kornewald and the rest of the Google App Engine Patch team have just released the first full text search implementation for Google App Engine (GAE).  LittleShoot has been using App Engine Patch since the early days of App Engine, and we can&#8217;t recommend it highly enough.  Its seamless Django integration has saved us countless [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=143&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Waldemar Kornewald and the rest of the <a title="Google App Engine Patch Waldemar Kornewald" href="http://code.google.com/p/app-engine-patch/">Google App Engine Patch</a> team have just released the first full text search implementation for Google App Engine (GAE).  <a title="BitTorrent Plugin P2P" href="http://www.littleshoot.org">LittleShoot</a> has been using App Engine Patch since the early days of App Engine, and we can&#8217;t recommend it highly enough.  Its seamless Django integration has saved us countless hours, and features like its tool for combining and compressing all of your JavaScript and CSS using the YUI compressor are just stellar.</p>
<p>While we don&#8217;t have an immediate need for full text search over at LittleShoot, we can tell you the team behind <a title="Google App Engine Search Patch Full Text" href="http://gae-full-text-search.appspot.com/">GAE full text search</a> is rock solid and battle tested.  Given the various limitations of the GAE datastore API, it&#8217;s also quite a technical feat.</p>
<p>If you need full text search, and you&#8217;re running on App Engine using python, <a title="Google App Engine Search Patch Full Text" href="http://gae-full-text-search.appspot.com/">GAE search</a> will save you a great deal of pain.  Go get it.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=143&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2009/07/01/google-app-engine-full-text-search-from-app-engine-patch-team/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Django and More on Google App Engine with App Engine Patch</title>
		<link>http://adamfisk.wordpress.com/2008/11/16/easier-django-on-google-app-engine-with-app-engine-patch/</link>
		<comments>http://adamfisk.wordpress.com/2008/11/16/easier-django-on-google-app-engine-with-app-engine-patch/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 21:28:43 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[open infrastructure]]></category>
		<category><![CDATA[p2p]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[boto]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[google app engine path]]></category>
		<category><![CDATA[LittleShoot]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sqs]]></category>
		<category><![CDATA[Waldemar Kornewald]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=126</guid>
		<description><![CDATA[I&#8217;ve recently had the chance to play with Waldemar Kornewald&#8217;s &#8220;Google App Engine Patch&#8221; and have come away very impressed. All LittleShoot Google App Engine (GAE) projects now run on it for a couple of simple reasons: Seamless Django integration (including 1.0.1) Thorough documentation Healthy open source development community with an excellent steward in Kornewald [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=126&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently had the chance to play with Waldemar Kornewald&#8217;s &#8220;<a title="Google App Engine Patch" href="http://code.google.com/p/app-engine-patch/">Google App Engine Patch</a>&#8221; and have come away very impressed. All <a title="p2p 2.0" href="http://www.littleshoot.org">LittleShoot</a> Google App Engine (GAE) projects now run on it for a couple of simple reasons:</p>
<ol>
<li>Seamless <a title="Django" href="http://www.djangoproject.com/">Django</a> integration (including 1.0.1)</li>
<li>Thorough documentation</li>
<li>Healthy open source development community with an excellent steward in Kornewald and frequent new releases</li>
</ol>
<p>The Django integration got me first. Almost everything works, such as manage.py, Django authentication, Django testing (the original reason I switched), etc. There are also lots of other goodies in there, like support for <a title="boto sqs" href="http://code.google.com/p/boto/">boto&#8217;s SQS</a> module. If you&#8217;re unfamiliar with it, boto SQS allows you to call <a href="http://aws.amazon.com/sqs/">Amazon&#8217;s Simple Queue Service (SQS)</a> from Python. That&#8217;s a huge step in getting around GAE&#8217;s limitation on longer lived, CPU-intensive tasks. Just queue it up in SQS, and your GAE app will keep humming along fine &#8212; cloud integration at its finest.</p>
<p>To get started with App Engine Patch, download the zip file from the <a title="google app engine patch" href="http://code.google.com/p/app-engine-patch/">home page</a> and work off the sample project. The download includes App Engine Patch itself as well as the sample project.  </p>
<p>With Django App Engine Helper not supporting Django 1.0 and seemingly inactive, App Engine Patch is a godsend and gets a huge thumbs up.</p>
<p>Great work Waldemar, and don&#8217;t forget to <a href="http://freenet-homepage.de/wkornewald/appenginepatch/donate-usd.html">donate</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/126/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=126&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2008/11/16/easier-django-on-google-app-engine-with-app-engine-patch/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Voting Location Via Text Message</title>
		<link>http://adamfisk.wordpress.com/2008/10/30/voting-location-via-text-message/</link>
		<comments>http://adamfisk.wordpress.com/2008/10/30/voting-location-via-text-message/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 18:53:09 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[open infrastructure]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[mobilecommons]]></category>
		<category><![CDATA[voting]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=130</guid>
		<description><![CDATA[My buddies Chris Muscarella and Benjamin Stein over at Mobile Commons just released a simple service to find your voting place via text message.  Here&#8217;s all you have to do: text pp then your street address and zip to 69866 (eg: pp 101 market st 94105) That&#8217;ll give you the polling place for your address [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=130&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>My buddies Chris Muscarella and Benjamin Stein over at Mobile Commons just released a simple service to find your voting place via text message.  Here&#8217;s all you have to do:</p>
<p>text pp then your street address and zip to 69866 (eg: pp 101 market st 94105)</p>
<p>That&#8217;ll give you the polling place for your address or the number for the <a href="http://www.866ourvote.org/">Election Protection Coalition</a> if your address isn&#8217;t in their system.  Their original post is <a title="voting location via text" href="http://mcommons.com/where-do-i-vote-via-txt-message">here</a>.</p>
<p>We&#8217;ll be studying this election for centuries.  Great job fellas.  I&#8217;m rooting for your servers holding up!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=130&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2008/10/30/voting-location-via-text-message/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>OSX Uninstallers the Easy Way</title>
		<link>http://adamfisk.wordpress.com/2008/10/22/osx-uninstallers-the-easy-way/</link>
		<comments>http://adamfisk.wordpress.com/2008/10/22/osx-uninstallers-the-easy-way/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 22:16:03 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>
		<category><![CDATA[Adam Fisk]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[do shell script]]></category>
		<category><![CDATA[LittleShoot]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[uninstaller]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=108</guid>
		<description><![CDATA[Back in the old days at LimeWire one of the many tasks I took on was building the installers for all platforms, and I&#8217;ve carried on my installer hacking with LittleShoot. While installers are anything but glamorous, I&#8217;m oddly obsessed with them I think because they&#8217;re your users&#8217; first introduction to your program. They need [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=108&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Back in the old days at LimeWire one of the many tasks I took on was building the installers for all platforms, and I&#8217;ve carried on my installer hacking with <a href="http://www.littleshoot.org">LittleShoot</a>. While installers are anything but glamorous, I&#8217;m oddly obsessed with them I think because they&#8217;re your users&#8217; first introduction to your program. They need to be simple, and they need to work.</p>
<p>One of Mac&#8217;s quirks has always been a lack of uninstallers, leading to widespread global frustration, decreased productivity, and some say a leading cause of the recent financial crisis (a small minority).</p>
<p>Salvation is at hand.  LittleShoot&#8217;s uninstaller is ridiculously simple. It&#8217;s a little snippet of AppleScript that just runs a bash file loaded into it&#8217;s application bundle using &#8220;do shell script&#8221; to run an external script file. Within this framework, your entire uninstaller is basically a bash script. Here are the steps to get this working:</p>
<ol>
<li>Copy the following AppleScript into a file called &#8216;uninstaller.scpt&#8217; and open it in Script Editor. You can also save the binary script from our SVN <a href="http://svn.littleshoot.org/svn/littleshoot/trunk/install/osx/LittleShootUninstaller.scpt">here</a> and open it in Script Editor directly (easier).</li>
<blockquote><p>on onConfirmUninstall()<br />
set applicationName to &#8220;LittleShoot&#8221;<br />
try<br />
display dialog &#8220;Are you sure you want to uninstall &#8221; &amp; applicationName &amp; &#8220;?&#8221;<br />
set uninstallScript to quoted form of POSIX path of (path to resource &#8220;uninstall.bash&#8221;)<br />
do shell script &#8220;bash &#8221; &amp; uninstallScript with administrator privileges<br />
display dialog &#8220;Successfully Uninstalled &#8221; &amp; applicationName buttons {&#8220;OK&#8221;} default button &#8220;OK&#8221;</p>
<p>on error err<br />
if err contains &#8220;User canceled&#8221; then<br />
display dialog &#8220;Canceled &#8221; &amp; applicationName &amp; &#8221; Uninstall&#8221; buttons {&#8220;OK&#8221;} default button &#8220;OK&#8221;<br />
else<br />
display dialog &#8220;We&#8217;re sorry, but there was an error uninstalling &#8221; &amp; applicationName &amp; &#8221; described as: &#8221; &amp; err buttons {&#8220;OK&#8221;} default button &#8220;OK&#8221;<br />
end if<br />
end try<br />
end onConfirmUninstall</p>
<p>onConfirmUninstall()</p></blockquote>
<li>Change the line &#8216;<span>set</span><span> </span><span>applicationName</span><span> </span><span>to</span><span> </span>&#8220;LittleShoot&#8221;&#8216; to &#8216;<span>set</span><span> </span><span>applicationName</span><span> </span><span>to</span><span> </span>&#8220;[your application name]&#8220;&#8216;</li>
<li>Choose File-&gt;Save As&#8230; in AppleScript Editor and save this script as an application bundle that&#8217;s <strong>run only</strong> with <strong>no startup screen</strong> (the options at the bottom when you choose Save As&#8230;). </li>
<li>Navigate via the Terminal to where you saved the bundle and cd into the &#8220;Contents/Resources&#8221; directory. In our case that&#8217;s &#8220;LittleShootUninstaller.app/Contents/Resources,&#8221; so it&#8217;s Contents/Resources within the app bundle.</li>
<li>Create an uninstall.bash file in Contents/Resources. As you can see in the AppleScript above, that&#8217;s the file the AppleScript looks for and executes.</li>
<li>Put whatever you need in uninstall.bash to uninstall your application. The script will run with administrator privileges, so you can really do whatever you want here. Here&#8217;s the LittleShoot uninstall script to get you going, although this is a little quirky because we use things like launchd that most applications don&#8217;t use. You can also grab this directly from our SVN <a href="http://svn.littleshoot.org/svn/littleshoot/trunk/install/osx/LittleShoot/component/LittleShootUninstaller.app/Contents/Resources/uninstall.bash">here</a>.</li>
<blockquote><p>#!/usr/bin/env bash </p>
<p>function die()<br />
{<br />
  echo $*<br />
  exit 1<br />
}</p>
<p>function cleanAndDie()<br />
{<br />
  clean<br />
  die &#8220;LittleShoot is already uninstalled&#8221;<br />
}</p>
<p>function clean()<br />
{<br />
  local plist=~/Library/LaunchAgents/org.lastbamboo.littleshoot.plist<br />
  test -f $plist &amp;&amp; launchctl unload $plist<br />
  rm -rf ~/Applications/LittleShoot.app<br />
  rm -f ~/Library/LaunchAgents/org.lastbamboo.littleshoot.plist<br />
  rm -rf /Library/Receipts/littleshoot.pkg<br />
  rm -rf ~/Library/Receipts/littleshoot.pkg<br />
  rm -rf ~/.littleshoot<br />
  rm -rf ~/Applications/LittleShootUninstaller.app<br />
}</p>
<p>function remove()<br />
{<br />
  rm -rf $1 || die &#8220;Could not remove file: $1&#8243;<br />
}</p>
<p># If it looks like we&#8217;ve already uninstalled, just make sure to remove everything again and die.<br />
test -e ~/Applications/LittleShoot.app || cleanAndDie</p>
<p>launchctl stop org.lastbamboo.littleshoot || die &#8220;Could not stop LittleShoot&#8221;<br />
launchctl unload ~/Library/LaunchAgents/org.lastbamboo.littleshoot.plist || die &#8220;Could not unload&#8221;<br />
rm -rf ~/Applications/LittleShoot.app || die &#8220;Could not remove LittleShoot&#8221;<br />
rm -f ~/Library/LaunchAgents/org.lastbamboo.littleshoot.plist || die &#8220;Could not remove plist&#8221;</p>
<p># We go through all this because the package file is placed differently on Tiger, Leopard, etc.<br />
globalReceipt=/Library/Receipts/littleshoot.pkg<br />
userReceipt=~/Library/Receipts/littleshoot.pkg<br />
test -e $globalReceipt &amp;&amp; remove $globalReceipt<br />
test -e $localReceipt &amp;&amp; remove $localReceipt<br />
rm -rf ~/.littleshoot || die &#8220;Could not remove LittleShoot config folder&#8221;<br />
rm -rf ~/Applications/LittleShootUninstaller.app || die &#8220;Could not remove LittleShoot uninstaller&#8221;</p></blockquote>
</ol>
<p> </p>
<p>So that&#8217;s about all she wrote. You basically just have to set up the uninstaller AppleScript application bundle, and then you can just edit your bash script from then on. The application bundle will use whatever script is stored in its Contents/Resources/uninstall.bash file. I&#8217;ve played around with a lot of different options for doing this, and the straight script file approach kills the other options in terms of maintainability and flexibility. Note that if the uninstaller encounters an error, the AppleScript will display a dialog to the user with anything your script has echoed, so make those errors informative. You also of course have to include the uninstaller application bundle in your installer.</p>
<p>In the end, your users have a simple uninstaller they can just double click on, and you have a really easy way to write and maintain your uninstaller code.</p>
<p>Back to allowing you to post LittleShoot files to Twitter&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/108/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=108&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2008/10/22/osx-uninstallers-the-easy-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Hadoop on EC2 with OpenSolaris</title>
		<link>http://adamfisk.wordpress.com/2008/10/02/hadoop-on-ec2-with-opensolaris/</link>
		<comments>http://adamfisk.wordpress.com/2008/10/02/hadoop-on-ec2-with-opensolaris/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 07:29:10 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[open infrastructure]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[opensolaris]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=96</guid>
		<description><![CDATA[The OpenSolaris crew just announced you can run Hadoop AMIs on EC2 running on top of OpenSolaris. That&#8217;s just cool. I&#8217;m still not ready to abandon my Django code running on App Engine (I&#8217;ve got a post coming up on the stellar new update to Google App Engine Patch, by the way), but I&#8217;d love [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=96&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The OpenSolaris crew just announced you can run Hadoop AMIs on EC2 running on top of OpenSolaris. That&#8217;s just cool. I&#8217;m still not ready to abandon my Django code running on App Engine (I&#8217;ve got a post coming up on the stellar new update to <a href="http://code.google.com/p/app-engine-patch/">Google App Engine Patch</a>, by the way), but I&#8217;d love to play with it. Anyone else given it a go?</p>
<p>You can run it with:</p>
<p>ec2-run-instances &#8211;url <a href="https://ec2.amazonaws.com/" target="_blank">https://ec2.amazonaws.com</a> ami-2bdd3942 -k &lt;your-keypair-name&gt;</p>
<p>You can get more info on running OpenSolaris on EC2 <a href="http://www.sun.com/third-party/global/amazon/Sun_AmazonEC2_GettingStartedAug08Update.pdf">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/96/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=96&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2008/10/02/hadoop-on-ec2-with-opensolaris/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
		<item>
		<title>Dojo 1.2 and Django 1.0 on Google App Engine 1.1.3</title>
		<link>http://adamfisk.wordpress.com/2008/09/17/dojo-12-and-django-10-on-google-app-engine-113/</link>
		<comments>http://adamfisk.wordpress.com/2008/09/17/dojo-12-and-django-10-on-google-app-engine-113/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 21:24:50 +0000</pubDate>
		<dc:creator>adamfisk</dc:creator>
				<category><![CDATA[p2p]]></category>
		<category><![CDATA[adamfisk]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[LittleShoot]]></category>

		<guid isPermaLink="false">http://adamfisk.wordpress.com/?p=69</guid>
		<description><![CDATA[Important Update: Use Google App Engine Patch for Django integration instead. It integrates Django seamlessly and includes lots of other goodies. For Dojo, also consider using xdomain and loading Dojo from Google&#8217;s AJAX Libraries API. For Google App Engine Patch, see my more recent post. This area changes quickly, so check the dates on any [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=69&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><strong>Important Update: </strong>Use <a href="http://code.google.com/p/app-engine-patch/">Google App Engine Patch</a> for Django integration instead. It integrates Django seamlessly and includes lots of other goodies. For Dojo, also consider using xdomain and loading Dojo from Google&#8217;s <a href="http://code.google.com/apis/ajaxlibs/">AJAX Libraries API</a>. For Google App Engine Patch, see my <a href="http://adamfisk.wordpress.com/2008/11/16/easier-django-on-google-app-engine-with-app-engine-patch/">more recent post</a>. This area changes quickly, so check the dates on any blog posts you&#8217;re looking at!</p>
<p>With the release of <a href="http://googleappengine.blogspot.com/2008/09/sdk-113-now-available-for-download.html">Google App Engine 1.1.3 (GAE)</a>, it&#8217;s now much more realistic to serve up Dojo on GAE. <a href="http://www.littleshoot.org">LittleShoot</a> uses a lot of Dojo (mostly because it rocks), so getting <a href="http://dojotoolkit.org">Dojo</a> up and running on our new GAE LittleShoot port has been a high priority.  </p>
<p>The problem is that vanilla Dojo quickly runs up against GAE&#8217;s <span style="color:#ff6600;">1000 file limit</span> per application. Django has the same problem. Our initial solution was to run a custom build that would delete a lot of unnecessary files, with thanks to Peter Higgins from SitePen for <a href="http://www.sitepen.com/blog/2008/04/02/dojo-mini-optimization-tricks-with-the-dojo-toolkit/">lighting our path</a>. This got our build down to about 700 files, solving the problem for the basic LittleShoot site.</p>
<p>We&#8217;re getting ready to release the LittleShoot platform, however, that allows any site to detect if LittleShoot&#8217;s installed and to call the LittleShoot &#8220;P2P 2.0&#8243; API if it&#8217;s available. That means we need external sites to be able to load our JavaScript, i.e. we need to support Dojo&#8217;s cross-domain builds. The cross-domain build adds about another 500 files, pushing us again over the 1000 file limit.</p>
<p>Thankfully, GAE 1.1.3 introduces &#8220;<a href="http://code.google.com/p/googleappengine/source/browse/trunk/google/appengine/ext/zipserve/__init__.py">zipserve</a>,&#8221; allowing you to serve static files directly from a zip file. <span style="color:#ff9900;"><span style="color:#ff6600;">Guido van Rossum</span></span> deployed a similar technique for serving Django for his fantastic <a href="http://code.google.com/p/rietveld/">Rietveld</a> code review tool and GAE demo app, but that only works for loading python code. So we copied Guido for loading Django 1.0, and now zipserve allows us to do more or less the same thing for Dojo.  </p>
<p>To serve Dojo using zipserve, you basically modify your app.yaml to include something like the following:</p>
<blockquote><p>- url: /dojo/.*<br />
  script: $PYTHON_LIB/google/appengine/ext/zipserve</p>
<p>- url: /dijit/.*<br />
  script: $PYTHON_LIB/google/appengine/ext/zipserve</p>
<p>- url: /dojox/.*<br />
  script: $PYTHON_LIB/google/appengine/ext/zipserve</p>
<p> </p></blockquote>
<p>This will look for dojo.zip, dijit.zip, and dojox.zip files in your *top-level* directory, the same directory containing app.yaml. You need to separate the zip files to avoid running up against the GAE limit on file sizes (1MB I believe). The zip file name basically <span style="color:#ff6600;">acts like a directory</span> in App Engine&#8217;s URL resolution. So, when a request goes to <a href="http://beta.littleshoot.org/dojo/dojo.js" rel="nofollow">http://beta.littleshoot.org/dojo/dojo.js</a>, for example, it loads dojo.js from dojo.zip (not from the dojo directory within dojo.zip). Here&#8217;s our script for generating the zips:</p>
<blockquote><p>#!/usr/bin/env bash</p>
<p>function die()<br />
{<br />
  echo $*<br />
  exit 1<br />
}</p>
<p>cd static/js<br />
dirs=&#8221;dojo dijit dojox littleshoot&#8221;</p>
<p>for x in $dirs<br />
do<br />
  cd $x || die &#8220;Could not cd to $x&#8221;<br />
  echo &#8220;Building zip for $x&#8221;<br />
  zf=../../../$x.zip<br />
  rm $zf<br />
  zip -rv $zf * || die &#8220;Could not create zip&#8221;<br />
  cd ..<br />
  # We actually delete all the contents because we don&#8217;t want to <br />
  # include them in GAE.<br />
  rm -rf $x<br />
done</p>
<p>exit 0</p></blockquote>
<p>Even with separating the zip files, dijit and dojox will still come close to the 1MB limit on file sizes.  We use rsync excludes to get rid of the files we don&#8217;t need.  Here&#8217;s our bash rsync excludes function, which you can customize to your liking (careful not to exclude anything you need!!):</p>
<blockquote><p>function excludeRsync<br />
{<br />
  rsync &#8211;exclude .svn/ \<br />
        &#8211;exclude test/ \<br />
        &#8211;exclude tests/ \<br />
        &#8211;exclude demo/ \<br />
        &#8211;exclude demos/ \<br />
        &#8211;exclude soria/ \<br />
        &#8211;exclude nihilo/ \<br />
        &#8211;exclude grid/ \<br />
        &#8211;exclude charting/ \<br />
        &#8211;exclude util/ \<br />
        &#8211;exclude analytics/ \<br />
        &#8211;exclude collections/ \<br />
        &#8211;exclude README* \<br />
        &#8211;exclude *.psd \<br />
        &#8211;exclude *.uncompressed.js \<br />
        &#8211;exclude *.commented.css \<br />
        &#8211;exclude dijit/templates \<br />
        &#8211;exclude dijit/form/templates \<br />
        &#8211;exclude dijit/layout/templates \<br />
        &#8211;exclude *silverlight* \<br />
        &#8211;exclude gfx3d/ \<br />
        &#8211;exclude dojo/_base/ \<br />
        &#8211;exclude dojo/_base.js \<br />
        &#8211;exclude dojo/build.txt \<br />
        &#8211;exclude functional/ \<br />
        &#8211;exclude off/ \<br />
        &#8211;exclude presentation/ \<br />
        &#8211;exclude sketch/ \<br />
        &#8211;exclude storage/ \<br />
        &#8211;exclude wire/ \<br />
        &#8211;exclude data/ \<br />
        &#8211;exclude dtl/ \</p>
<p>        -avz $tmpDir/js $releaseDir || die &#8220;Could not sync&#8221;</p>
<p>}</p></blockquote>
<p>We call the rsync script after running our dojo build.  The <a href="http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/package-system-and-custom-builds">dojo build</a> puts everything in the &#8220;$tmpDir/js&#8221; directory listed on the last line of the rsync.</p>
<p>OK, so there are still some hoops to jump through, but it works!  On the Django 1.0 side, I&#8217;d highly recommend copying Guido&#8217;s <a href="http://code.google.com/p/rietveld/">Rietveld</a> settings.  The <a href="http://code.google.com/p/google-app-engine-django/">Google App Engine Django Helper</a> is also useful, but Django 1.0 support hasn&#8217;t been released as of this writing.  We&#8217;re using Guido&#8217;s settings for now &#8212; basically the Makefile, make_release.sh, settings.py, and main.py.  Oh, I also tweaked his rietveld.py script, turning it into littleshoot.py.  You can find all of these files in the Rietveld svn <a href="http://code.google.com/p/rietveld/source/browse/#svn/trunk">here</a>.  Most of the tweaks to these files are pretty obvious when you glance at the scripts &#8212; nothing super complicated going on.  Not that it&#8217;s a breeze, but each files is individually fairly straightforward.  The scripts will also create a zipped version of django from the django directory, so using svn:externals (described below) is handy.</p>
<p>We load both Django and Dojo with svn:externals. You might be on information overload at this point, but here&#8217;s another little nugget if you&#8217;re still with me. You can run the following in the respective directories where you want Django and Dojo to reside.</p>
<blockquote><p>svn &#8211;editor-cmd=vim pe svn:externals .</p></blockquote>
<p>For Dojo, enter the following:</p>
<blockquote><p>dojo <a href="http://svn.dojotoolkit.org/src/tags/release-1.2.0b2/" rel="nofollow">http://svn.dojotoolkit.org/src/tags/release-1.2.0b2/</a></p></blockquote>
<p>For Django, try:</p>
<blockquote><p>django <a href="http://code.djangoproject.com/svn/django/trunk/django" rel="nofollow">http://code.djangoproject.com/svn/django/trunk/django</a></p></blockquote>
<p>That will put Dojo 1.2 beta 2 in the &#8220;dojo&#8221; directory and the Django trunk in the &#8220;django&#8221; directory when you run &#8220;svn up&#8221;.  </p>
<p>If you successfully navigate through all of that, the end result is the latest Dojo and the latest Django running on the spanking new Google App Engine 1.1.3. Web app setups just don&#8217;t get any sweeter. If you&#8217;re a total geek like me, that&#8217;s living the good life! Sad, I know&#8230;</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/adamfisk.wordpress.com/69/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/adamfisk.wordpress.com/69/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adamfisk.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adamfisk.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adamfisk.wordpress.com&#038;blog=315237&#038;post=69&#038;subd=adamfisk&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adamfisk.wordpress.com/2008/09/17/dojo-12-and-django-10-on-google-app-engine-113/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0a2cafa6dd692e8965f075f80c0f3915?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">adamfisk</media:title>
		</media:content>
	</item>
	</channel>
</rss>
