mtrichardson.comhttp://mtrichardson.com/2010-10-01T20:30:49+00:00Entries and links from mtrichardson.comMoving Forward in Oregon 2010-10-01T20:30:49+00:00http://mtrichardson.com/2010/10/moving-forward-oregon/ <p><strong>As you might expect, all thoughts and opinions expressed here are my own and don't reflect any position of my employer and company, Urban Airship.</strong></p> <p>It's been about sixteen months since four of us met at <a href="http://www.baileystaproom.com/">Bailey's Taproom</a> and decided to go forward with <a href="http://urbanairship.com/">Urban Airship.</a> We had no runway and no idea if what we were going to do was going to work. We've proven the business, have hit a lot of major milestones, talk to an absurd number of mobile devices, are making some amazing technology, and have built an incredible team. All this happened during one of the worst economic depressions.</p> <p>One of my cofounders <a href="http://adam.therobots.org">Adam</a> and myself had been laid off. We were on unemployment, which was enough to live on, but required us to be constantly looking for jobs. One of our friends, <a href="http://discorporate.us/jek/">Jason,</a> then told us about a program that's administered by the state called the <a href="http://www.oregon.gov/EMPLOY/ES/SEEKER/self_employment_assistance.shtml">Self Employment Assistance Program.</a> The program is simple: you receive your unemployment benefits but, instead of job seeking, you work on starting your business.</p> <p>Without this program, Urban Airship would in no way be where we're at now. It allowed us to focus full time on getting up and running. Without it, in those early days we would have had to do consulting or other distractions just to keep personally afloat. The business was doing great, and when the SEA ended after six months, we were able to keep going. It was, however, crucial in those early days that we focus everything we had on the company. Without the assistance of the SEA, we could not have done that.</p> <p>After bootstrapping and proving the business, we received funding from <a href="http://www.trueventures.com/">True Ventures</a> in February. We immediately started hiring. We're up to around fifteen people now and <a href="http://urbanairship.com/jobs">looking for more.</a></p> <p>We're bringing money into Oregon. We're bringing jobs to Oregon. And we couldn't have done it without the SEA. It's an incredible resource and if you're unemployed and thinking about starting something new, I strongly recommend taking a look at it. Not every state does it, but yours might. I'm incredibly grateful that Oregon does.</p> <p><strong>This is where I start ranting about Oregon and politics.</strong></p> <p>Working in Oregon has a lot of advantages. Great culture, low cost living, a thriving creative environment and astonishing natural beauty all together in one place? Yes please. Oregon still has issues, however. We have lots of unemployment and people are looking at cutting basic services, like education, to help the state's financial issues. This concerns me greatly. If people are leaving because they can't find jobs, or because the state can't provide good enough education, then our talent pool is threatened and it becomes more and more difficult to grow successfully.</p> <p>As a cofounder of a growing small business that's bringing jobs into Oregon, the choice is clear. We need strong leaders. We need a strong business environment and a healthy habitat for growing companies, like ours. We need to be able to easily bring in jobs, and employees, into the state, and we need to encourage more entrepreneurship and help get more small businesses off the ground. That's why I'm voting for <a href="http://www.johnkitzhaber.com/">John Kitzhaber,</a> and why I'm encouraging you to take a look as well. Check out his closing statement from the recent debate, as it expresses perfectly why I think he's the right choice:</p> <p><object width="460" height="283"><param name="movie" value="http://www.youtube.com/v/b6HWOZRuzqA?fs=1&amp;hl=en_US&amp;rel=0&amp;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/b6HWOZRuzqA?fs=1&amp;hl=en_US&amp;rel=0&amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="460" height="283"></embed></object></p> <p>There's no question for me that John Kitzhaber should be our next governor. I believe he's the candidate with the experience and values to help businesses like ours get off the ground and thrive.</p> <p>In the video above, Kitzhaber says that Oregon's best days are still ahead. It's a sentiment that I strongly agree with, and I feel the same way about the company I helped start. I hope you'll join me this November in helping make Oregon become an even better place to start, and grow, a company.</p> DjangoCon NoSQL Panel 2010-09-16T19:53:57+00:00http://mtrichardson.com/2010/09/djangocon-nosql-panel/ <p><embed src="http://blip.tv/play/AYH8iksC" type="application/x-shockwave-flash" width="480" height="390" allowscriptaccess="always" allowfullscreen="true"></embed></p> <p>I was on a panel recently at DjangoCon. The topic was NoSQL in Django. You can watch it above if you'd like.</p> <p>At <a href="http://urbanairship.com/">Urban Airship</a> we went from PostgreSQL as the data store for our most used data to MongoDB. This happened around January/February. For us, it was the quickest path away from spending all of our time fighting fires around our usage on Postgres and towards building new features. Given our set of limitations and our goals, I think it was definitely the right move. Let me be clear, however: <strong>Postgres could have done everything we needed it to.</strong> We still use it for a lot of our data. However, we didn't have the time, expertise, or money to be able to implement a good and proper postgres setup that would have alleviated our issues. Mongo was extremely quick to get up and running and handled things well until recently. It's starting to show some pains and there are some low level design decisions that impede our moving forward with it (the first point on <a href="http://ethangunderson.com/blog/two-reasons-to-not-use-mongodb/">Ethan Gunderson's recent post</a> is the most relevant here, but isn't the only one).</p> <p>Joe Stump has some <a href="http://stu.mp/2010/03/nosql-vs-rdbms-let-the-flames-begin.html">flame bait-y but good thoughts around using NoSQL.</a> As I mentioned above, a lot of it comes down to constraints.</p> <p>Architecture and infrastructure is a process. It's fluid. It changes over time as your needs grow and evolve. Eventually, you figure out something that works for the long-near-term. That's about all we can ask for.</p> Posterous and URLs 2010-06-29T04:38:48+00:00http://mtrichardson.com/2010/06/posterous-and-urls/ <p><a href="http://posterous.com">Posterous</a> is a <a href="http://tumblr.com">Tumblr-like</a> service that exists to make blogging easy. Both it and Tumblr do a remarkably good job at that. Lately, Posterous has been promoting all the different services from which they allow you to import your old content. You can take an existing Wordpress blog, Tumblr, whatever kind of service out there and import all the old content into a brand new Posterous account. There is, unfortunately, a grievous problem with this whole process: <strong>URLs are not preserved.</strong></p> <p>Let's say, for the sake of argument, that I'm tired of my hacky home-grown Django blog at http://mtrichardson.com/ and that, for some reason, Posterous supports importing from it. I go through the very quick and easy process, import all my content, and then move to switch the domain over.</p> <p>Except that, if I did that, every link that has ever been made to a piece of content on my blog would be broken.</p> <p>The new imported content is assigned its own URL and there's no way of changing that. Since the domain is entirely under Posterous' control, I can't do any kind of normal trickery around setting up redirects from old content to new content.</p> <p>In my opinion, this is very unfortunate. On top of promoting the spread of duplicate content and causing confusion among followers, it also trains us to not care about the long-term consequences of our hosting decisions. I should be able to move between Tumblr, Posterous, Wordpress, anything you want without breaking things everywhere.</p> <p>That being said, I do recognize that I'm in the minority - this issue only affects people who are using custom domains already (or at least have the ability to 301 requests from the old domain to the new one). That being said - custom URLs would still be a wonderful change to see, and it would be a great feature to build into their importing system.</p> <hr /> <p><strong>Edit (06/29/2010):</strong> If you normally skip the comments section of blog posts (like I do), you might want to make a special effort to check out this one. It's great to such a dedicated team behind Posterous and I can't wait to see the next features.</p> ZNC&#39;s partyline 2010-03-16T22:58:39+00:00http://mtrichardson.com/link/2010/zncs-partyline/ <p>I asked around looking around for what people used for an SSL-and-password-protected private IRC network. <a href="http://twitter.com/IdanGazit">Idan</a> very kindly mentioned that the IRC bouncer <a href="http://en.znc.in/wiki/ZNC">ZNC</a>, which we were using anyway, supports a partyline. A partyline is a private room that's on the bouncer, independent of other networks. Since our ZNC is already behind SSL and password protected, the ability to do a private room on that bouncer fits our needs perfectly.</p> Setting up Hudson on Ubuntu 9.10 with Apache, Django, VirtualEnv, etc. 2010-02-27T16:00:08+00:00http://mtrichardson.com/2010/02/setting-hudson-ubuntu-910-apache-django-virtualenv-etc/ <p><a href="http://hudson-ci.org/">Hudson</a> is the new testing hotness. It's a continuous integration server, like buildbot, except it doesn't take a ton of configuration. However, it can still take a little while to get your build system fully up and running (or at least it did for me) and I wanted to document how I did it in case other people found it useful.</p> <p>First off, a bit about our system: we're a Python shop, we use virtualenv, we have a <a href="http://www.blueskyonmars.com/projects/paver/">paver</a> task to run our tests, the project is a Django project, and we use <a href="http://bitbucket.org/mtrichardson/django_satprep/">django-satprep</a> as our test runner (mmm, <a href="http://somethingaboutorange.com/mrl/projects/nose/0.11.1/">nose</a>). We use Postgres as our database, but we also use <a href="http://www.mongodb.org/display/DOCS/Home">MongoDB</a>. We also wanted to put this on a server that already had <a href="http://www.reviewboard.org/">ReviewBoard</a> on it and just have Hudson be a separate endpoint on that server. And, of course, we didn't want any random yahoo coming along and seeing how our builds were going. This is also the same server where we keep our central hg repo and while that makes some things easy, it's not required.</p> <p>So, let's get going.</p> <h1>Installing Hudson</h1> <p>This was incredibly simple. Hudson has <a href="http://hudson-ci.org/debian/">native packages</a> for Ubuntu, so I just followed the instructions there and I was up and running. I could visit http://myserver:8080/ and see Hudson. Wow. Nice. That was it. Done.</p> <h1>Hooking Hudson up to Apache</h1> <p>Now, to get Hudson working at http://myserver/hudson. This took me a while, though it really shouldn't have. The <a href="http://wiki.hudson-ci.org/display/HUDSON/Running+Hudson+behind+Apache">wiki page on setting up Hudson behind Apache</a> worked great for me. Basically, edit /etc/defaults/hudson to add "--prefix=/hudson" to HUDSON_ARGS (at the bottom of that file). I also edited it to run on port 8081 instead of 8080. Then, restart Hudson.</p> <p>However, here's where the issue was: the restarting of Hudson didn't appear to really... do anything. I saw that the commands in ps aux were with the new information, but it just wouldn't take. After I killed all hudson processes with fire, and restarted Hudson, everything magically worked beautifully. So... that was fun.</p> <p>At any rate, something like:</p> <pre><code>ProxyPass /hudson http://localhost:8081/hudson ProxyPassReverse /hudson http://localhost:8081/hudson ProxyRequests Off &lt;Proxy http://localhost:8081/hudson*&gt; Order deny,allow Allow from all &lt;/Proxy&gt; </code></pre> <p>and an Apache restart later, http://myserver/hudson should welcome you with open arms. Huzzah!</p> <p>You can now go into your Hudson project, click on 'Manage Hudson', and give it your SMTP settings (if you want email notifications) and give it the final URL it lives at. These are both under 'Configure System'/E-Mail Notification.</p> <h1>Protecting Hudson</h1> <p>Hudson by default is kind of "everybody can do everything!" You can lock it down with user controls, but it still showed quite a bit of information that I didn't really want out there. It seemed like the easiest way to protect it would be to put it up behind basic auth in Apache. This was easily accomplished - in Apache 2.2 you can dd the authorization arguments to a <proxy> definition, but I still stuck it in a <Location "/hudson"> block. The only trick here is that I had already enabled authentication in Hudson and the two conflicted. If you're doing auth with Apache, be sure to disable any security in Hudson beforehand. They don't play nice.</p> <h1>Install Plugins</h1> <p>Hudson comes pretty bare-bones, which is nice. The Plugin Manager is nifty - follow the 'Manage Hudson' link and then 'Manage Plugins'. I recommend the following plugins:</p> <ul> <li>Bruce Schneier Plugin</li> <li>Hudson Mercurial Plugin</li> <li>Green Balls</li> </ul> <p>Two are purely cosmetic - the Mecurial plugin is the main one that you need. The install process should work fine, but sometimes seems to just take forever and/or hang. Kicking hudson via /etc/init.d/ will fix it.</p> <h1>Setting up your server</h1> <p>This might be the longest bit, depending on your project needs. I strongly recommend using the same database that you will in production (Postgres, in our case) and make this as true to what you're going to be live with as possible. We manage settings for different environments (development, staging, production, etc.) via different settings files copied to ourproject/local_settings.py, which is then imported at the bottom of our main settings.py file. So, I created a hudson_settings.py that didn't email us on errors, but also used production-like settings. I then tested for a bit in my home directory on that machine to make sure I could check out the project from Mercurial, run our bootstrap.py file to get started (which automatically creates a virtualenv for us, installs libraries, and does a couple of other basic set up tasks), run migrations, etc., and successfully run the tests on that box (if you get failures that aren't related to your setup, great!).</p> <h1>Testing with Hudson</h1> <p>Okay, now joy! We want Hudson to automatically checkout our project, run the bootstrap file, copy over our hudson_settings.py file to local_settings.py, perform any migrations on our main database, and then run our tests. Luckily this is pretty easy to do.</p> <p>On your Hudson install, click on "New Job".</p> <p>Give the job a name, then choose "Build a free-style software project."</p> <p>You'll be taken to the job detail screen. We're doing a Mercurial project, and a local one at that, so once we choose "Mercurial" under the Source Code Management section we enter in the path to the repo on that box. If you don't need a specific branch, just leave it blank.</p> <p>Next, under "Build", add an "Execute Shell" section. This is going to look something like this:</p> <pre><code>#!/bin/bash -ex python bootstrap.py rm -rf bin lib include source ./bin/activate cp myproject/hudson_settings.py myproject/local_settings.py python myproject/manage.py migrate paver test --with-xunit </code></pre> <p><strong>Update:</strong> Before I didn't have that rm -rf in there - we want that to wipe out the virtualenv so we do a full bootstrap. This will catch any libraries that have suddenly stopped working. The real solution is to have your own version of pypi.</p> <p>First off, Hudson uses sh to run these by default, so we put a shebang line in there to force bash (which we need to activate the virtualenv). We copy the hudson_settings over to local_settings, migrate the database (your database should have a decent amount of realish information in there to properly exercise this step), and then test. Our paver task "test" looks like this (in pavement.py):</p> <pre><code>@task @consume_args def test(): """Run manage.py tests in a more friendly manner.""" command_list = ['python', '-W', 'ignore::DeprecationWarning', '-W', 'ignore::SyntaxWarning', 'myproject/manage.py', 'test', '--verbosity=0', '--noinput'] if options.args: command_list.append('--') command_list.extend(options.args) subprocess.check_call(command_list) </code></pre> <p>As you can see, it's pretty basic - it's just a friendly wrapper around manage.py test, which in turn calls django-satprep's nose test runner. However, we do tell it to do xunit - this information gets output in a nosetests.xml file, which is useful for the next step.</p> <p>After we set up the script to execute on each build, check the 'Publish JUnit test result report' and enter 'nosetests.xml' in the 'Test report XMLs' section that will appear. Don't worry if it gives you a warning about it not existing.</p> <p>After that, we activate Bruce Schneier, and E-Mail Notification, telling it to email our whole list if anything goes wrong.</p> <p>So, great! Wonderful!</p> <p>Except right now, we have to manually activate the builds. We could have it poll Mercurial every minute or so, but it's really easy to set up a post-push commit hook to do that for us.</p> <h1>Automatic Builds on Push</h1> <p>It turns out that an authenticated HTTP GET to http://myserver/job/JobName/build will start the build process automatically. We just need to write a commit hook to do that for us.</p> <p>Easy!</p> <p>Here's an example script, notify_hudson.py (note that we use https, you might need just HTTPConnection):</p> <pre><code>import httplib USERNAME = 'myuser' PASSWORD = 'mypass' auth_string = ('%s:%s' % (USERNAME, PASSWORD)).encode('base64')[:-1] def hook(*args, **kwargs): h = httplib.HTTPSConnection('myserver') headers = { 'authorization': 'Basic %s' % auth_string, } h.request("GET", "/hudson/job/JobName/build", headers=headers) resp = h.getresponse() if __name__ == "__main__": hook() </code></pre> <p>Run this to see if your build runs. If it does, then you can hook it up to your repo.</p> <p>In your repo's .hg/hgrc file, put something like this in:</p> <pre><code>[hooks] changegroup.hudson = python:notify_hudson.hook [extensions] notify_hudson = /path/to/notify_hudson.py </code></pre> <p>And you're good to go. When you push upstream, your Hudson build will automatically clone the project, boostrap, run migrations, and run all tests. If something breaks, it'll notify you (and once something is fixed again, it'll do that too). We'll be able to see detailed history of our tests thanks to the junit/xunit integration. It's all awesome.</p> pubsubsuperfeedr 2010-01-28T23:48:41+00:00http://mtrichardson.com/2010/01/pubsubsuperfeedr/ <p>We use <a href="http://superfeedr.com/">Superfeedr</a> to power our RSS-&gt;Push feature. It's pretty great. We released the code we use to talk to Superfeedr. It's <a href="http://bitbucket.org/mtrichardson/pubsubsuperfeedr/src/">pubsubsuperfeedr</a>, available now from pypi. Major thanks to <a href="http://twitter.com/harper">Harper Reed</a> for doing <a href="http://github.com/harperreed/gae-superfeedr-shell/">gae-superfeedr-shell</a> which seriously bootstrapped this.</p> MongoDB is awesome. (Edit: not so fast) 2010-01-08T06:20:49+00:00http://mtrichardson.com/link/2010/mongodb-awesome/ <p>"...as writes occur old data will start migrating to other shards."</p> <p>Thanks <a href="http://adam.therobots.org/">Adam</a> for pointing this out.</p> <p>We recently started using MongoDB at <a href="http://urbanairship.com/">work</a> and, I have to say, it's been an absolute dream so far.</p> <p><strong>Update:</strong> This keeps coming back to haunt me, often in humorous situations. Want to know why? Read <a href="http://wiki.postgresql.org/images/7/7f/Adam-lowry-postgresopen2011.pdf">Adam's dissection of our recent history</a>.</p> PIL, libjpeg, Snow Leopard, and missing _jpeg_resync_to_restart 2009-11-21T02:02:48+00:00http://mtrichardson.com/2009/11/pil-libjpeg-snow-leopard-and-missing-_jpeg_resync_to_restart/ <p>I just spent a lot of time trying to get this working and I figured I should blog about this.</p> <p>The Snow Leopard, libjpeg and PIL combination has a lot of issues. There are tons of blog posts out there about this, and they definitely helped get me a long way.</p> <p><a href="http://proteus-tech.com/blog/cwt/install-pil-in-snow-leopard/">This blog post</a> and <a href="this one">http://proteus-tech.com/blog/cwt/install-pil-in-snow-leopard/</a> both are great for installing PIL and libjpeg, and if those work, <strong>great.</strong> You're done.</p> <p>If, however, you keep getting issues after this when you attempt to import _imaging, try compiling libjpeg as i386.</p> <p>When going to compile libjpeg:</p> <blockquote> <p>CC="gcc -arch i386" ./configure --enable-shared --enable-static</p> </blockquote> <p>And then do the rest normally, and you should be good to go.</p> <p>Good luck.</p> More favorite tools: Gowalla 2009-11-19T19:34:36+00:00http://mtrichardson.com/link/2009/more-favorite-tools-gowalla/ <p>So, full disclosure, I found out about Gowalla because they signed up to use Urban Airship. In other words, Gowalla uses Urban Airship, and I'm a cofounder at UA.</p> <p>HOWEVER</p> <p>That does not dilute Gowalla's awesomeness.</p> <p><img alt="Gowalla home screen" src="http://mtrichardson.com/media/uploads/photo.jpg" /></p> <p>Gowalla is kind of like FourSquare - you check in at locations and your friends are notified that you have done so. I view these apps as an easy way to invite my friends to my location. And, yes, there is the game aspect of it. With FourSquare, you're competing on points and attempting to get mayorships. With Gowalla, you get items - beautifully done images, really - that you can swap with items at the spot you're at or others.</p> <p>FourSquare has several advantages over Gowalla, such as a larger user base, restrictions to city limits (though I do enjoy seeing British friends checking in, it's not exactly useful information) and an API. However, it seems that Gowalla is working hard on these things, so I'm looking forward to them as well. Gowalla also requires that you be within a certain distance around the spot you're checking in at, which is nice.</p> <p>Much like a luxury car vs. an economy car, or a Mac vs. a PC, it's the little features that are so well done that appeal to me about Gowalla. They have a great design and the app is rock solid. I'm definitely a fan.</p> New version of Gabble 2009-11-18T23:02:33+00:00http://mtrichardson.com/link/2009/new-version-gabble/ <p>I figured I should probably be talking a bit more about the tools that I/we use and love.</p> <p>We use <a href="https://www.yammer.com/">Yammer</a> at <a href="http://urbanairship.com/">work</a> and it's fantastic. It fills a perfect niche for sharing information across our four-person team. I've also found that <a href="http://erikhinterbichler.com/software/gabble/">Gabble</a> is the best client for it and, as of the latest update, it solves all but one of my minor beefs with it.</p> <p>It now has image viewing inline (before attachments would often get lost), it will resize the text area without bumping the text below the screen if Gabble is at the bottom of the screen (this is a complicated description, but trust me, it was annoying), and a bug fix that never really affected me.</p> <p>The only thing that Gabble could fix that's bothering me right now is that it often reposts an entire day's worth of Yammer entries (I refuse to call them "yams") to Growl, cluttering that up for a bit. I think this happens when it unexpectedly quits or updates.</p> <p>At any rate, Yammer + Gabble is a very nice tool.</p> Eric Holscher releases Kong 2009-11-18T16:52:45+00:00http://mtrichardson.com/link/2009/eric-holscher-releases-kong/ <p>Kong is a way to run automated Twill tests against a suite of existing services. <a href="http://simonwillison.net/2009/Nov/18/kong/">Simon</a> describes it as a monitoring tool, which I don't think is quite accurate - I'd still use <a href="http://mmonit.com/monit/">monit</a> for that. This is a step above that, doing basic integration testing on production sites to make sure that everything appears happy. I definitely see a use for this, especially when managing a large number of sites that share a code base.</p> FullCalendar - jQuery plugin to provide a calendar interface 2009-11-18T05:19:01+00:00http://mtrichardson.com/link/2009/fullcalendar-jquery-plugin-provide-calendar-interface/ <p>Thanks to <a href="http://jacobian.org/">Jacob</a> for finding this one.</p> <blockquote> <p>"FullCalendar is a jQuery plugin that provides a full-sized, drag &amp; drop calendar ... It uses AJAX to fetch events on-the-fly for each month and is easily configured to use your own feed format (an extension is provided for Google Calendar). It is visually customizable and exposes hooks for user-triggered events (like clicking or dragging an event)."</p> </blockquote> <p>This is just fantastic. I don't have a particular need for it at the moment, but it's very comforting to know that it's there when I do.</p> tender-multipass, Python utilities for easily integrating Tender&#39;s MultiPass authentication 2009-10-19T20:53:00+00:00http://mtrichardson.com/2009/10/tender-multipass-python-utilities-for-easily-integrating-tenders-multipass-authentication/ <p>At <a href="http://urbanairship.com/">Urban Airship,</a> we're evaluating <a href="http://tenderapp.com/">Tender,</a> which is a hosted support and knowledge base app. It's done by <a href="http://entp.com/">ENTP,</a> who are also somewhat located in Portland, OR. We were really liking what we were seeing so decided to do a spike to test it out. One of the nifty features is shared authentication - they'll delegate all auth to your existing app so users don't have to create additional accounts (this really is quite essential for something like this). Their <a href="https://help.tenderapp.com/faqs/setup-installation/login-from-cookies">MultiPass system</a> is relatively easy to implement if you're using Ruby, but Python doesn't have great OpenSSL bindings - the equivalent of <a href="http://ezcrypto.rubyforge.org/">EZCrypto</a> doesn't exist yet, unfortunately. So, after finally getting it working, we decided to release our code so others don't have to go through this process.</p> <p>So, introducing <a href="http://bitbucket.org/mtrichardson/tender-multipass/">tender-multipass</a>, available now on <a href="http://pypi.python.org/pypi/tender_multipass">pypi.</a> The source is <a href="http://bitbucket.org/mtrichardson/tender-multipass/">up on bitbucket.</a></p> <p>As always, I had a lot of help doing this - special thanks to my Urban Airship coworker <a href="http://adam.therobots.org/">Adam Lowry</a>, <a href="http://www.linkedin.com/in/igalk">Igal Koshevoy</a> and <a href="http://www.evanfosmark.com/2008/06/xor-encryption-with-python/">Evan Fosmark for this blog post for the xor stuff.</a></p> Fixing jinja2 and pycrypto (and probably others) on Snow Leopard 2009-09-07T11:28:49+00:00http://mtrichardson.com/2009/09/fixing-jinja2-and-pycrypto-and-probably-others-on-snow-leopard/ <p>I use the <a href="http://python.org/">python.org</a> installs for my system Python. However, these installs assume a 10.4 SDK on the system, which Snow Leopard does not install by default - it's an optional install in the developer tools installer. This causes the C bits to fail with a dramatic flourish of errors. Luckily, there are two easy ways to fix it. The first way, and probably the better one, is to just install the 10.4 SDK. If you're too lazy to hunt for your SL CD (though it's probably early enough that it's still sitting on your desk somewhere) you can modify /Library/Frameworks/Python.framework/Versions/Current/lib/python2.6/config/Makefile and replace all instances of 10.4u with 10.6.</p> <p>There is no way that I figured this out on my own - the wonderful folks in #pocoo on irc.freenode.net helped me out (special thanks to mq and mitsuhiko). Also thanks to <a href="http://www.reddit.com/r/Python/comments/9gpuc/snow_leopard_and_python_compatibility_issues/">this reddit post</a> which contained a few pointers.</p> <p>(note that this is a Python issue, not a Jinja2/PyCrypto/whatever issue)</p> Introducing JSONP-USGS 2009-08-26T09:56:07+00:00http://mtrichardson.com/2009/08/introducing-jsonp-usgs/ <p>I've been playing around with Google Maps a bit. It got to the point where I needed elevation data, so I went looking and came across a wonderful API put out by the United States Geological Survey - it's basically a simple API for elevation. Give it a latitude and a longitude and out spits out the elevation of that point. It makes me happy that it exists.</p> <p>Unfortunately, it doesn't do JSONP, which means I can't really have an interactive application that uses the elevation data - so I made a quick little Werkzeug-powered Google App Engine-hosted wrapper around it. Introducing, <a href="http://jsonpusgs.appspot.com/">http://jsonpusgs.appspot.com/</a>. Pass it a lat and lng and it'll return the elevation data in JSON. Add a callback and you have JSONP. All very, very basic.</p> <p>Here's an example - click anywhere on the map and you'll get the (astoundingly precise) elevation.</p> <iframe src="http://mtrichardson.com/bp.html" style="width: 300px; height: 300px;" scrolling="no"></iframe> <p>Feel free to use and all feedback welcome.</p> Just a tip 2009-05-18T00:23:09+00:00http://mtrichardson.com/2009/05/just-a-tip/ <p>Don't even bother trying to watch videos and other Flash content in Firefox on OS X - Safari just works so much better.</p>