<?xml version="1.0"?>
<rss version="2.0">

<channel>
	<title>Bloodpact Blogging</title>
	<link>http://www.egometry.com/bloodpact/</link>
	<language>en</language>
	<description>Bloodpact Blogging - http://www.egometry.com/bloodpact/</description>

<item>
	<title>Chad Austin: Your Version Control and Build Systems Dont Scale</title>
	<guid>http://chadaustin.me/?p=1508</guid>
	<link>http://chadaustin.me/2010/03/your-version-control-and-build-systems-dont-scale-introducing-ibb/</link>
	<description>&lt;p&gt;Let&amp;#8217;s spend a minute and talk about the performance of a tool you use every day: your build system.  For this purpose, they&amp;#8217;re all the same, so let&amp;#8217;s assume you use GNU Make.  For a no-op build, what is Make&amp;#8217;s running time?  You know, that O(N) stuff.&lt;/p&gt;

&lt;p&gt;If you said &lt;code&gt;O(Files)&lt;/code&gt;, you&amp;#8217;re right.  Every time you type &lt;code&gt;make&lt;/code&gt; and press enter, it scans every file in the project, looking for out-of-date sources.  That doesn&amp;#8217;t sound so bad.  Linear algorithms are good, right?&lt;/p&gt;

&lt;p&gt;Oh, but projects grow over time, typically in proportion with the number of engineers (even if some are &lt;a href=&quot;http://twitter.com/chadaustin/status/8623778614&quot;&gt;net&lt;/a&gt; &lt;a href=&quot;http://twitter.com/chadaustin/status/8624762041&quot;&gt;negative&lt;/a&gt;).  Since projects grow:&lt;/p&gt;

&lt;pre&gt;
O(Files) = O(Engineers * Time)
&lt;/pre&gt;

&lt;p&gt;Assuming you&amp;#8217;re successful, your team is probably growing too:&lt;/p&gt;

&lt;pre&gt;
O(Engineers) = O(Time)
&lt;/pre&gt;

&lt;p&gt;Applying some substitutions:&lt;/p&gt;

&lt;pre&gt;
O(Make) = O(Files) = O(Engineers * Time) = O(Time^2)
&lt;/pre&gt;

&lt;p&gt;A no-op make is &lt;em&gt;quadratic&lt;/em&gt; in the duration of the project?!&lt;/p&gt;

&lt;p&gt;Exhibit A, Mozilla:&lt;/p&gt;

&lt;pre&gt;
Chad@laptop /c/xulrunner/mozilla-central/obj-xulrunner
$ time make
rm -f -rf ./dist/sdk
[tons of output snipped]
make[1]: Leaving directory `/c/xulrunner/mozilla-central/obj-xulrunner'

real    21m31.526s
user    4m13.292s
sys     9m15.066s
&lt;/pre&gt;

&lt;p&gt;21.5 MINUTES!  This is a no-op build!  I changed nothing from the last build!&lt;/p&gt;

&lt;p&gt;Mozilla&amp;#8217;s build is an especially egregious example, but it&amp;#8217;s not uncommon for nontrivial Make, SCons, or Jam no-op builds to exceed 15 seconds.  Every time you run SCons, for example, it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loads Python,&lt;/li&gt;
&lt;li&gt;imports a bunch of Python code,&lt;/li&gt;
&lt;li&gt;creates an entire dependency graph in memory,&lt;/li&gt;
&lt;li&gt;scans all files for changes,&lt;/li&gt;
&lt;li&gt;determines what to build,&lt;/li&gt;
&lt;li&gt;builds it,&lt;/li&gt;
&lt;li&gt;and throws all of those intermediate results away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Am I the only person who thinks this situation is insane?  We&amp;#8217;re spending all of our time improving &lt;a href=&quot;http://www.scons.org/wiki/GoFastButton&quot;&gt;constant&lt;/a&gt; &lt;a href=&quot;http://gamesfromwithin.com/the-quest-for-the-perfect-build-system-part-2&quot;&gt;factors&lt;/a&gt; rather than addressing fundamentally quadratic build algorithms.&lt;/p&gt;

&lt;p&gt;No-op builds should be &lt;code&gt;O(1)&lt;/code&gt; and instantaneous, and most other builds should be &lt;code&gt;O(WhateverChanged)&lt;/code&gt;.  What if I told you this is possible?&lt;/p&gt;

&lt;h2&gt;Introducing IBB: I/O-Bound Build&lt;/h2&gt;

&lt;p&gt;Dusty, one of the best engineers I know, once told me that C compilers are now fast enough that they&amp;#8217;re I/O-bound, not CPU-bound as you&amp;#8217;d expect.  This was inspiration for a &lt;del&gt;build system&lt;/del&gt; dependency engine architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A long-running server process that contains a complete dependency graph between files, including the commands required to update targets from sources.&lt;/li&gt;
&lt;li&gt;An ultra-tiny C program that communicates build requests to the build server.&lt;/li&gt;
&lt;li&gt;A background thread that watches for filesystem updates (via &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa365465(VS.85).aspx&quot;&gt;ReadDirectoryChangesW&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/File_alteration_monitor&quot;&gt;libfam&lt;/a&gt;) and updates the dependency graph in memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have built a prototype of ibb&amp;#8217;s architecture, and its code is available on &lt;a href=&quot;http://github.com/chadaustin/ibb&quot;&gt;my github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In ibb, a no-op build takes constant time, no matter the size of the project.  I tested with Noel Llopis&amp;#8217;s &lt;a href=&quot;http://gamesfromwithin.com/the-quest-for-the-perfect-build-system&quot;&gt;build system stress test&lt;/a&gt; and no-op builds are merely &lt;b&gt;50 milliseconds&lt;/b&gt;.  Take that, everyone else!&lt;/p&gt;

&lt;h2&gt;A Faster Grep&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s say you wanted to run a regular expression across your entire codebase.  On Windows, you&amp;#8217;ll spend all of your time in kernel calls, even if the files are in cache.  However, remember that modern memory bandwidths are measured in GB/s&amp;#8230;&lt;/p&gt;

&lt;p&gt;ibb&amp;#8217;s &lt;a href=&quot;http://github.com/chadaustin/ibb/blob/master/example/search/main.ibb&quot;&gt;file search&lt;/a&gt; implementation can run a regular expression across 200 MB of PHP and JavaScript in &lt;b&gt;100 milliseconds&lt;/b&gt;.  It copies file data into memory on the first run and rapidly scans across that memory on future runs.  It could just as easily mmap and use OS&amp;#8217;s disk cache to avoid kernel calls.&lt;/p&gt;

&lt;h2&gt;Minimal Test Runner&lt;/h2&gt;

&lt;p&gt;Carl Masak&amp;#8217;s inspirational &lt;a href=&quot;http://use.perl.org/~masak/journal/39639&quot;&gt;addictive TDD harness&lt;/a&gt; is also possible with ibb.  If you can determine which unit tests depend on which source files (via an __import__ hook in Python, say), you can run appropriate tests immediately after saving a source file.&lt;/p&gt;

&lt;h2&gt;Version Control&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ve watched both git and Subversion fall apart as a codebase grows.  git is so faaast&amp;#8230;  until you import a 20 GB repository.  Then it&amp;#8217;s &lt;code&gt;O(Files)&lt;/code&gt; just like everything else.&lt;/p&gt;

&lt;pre&gt;
$ time git status
# On branch master
nothing to commit (working directory clean)

real    0m9.603s
user    0m0.858s
sys     0m7.378s
&lt;/pre&gt;

&lt;p&gt;10 seconds to see what files I&amp;#8217;ve modified.  Ouch.&lt;/p&gt;

&lt;p&gt;Imagine if ibb could keep track of which files have changed&amp;#8230;&lt;/p&gt;

&lt;h2&gt;What This Means For You&lt;/h2&gt;

&lt;p&gt;Running tests, grepping code, and building binaries from source are equivalent problems.  ibb&amp;#8217;s architecture supports lightning-fast implementations of all of the above.&lt;/p&gt;

&lt;p&gt;By converting an &lt;code&gt;O(Time^2)&lt;/code&gt; build, test runner, or version control system to &lt;code&gt;O(1)&lt;/code&gt;, we eliminate hours of costly engineer time and encourage good habits like committing often and frequently running tests, no matter the age of the project.  Frankly, instant feedback feels great.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s crazy to me that this architecture isn&amp;#8217;t standard practice across development tools.&lt;/p&gt;

&lt;p&gt;Take &lt;a href=&quot;http://github.com/chadaustin/ibb&quot;&gt;ibb&amp;#8217;s concepts or code&lt;/a&gt;, integrate it with your engineering processes, and improve the quality of your team&amp;#8217;s life today.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/eisD9teKN2c&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 04 Mar 2010 08:02:18 +0000</pubDate>
</item>
<item>
	<title>Michael Rooney: Why I Switched from Ubuntu One back to Dropbox</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-1825431327919946565</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/AvTvOZQ1ZpI/why-i-switched-from-ubuntu-one-back-to.html</link>
	<description>As many of you surely know, Dropbox and Ubuntu One are applications to keep files on your desktop in sync across multiple computers, and backed up in the cloud. After using Dropbox for a year or so on Ubuntu, the Ubuntu One project came out and I thought I'd move over to it. I assumed it would be easier to set up, being pre-installed, and could integrate better with the file manager and other applications, being made specifically for Ubuntu.&lt;br /&gt;&lt;br /&gt;After about 6 months of using Ubuntu One, I found it to be too much of a regression compared to Dropbox and switched back. I thought I'd detail why here for the usefulness of others and to hopefully provide some constructive criticism to the Ubuntu One team which overall is doing good work. So here's why I went back to Dropbox:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Better Nautilus integration&lt;/b&gt;&lt;br /&gt;The nautilus (file manager) integration in Dropbox feels very mature and polished. Normally I'd say this is to be expected since Ubuntu One is much younger, but since the nautilus aspect of Dropbox is open-source, there didn't seem to be much of an excuse for the Ubuntu One team to not use it as a starting point or at least as inspiration. Whenever I added files to my Ubuntu One folder, no matter how large or how many, they instantly had the checkbox emblem which implies to me they are in sync, even though they couldn't possibly be uploaded that quickly. In Dropbox, the files show an animated progress emblem until they are actually uploaded, and show this again when they are being updated. I wasn't able to trust the status of files with Ubuntu One, and that wasn't a good feeling.&lt;br /&gt;&lt;br /&gt;Sharing files in Dropbox is also a lot easier via Nautilus, but that deserves it's own point.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Easier file sharing&lt;/b&gt;&lt;br /&gt;In my typical use cases of file sharing, I want to go from having a file in mind to someone else seeing that file as quickly as possible, be it in an instant message, chatroom (IRC/Jabber), or email to a friend or two. Dropbox makes this a breeze; drag a file into the &quot;Public&quot; folder in your Dropbox directory, and right-click on it and select &quot;Dropbox &gt; Copy Public Link&quot;. Now you have a publicly accessible link to your file in your clipboard!&lt;br /&gt;&lt;br /&gt;I never quite figured out how to do this in Ubuntu One; it seems you have to share files with specific people who also are running Ubuntu One (which really compounds the non-cross-platform issue) via the web interface by typing in an email address. This is a cool idea, but seems way over-engineered as a starting point. This was even brought up at the last UDS in an Ubuntu One session but was brushed off; they sadly seemed more interested in engineering complex sharing UIs than getting feedback to ensure they were solving actual problems.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Sane notifications&lt;/b&gt;&lt;br /&gt;I think &lt;a href=&quot;https://bugs.launchpad.net/ubuntuone-client/+bug/462747&quot;&gt;bug 462747&lt;/a&gt; is what ultimately drove me to drop Ubuntu One. It notifies you not once but twice for every file you change; once to tell you it is syncing the file and another to tell you it is done. Regarding the first notification, I probably already know that I changed that file; regarding the second, if I'm really curious about the status of the synchronization, a quick glance at the applet should tell me what I need to know. This was mildly annoying as is, but it does this for hidden files like vim swap files too. Every time I would open or save a file in vim (and I save early and often), I got two notifications about syncing the hidden swap file!&lt;br /&gt;&lt;br /&gt;Dropbox was much more sane regarding notifications; whenever I would turn on or sit down at a computer, it would show &lt;b&gt;one&lt;/b&gt; notification telling me how many files it synced from other machines or, if there was just one changed file, the name of it. Beautiful!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Better web UI&lt;/b&gt;&lt;br /&gt;The web user interface for Dropbox felt a lot easier to use, and I often had problems where the Ubuntu One web view would show deleted files or not show files I knew were there that were added days ago. Sometimes I had to collapse and expand a folder a time or two to get it to show the right contents. This led to a similar problem that I mentioned with the nautilus integration; it wasn't a UI I could trust to be accurate as was therefore essentially useless. The Dropbox UI was always accurate, and had some nice extras which could prove to be lifesavers like getting past versions of files.&lt;br /&gt;&lt;br /&gt;I also experienced some other issues including &lt;a href=&quot;https://bugs.launchpad.net/ubuntuone-client/+bug/498444&quot;&gt;bug 498444&lt;/a&gt; which caused Ubuntu One applet to start up with the exclamation icon, giving the impression of not syncing files. If I wanted to edit or view a file that might have changed remotely, I had to manually tell the applet to try syncing again after startup to make sure the file was latest version (or else I could silently end up with .u1conflict file, but that's another issue). Additionally, although the transparency is praiseworthy, &lt;a href=&quot;http://twitter.com/UbuntuOne/status/9498991639&quot;&gt;all&lt;/a&gt; &lt;a href=&quot;http://twitter.com/UbuntuOne/status/9331800792&quot;&gt;these&lt;/a&gt; &lt;a href=&quot;http://twitter.com/UbuntuOne/status/9292086471&quot;&gt;tweets&lt;/a&gt; &lt;a href=&quot;http://twitter.com/UbuntuOne/status/9020860066&quot;&gt;about&lt;/a&gt; &lt;a href=&quot;http://twitter.com/UbuntuOne/status/8963442390&quot;&gt;recent&lt;/a&gt; &lt;a href=&quot;http://twitter.com/UbuntuOne/status/7755587471&quot;&gt;issues&lt;/a&gt; or &lt;a href=&quot;http://twitter.com/UbuntuOne/status/8870678995&quot;&gt;downtime&lt;/a&gt; do not inspire confidence.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;That being said&lt;/b&gt;&lt;br /&gt;Ubuntu One does have a few things going for it, however. It is installed by default which means it is the easiest cloud sync/backup solution to get started with for an Ubuntu user. And thanks to CouchDB and a package manager, Ubuntu can ship applications that make it trivial to sync their data with Ubuntu One out of the box. If I can tell all the applications I care about to sync with Ubuntu One (bookmarks, notes, podcasts, basic OS settings/appearance) from one configuration UI, that's going to be pretty compelling.&lt;br /&gt;&lt;br /&gt;While I currently can't in good conscience recommend Ubuntu One to a friend (and plenty of my friends don't even use Ubuntu), I do have high hopes for the project; it is young and if they can work out some of the above issues, many of them being personal show-stoppers, while providing application and OS integration, Ubuntu One (and perhaps Ubuntu itself) could become too compelling to not use for many people. For now however, Dropbox is the solution which stays out of my way, allows me to solve my problems, and just works.&lt;br /&gt;&lt;br /&gt;If you are using Ubuntu One or Dropbox, certainly chime in on what the critical features are for you and why you chose one over the other!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-1825431327919946565?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/AvTvOZQ1ZpI&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 22 Feb 2010 23:01:53 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Jeff Lindsay: The latest from Wozniak</title>
	<guid>http://progrium.livejournal.com/236161.html</guid>
	<link>http://progrium.livejournal.com/236161.html</link>
	<description>&quot;My latest idea that I've been expressing is that there's no real value to humanity in creating technology like computers. What really matters and makes a difference is when you do something nice for someone else, like tying the shoe of a child. Or bringing smiles to any stranger.&quot;</description>
	<pubDate>Wed, 17 Feb 2010 05:33:25 +0000</pubDate>
</item>
<item>
	<title>Chuck Rector: Poisonous devices</title>
	<guid>tag:blogger.com,1999:blog-3327768276254607141.post-4653380857422514326</guid>
	<link>http://choosetheforce.blogspot.com/2010/02/poisonous-devices.html</link>
	<description>&lt;h2&gt;Phones&lt;/h2&gt;

&lt;p&gt;Sometimes, it's nice when friends and family call. I've even been pleasantly surprised by strangers before. Other times, people call me for the wrong reasons and at the wrong times. I used to believe that when phones ring they must be answered, but that's no longer the case. A phone is an assistive device. If it's not assisting me then what value does it provide?&lt;/p&gt;

&lt;p&gt;I used to be terrified of phones. After a part-time job which required a lot of phone time with strangers, that terror went away. Except that in hindsight I don't think it did. It was always stressful. I simply grew to accept that stress.&lt;/p&gt;

&lt;p&gt;Over the years I've been tuning my phone usage. I used to answer every call because it was about facing my fear. Then I answered every call because... that's just what you do. It's a phone! Then I realized that it's not my job to answer the phone. This was an important realization for me, because that part-time job had programmed me to believe that it was. I began answering the phone less and less.&lt;/p&gt;

&lt;p&gt;These days, I hardly ever answer my phone. One huge source of stress: gone.&lt;/p&gt;

&lt;p&gt;This sometimes means I miss calls from friends and family, but ultimately the people I know and love have many ways to reach me. If a chat on the phone is absolutely necessary, it will happen. Eventually. If it's a call from a stranger about random crap I don't care about, guess what: I win. You are unlikely to call me again.&lt;/p&gt;

&lt;p&gt;One of my favorite things to do is to turn off my phone. Especially when I go to sleep. Often I'll turn it off when I get home after work as well. And it's fantastic. Especially the part where I'm never jarred awake in the middle of the night.&lt;/p&gt;

&lt;h2&gt;Clocks&lt;/h2&gt;

&lt;p&gt;I used to have a watch and I would look at it all the time. If I'm at the bus stop waiting for the bus, I'm checking my watch. If I'm at work and wishing that lunch would come, I'm checking my watch. If I'm wishing work is over so I can go home, I'm checking my watch. If I'm waiting for a friend to come over, if I'm waiting for a show to come on, if I'm trying not to stay up too late...&lt;/p&gt;

&lt;p&gt;I decided that looking at clocks is stressful. How about I just change how I'm living so I don't need to look at them? That's what I do now. I engineer my life to alleviate stress and to optimize fun and learning.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't look at bus schedules anymore. Instead, I get enough sleep, wake up refreshed, and walk over to the bus stop when I'm good and ready. This is usually hours before I need to be at work, so I'm never in a rush. I listen to music while I wait, enjoy the cool morning air, and watch the birds while I munch on an apple. Some mornings are foggy and wet and some are bright and warm. I notice and appreciate them because I'm not late for work, I'm not tapping my toe, and I'm not constantly looking at my watch.&lt;/li&gt;
&lt;li&gt;There are dozens of ways to alleviate stress at work, and I ruthlessly identify and crush them. As a result, I'm not wishing lunch would come quickly so I can get a moment's relief. I'm not wishing the day would end so I can go home and get a few more moments of relief. I've made my work incredibly satisfying. When lunch rolls around, it's usually a happy surprise. Same thing for the end of the day. So much so that I come into the office on weekends because it's an enjoyable part of my life that I want to experience daily.&lt;/li&gt;
&lt;li&gt;It turns out that once I alleviated so much stress in other parts of my life, I also alleviated boredom. For me, boredom was the end result of living in a constant state of stress. This may not make immediate sense, but when I was in a constant state of stress, I was always doing one of two things: stressing or recovering. In that mode of living, I was never actually spending time on myself, either by having fun or by feeding my mind with fulfilling personal learning. Even when I thought I was doing these things, I really wasn't. In that severe state of stress, I believe there was no fun or personal learning. There was a heavy weight which pushed me down and which permeated everything I did. What I thought was fun or learning was instead &quot;escape&quot;. Enter boredom: when escape velocity was not sufficient to outmatch stress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever I think about clocks, I think about the rabbit from Alice in Wonderland. I don't want to be That Guy, running around, worrying his head off, with precious little time to spend on himself. I'm valuable to myself, so I make plenty of time for me.&lt;/p&gt;

&lt;h2&gt;Alarms&lt;/h2&gt;

&lt;p&gt;Alarms are like clocks, plus a punch in the face. If I don't like waking up in the middle of the night when I'm not done sleeping, then I don't like waking up in the morning when I'm not done sleeping either. How about I just get enough sleep so that I don't need an alarm?&lt;/p&gt;

&lt;p&gt;I have also learned that caffeine is the catalyst for my own personal hell (another poisonous device!) It kicks off a vicious cycle. I drink caffeine. I am amped. I come down off the high. I drink more. It's late and I'm full of energy and my body's burning calories so I eat. I now have even more energy. I stay up late. I have to get into work early so I set an alarm. Too few hours later, my alarm punches me in the face. I drink caffeine to jump start my system. And away we go...&lt;/p&gt;

&lt;p&gt;As I mentioned, I turn my phone off when I go to sleep. It's not entirely a coincidence that my phone is also my alarm (iPhone.) I turn it off with purpose. When I'm sleeping, phone calls and alarms are equivalent. Depriving myself of sleep does not improve my life. I control my phone, therefore I choose to improve my life by turning it off when I'm sleeping.&lt;/p&gt;

&lt;p&gt;Alarms should be used for alarming circumstances. Like fires. Not burning to death is a good way to add value to my life. Other alarms, not so much.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3327768276254607141-4653380857422514326?l=choosetheforce.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 14 Feb 2010 11:46:00 +0000</pubDate>
	<author>noreply@blogger.com (卡车 Chuck)</author>
</item>
<item>
	<title>Chuck Rector: Right the wrongs</title>
	<guid>tag:blogger.com,1999:blog-3327768276254607141.post-1887807750003621505</guid>
	<link>http://choosetheforce.blogspot.com/2010/02/right-wrongs.html</link>
	<description>&lt;p&gt;It's difficult and painful and time-consuming to switch from a habitual lifestyle of bitching over to one of fixing, but it's possible to change. My first impulse when encountering foreign and confusing code has always been to complain about it to someone, immediately. It's such a dumb and mindless thing to do, but I've done it a million times. On some level it's about camaraderie. Wah-wah, it sucks, let me cry on your shoulder. You understand how awful this is, right?&lt;/p&gt;

&lt;p&gt;My first attempts at correcting this behavior focused on the wrong thing: demeanor. It's not bitching if I'm calm, collected, and diplomatic when I say it right? It's okay if I try to trick myself into thinking I made an attempt, but was mostly silently seething to myself, and then came to you for help right? What a passive-agressive waste of someone else's time. There's help and then there's hand-holding. Instead, my focus needed to be on solving problems, not the injustice of hard ones and trying to foist them on others.&lt;/p&gt;

&lt;p&gt;This video &lt;a href=&quot;http://www.youtube.com/watch?v=k2h2lvhzMDc&quot;&gt;http://www.youtube.com/watch?v=k2h2lvhzMDc&lt;/a&gt; (Ed Catmull, Pixar) reminded me of useless bitching (the kind I envision &quot;mediocre teams&quot; would participate in) and that my programmed response in the face of difficulty should be one of reason and action rather than victimization. It's not that someone intended to punch me in the face with their code, it's that the target has shifted and I need to correct course. It's not about personal vendetta, it's about what works and what doesn't work.&lt;/p&gt;

&lt;p&gt;This is my reminder to myself to be intelligent and thoughtful and to right wrongs rather than wallow, sidestep, or avoid. I righted wrongs today, and it's awesome.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3327768276254607141-1887807750003621505?l=choosetheforce.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 12 Feb 2010 00:03:00 +0000</pubDate>
	<author>noreply@blogger.com (卡车 Chuck)</author>
</item>
<item>
	<title>Michael Rooney: wxBanker 0.7: simple personal finance</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-4269198340218823775</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/8tIxeqNnkG8/wxbanker-07-simple-personal-finance.html</link>
	<description>Your favorite personal finance application, &lt;a href=&quot;https://launchpad.net/wxbanker&quot;&gt;wxBanker&lt;/a&gt;, has turned 0.7!&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/S29A7hvLBVI/AAAAAAAAAbg/d0PZdNtqyqI/s1600-h/wxBanker-0.7a.png&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/S29A7hvLBVI/AAAAAAAAAbg/d0PZdNtqyqI/s400/wxBanker-0.7a.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5435634666672162130&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This release comes about 2 months after the previous release, and focuses on usability and user experience issues that I obtained from watching people use wxBanker as well as from Launchpad bugs (thanks &lt;a href=&quot;https://bugs.launchpad.net/wxbanker/+bug/496878&quot;&gt;Arty&lt;/a&gt;!). Let's take a look at some of the changes, starting with the account control:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/S28ugG2hSQI/AAAAAAAAAbQ/iIskUB1WYi0/s1600-h/wxbanker-6-7-accountctrl.png&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/S28ugG2hSQI/AAAAAAAAAbQ/iIskUB1WYi0/s400/wxbanker-6-7-accountctrl.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5435614404389456130&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On the right we have the new account chooser in 0.7. The main change is using radio buttons for the accounts instead of links. This is a much better, already understood method for choosing accounts, and will also fit in with themes better. The last item is now &quot;All accounts&quot; and is selectable, making it easy to get a view of all your transactions and search in them.&lt;br /&gt;&lt;br /&gt;The &quot;Hide zero-balance accounts&quot; option has moved to the View menu, and now has a keyboard shortcut. I've also removed the total number of accounts from the header, as well as the colons after the account names, to reduce clutter. Finally, everything has been given a bit more padding and the buttons have been slightly rearranged.&lt;br /&gt;&lt;br /&gt;Additionally, the previous graphing library has been replaced by cairoplot (thanks &lt;a href=&quot;https://blueprints.launchpad.net/wxbanker/+spec/replaceable-plot-renderers&quot;&gt;Karel&lt;/a&gt;!), which looks much more attractive. Let's check it out:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_HU7L5oFDSeA/S286U7l8uqI/AAAAAAAAAbY/ztBe-P27WY4/s1600-h/wxBanker-0.7b.png&quot;&gt;&lt;img src=&quot;http://1.bp.blogspot.com/_HU7L5oFDSeA/S286U7l8uqI/AAAAAAAAAbY/ztBe-P27WY4/s400/wxBanker-0.7b.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5435627406528133794&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Summary view allows you to see a graph of your balance over time, and you can view a graph of a specific account or all accounts by using the account chooser on the left (previously the graph had its own account chooser, that was silly!).&lt;br /&gt;&lt;br /&gt;And in case you missed the 0.6 announcement, that version brought recurring transactions, XDG directory support, and more intuitive behavior regarding deleting/editing transfer transactions.&lt;br /&gt;&lt;br /&gt;For downloads and the full list of features and bug-fixes, check out the &lt;a href=&quot;https://launchpad.net/wxbanker/0.7/0.7&quot;&gt;release page&lt;/a&gt;. You can also add &lt;a href=&quot;https://launchpad.net/~wxbanker-users/+archive/ppa&quot;&gt;the PPA&lt;/a&gt; for easy installation and upgrades.&lt;br /&gt;&lt;br /&gt;If you'd like to stay in the loop join the &lt;a href=&quot;https://launchpad.net/~wxbanker-users&quot;&gt;wxBanker Users team&lt;/a&gt; (and announcement mailing list) on Launchpad, follow &lt;a href=&quot;http://twitter.com/wxbanker&quot;&gt;wxBanker on Twitter&lt;/a&gt;, or hang out in #wxbanker on irc.freenode.net.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-4269198340218823775?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/8tIxeqNnkG8&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 07 Feb 2010 18:15:00 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Chuck Rector: I am posting to my blog. Stop.</title>
	<guid>tag:blogger.com,1999:blog-3327768276254607141.post-2781556933171699107</guid>
	<link>http://choosetheforce.blogspot.com/2010/02/i-am-posting-to-my-blog-stop.html</link>
	<description>&lt;p&gt;I am kind of amused by people who end their emails with their name. Your name is in my contact list. I can read the From: field. I know who you are.&lt;/p&gt;

&lt;p&gt;Even more amusing is when they end it with a single letter. Is that supposed to be a signature? I don't get it. If you're going to use a signature, make it cool.&lt;/p&gt;

&lt;p&gt;For example, there's this guy who &quot;signs&quot; all of his CSS with this:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;c(~)&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;It's a mug of beer with a handle and sloshitude inside, see? Awesome.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3327768276254607141-2781556933171699107?l=choosetheforce.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 02 Feb 2010 17:52:00 +0000</pubDate>
	<author>noreply@blogger.com (卡车 Chuck)</author>
</item>
<item>
	<title>Jeff Lindsay: On Knowledge</title>
	<guid>http://progrium.livejournal.com/235792.html</guid>
	<link>http://progrium.livejournal.com/235792.html</link>
	<description>Despite conventional wisdom, knowledge is not just a collected body of facts. This is because that's exactly what information is, so knowledge must be something else. In fact, it's so much more.&lt;br /&gt;&lt;br /&gt;First of all, I argue that knowledge must be validated to be knowledge. You might hear about wrong information, but rarely do you hear about wrong knowledge. In fact, you commonly hear knowledge associated with truth. This is because knowledge is acquired through experience, the validation of consistency against reality. As they say, you never know until you try. &lt;br /&gt;&lt;br /&gt;I also argue that knowledge is not real until it is learned. In a sense, knowledge doesn't exist outside of a person. We talk about our collected body of knowledge, but we're really talking about people and the knowledge they have, or had when they were alive. Anything else is merely information, potential knowledge that has yet to be validated and internalized. Although we trust certain information to be validated &quot;knowledge&quot; since it was once acquired by someone else, it's only an assumption until you have learned it (experienced it) for yourself.&lt;br /&gt;&lt;br /&gt;Whether you buy that or not, we all seem to agree that knowledge is power. This is revealing about knowledge when you consider that power is defined as the capacity to cause change. This implies that the nature of knowledge is biased towards the idea of how-to. Although we consider the declarative what-is-true knowledge of, say, mathematics, to be knowledge, it is only a shorthand for the proof behind it, and the process of deriving a proof is obviously a question of how-to.&lt;br /&gt;&lt;br /&gt;The idea that knowledge is concerned with change and *how* things happen is important in contrast to why things happen. The fundamental difference between how and why is that how is concerned with structure and process, while why is concerned with function and meaning. The how of something can be determined without context through analysis. How does it work? Take it apart and find out! The why of something is highly dependent on context and synthesis. Why do we have xyz? You'll *never* know from taking xyz apart. Meaning comes from the outside. It accumulates not as knowledge, but as understanding.&lt;br /&gt;&lt;br /&gt;A probably more significant implication of knowledge being about change and process, is its relation to computer science. Not computer science as in the specific field of study, but computer science as the essence of computation. Perhaps, philosophy of computation. What computation and programming are about is the notion of formalizing intuitions about . . . process. &lt;br /&gt;&lt;br /&gt;Harold Abelson, co-developer of MIT's introductory computer science course, says computer science is not even so much about the computer. &quot;When a field is just getting started, it's easy to confuse the essence of that field with the tools that you use.&quot; I think the big significance of computation is not computation at all . . . it's about a means to formally talk about knowledge itself.&lt;br /&gt;&lt;br /&gt;We have general language as a formal expression of information and data, and we have basically programming and computers as a formal expression of knowledge and process. This leads me to wonder: what will we develop that allows us to formally express understanding and meaning? What kind of revolution will that be?</description>
	<pubDate>Tue, 02 Feb 2010 17:36:18 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Learning from disparity, aka “failure”</title>
	<guid>http://blogrium.wordpress.com/?p=169</guid>
	<link></link>
	<description>I&amp;#8217;ve long argued that failure is the only way a person can learn. This has been a very reasonating bit of wisdom for me, despite the fact people have often argued against it with rather sound logic. &amp;#8220;Yes, you can learn from failure, but you can also learn from success!&amp;#8221; Only after reading Jason Fried&amp;#8217;s [...]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=169&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;</description>
	<pubDate>Tue, 02 Feb 2010 07:32:14 +0000</pubDate>
</item>
<item>
	<title>Michael Rooney: Automating translation template generation and check-ins for Launchpad</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-9058984383653396016</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/yZY-qKeOmgQ/automating-translation-template.html</link>
	<description>I &lt;a href=&quot;http://mrooney.blogspot.com/2009/07/launchpad-is-now-automatic-magical.html&quot;&gt;previously wrote&lt;/a&gt; about how excited I was for the automated translation import and export features of Launchpad. Launchpad will automatically notice when you commit a translation template and import it, making it available for translation online. Generous translators will then contribute translations, and Launchpad will commit them back to your project.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_HU7L5oFDSeA/S2fxD3QRaNI/AAAAAAAAAbI/AfTFW4D9U7s/s400/thumbsup.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5433576524119894226&quot; /&gt;&lt;br /&gt;Okay, so this is pretty good! However for this process to work well, the translation template needs to be generated manually by a developer whenever there are changes to strings. Otherwise, translators are working on potentially outdated strings; some are perhaps not in the application anymore, and there are likely some strings which aren't in the template yet.&lt;br /&gt;&lt;br /&gt;After forgetting to generate and commit my template until shortly before a release more than once (and thus having poor translation coverage on newly added strings), I decided to automate this part of the process as well. All it took was a relatively small script to generate the template, and then if there were any changes, commit and push to the branch configured for automatic import in Launchpad. The following script does just that, by searching for any files using gettext calls starting with _(&quot; or _(', and passing them to xgettext.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: bash&quot;&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;set -e&lt;br /&gt;ack-grep &quot;_\([\&quot;\']&quot; -l | xargs xgettext --output=wxbanker/po/wxbanker.pot&lt;br /&gt;ACTUALCHANGES=&quot;`bzr diff | grep \&quot;^[\-\+]msg\&quot; | wc -l`&quot;&lt;br /&gt;if [[ &quot;$ACTUALCHANGES&quot; != &quot;0&quot; ]]; then&lt;br /&gt;  bzr ci -m &quot;automated generation of translation template&quot;&lt;br /&gt;  bzr push :parent&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that if you aren't using Python, you may need to tweak the regular expression supplied to ack-grep. Once the template is generated, the diff is piped through grep to grab any changes to actual messages and make sure there was at least one. Otherwise there would always be changes due to the timestamp in the template, causing useless commits.&lt;br /&gt;&lt;br /&gt;I then threw this script into a &lt;a href=&quot;http://hudson-ci.org/&quot;&gt;Hudson&lt;/a&gt; job, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Continuous_integration&quot;&gt;Continuous Integration server&lt;/a&gt; I use for &lt;a href=&quot;https://launchpad.net/wxbanker&quot;&gt;wxBanker&lt;/a&gt;. I configured this particular job to run nightly, pulling down the latest bzr branch beforehand, and emailing me on any failures.&lt;br /&gt;&lt;br /&gt;It seems to be working quite well and ensures translators are always translating the latest strings and leaves nothing for me to forget, smoothing out the release process.&lt;br /&gt;&lt;br /&gt;If this sounds interesting to you but you're not familiar with Launchpad as a translation system, check out &lt;a href=&quot;http://blog.launchpad.net/general/trying-out-launchpad-translations&quot;&gt;http://blog.launchpad.net/general/trying-out-launchpad-translations&lt;/a&gt; and feel free to ask any questions here. If you do have experience with translations, how do you handle generating translation templates and then integrating the translations?&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-9058984383653396016?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/yZY-qKeOmgQ&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 02 Feb 2010 01:35:52 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Jessy Cowan-Sharp: Culture of Yes</title>
	<guid>http://blog.quaternio.net/?p=515</guid>
	<link>http://blog.quaternio.net/2010/01/06/culture-of-yes/</link>
	<description>Washington, DC&amp;#8217;s recently released open government directive has a lot of us in the open government community stoked about the mandate we are finally being given, collectively and formally, to make government more transparent and accessible. 
The three tenets of participation, transparency, and collaboration are particularly relevant because, while they are couched in specific deliverables [...]</description>
	<pubDate>Wed, 06 Jan 2010 21:30:45 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: Comparing Final Fantasy III to Final Fantasy IV</title>
	<guid>http://chadaustin.me/?p=1491</guid>
	<link>http://chadaustin.me/2010/01/comparing-ff3-to-ffantasy-iv/</link>
	<description>&lt;p&gt;Having grown up with Final Fantasy IV on SNES, I recently enjoyed playing through &lt;a href=&quot;http://www.amazon.com/gp/product/B000GABOTU?ie=UTF8&amp;#038;tag=aegisknightor-20&amp;#038;linkCode=as2&amp;#038;camp=1789&amp;#038;creative=390957&amp;#038;creativeASIN=B000GABOTU&quot;&gt;Final Fantasy III&lt;/a&gt;&lt;img src=&quot;http://www.assoc-amazon.com/e/ir?t=aegisknightor-20&amp;#038;l=as2&amp;#038;o=1&amp;#038;a=B000GABOTU&quot; width=&quot;1&quot; height=&quot;1&quot; alt=&quot;&quot; /&gt;.  For my own edification and those curious, I&amp;#8217;d like to note some of the design similarities between the games, providing color on the evolution of the Final Fantasy franchise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Airships are a primary theme, both as transportation and cultural status.&lt;/li&gt;
&lt;li&gt;Final Fantasy 3 introduced the character class system in a big way, setting the stage for the classes used in FF4&amp;#8217;s story.&lt;/li&gt;
&lt;li&gt;Desch and Yang provide similar service to their respective stories: help the party for a while, followed by dramatic sacrifice.&lt;/li&gt;
&lt;li&gt;FF3 introduced the Toad and Mini status effects as first-class gameplay elements.  Toad allows you to swim and Mini allows you to fit in tiny passages.  While Mini, your attacks are useless but magic still works.  These status effects remained in FF4, although vestigial.  (I always wondered why &amp;#8220;mini-mages&amp;#8221; were so common in FF4.  Without having played FF3, they didn&amp;#8217;t make sense.)&lt;/li&gt;
&lt;li&gt;FF3 introduced the Leviathan, Odin, Bahamut hierarchy.&lt;/li&gt;
&lt;li&gt;Eureka (FF3) paralleled the Lunar Subterrane (FF4).  They&amp;#8217;re both extremely hard when you first enter, but they force the party to gain about ten levels.  In addition, they contain several smaller bosses and a bunch of powerful equipment.  Both provide a sense of progress and accomplishment, without feeling like grind.&lt;/li&gt;
&lt;li&gt;The last areas and bosses of both games are unusually difficult.  They each took me multiple attempts to complete.&lt;/li&gt;
&lt;li&gt;In both final battles, previous allies provide &amp;#8220;spiritual assistance&amp;#8221;, making it possible to defeat the overpowering final boss.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However incomplete this list, these are the similarities I noted.  Final Fantasy 3 had not quite discovered the Final Fantasy &amp;#8220;sauce&amp;#8221;, but it was an important step along the way.&lt;/p&gt;

&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/LQPKbzlE_Iw&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 05 Jan 2010 03:57:31 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: The Completionists Guide to Sims 3 iPhone</title>
	<guid>http://chadaustin.me/?p=1495</guid>
	<link>http://chadaustin.me/2010/01/the-completionists-guide-to-sims-3-iphone/</link>
	<description>&lt;p&gt;I play simulation games in two phases: first, I tackle the often-repetitive mechanics, unlocking every option and building up money so that I can creatively decorate my house or farm or whatever.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.ea.com/games/the-sims-3-iphone&quot;&gt;Sims 3 for iPhone&lt;/a&gt; was no different.  Having accomplished nearly everything in the game, I will share a strategy for completing all 73 goals and acquiring the best job: $600 per day at the Pawn Shop.&lt;/p&gt;

&lt;h2&gt;The Objective&lt;/h2&gt;

&lt;p&gt;To open the pawn shop, you must complete the following 73 goals:&lt;/p&gt;

&lt;h3&gt;Goals for all Sims (55)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Try fishing&lt;/li&gt;
&lt;li&gt;Try cooking&lt;/li&gt;
&lt;li&gt;Buy fishing kit&lt;/li&gt;
&lt;li&gt;Buy watering can&lt;/li&gt;
&lt;li&gt;Buy repair kit&lt;/li&gt;
&lt;li&gt;Buy a stove&lt;/li&gt;
&lt;li&gt;Buy a bath&lt;/li&gt;
&lt;li&gt;Gain a skill point at cooking&lt;/li&gt;
&lt;li&gt;Gain a skill point at fishing&lt;/li&gt;
&lt;li&gt;Gain a skill point at repairing&lt;/li&gt;
&lt;li&gt;Meet a new Sim&lt;/li&gt;
&lt;li&gt;Befriend a Sim&lt;/li&gt;
&lt;li&gt;Begin a romantic relationship&lt;/li&gt;
&lt;li&gt;Make an enemy&lt;/li&gt;
&lt;li&gt;Make a Sim laugh&lt;/li&gt;
&lt;li&gt;Annoy a Sim&lt;/li&gt;
&lt;li&gt;Insult a Sim&lt;/li&gt;
&lt;li&gt;Creep-out another Sim&lt;/li&gt;
&lt;li&gt;Slap a Sim&lt;/li&gt;
&lt;li&gt;Get a job&lt;/li&gt;
&lt;li&gt;Buy something&lt;/li&gt;
&lt;li&gt;Catch a fish&lt;/li&gt;
&lt;li&gt;Catch a trout&lt;/li&gt;
&lt;li&gt;Catch a salmon&lt;/li&gt;
&lt;li&gt;Catch a catfish&lt;/li&gt;
&lt;li&gt;Repair something&lt;/li&gt;
&lt;li&gt;Discover a new recipe&lt;/li&gt;
&lt;li&gt;Cook something&lt;/li&gt;
&lt;li&gt;Cook grilled cheese&lt;/li&gt;
&lt;li&gt;Cook steak &amp;#038; veggies&lt;/li&gt;
&lt;li&gt;Cook minestrone&lt;/li&gt;
&lt;li&gt;Grow something&lt;/li&gt;
&lt;li&gt;Grow carrots&lt;/li&gt;
&lt;li&gt;Grow corn&lt;/li&gt;
&lt;li&gt;Grow tomato&lt;/li&gt;
&lt;li&gt;Watch TV&lt;/li&gt;
&lt;li&gt;Kick over a Trash Can&lt;/li&gt;
&lt;li&gt;Sleep in another Sim&amp;#8217;s bed&lt;/li&gt;
&lt;li&gt;Use another Sim&amp;#8217;s shower&lt;/li&gt;
&lt;li&gt;Use another Sim&amp;#8217;s toilet&lt;/li&gt;
&lt;li&gt;Get a better couch&lt;/li&gt;
&lt;li&gt;Get a better TV&lt;/li&gt;
&lt;li&gt;Accumulate $1000&lt;/li&gt;
&lt;li&gt;Catch 15 fish&lt;/li&gt;
&lt;li&gt;Harvest 30 crops&lt;/li&gt;
&lt;li&gt;Stay entertained for three days&lt;/li&gt;
&lt;li&gt;Stay fed for three days&lt;/li&gt;
&lt;li&gt;Stay rested for three days&lt;/li&gt;
&lt;li&gt;Stay clean for three days&lt;/li&gt;
&lt;li&gt;Meet all the Sims in town&lt;/li&gt;
&lt;li&gt;Make a Sim jealous of you&lt;/li&gt;
&lt;li&gt;Sleep in three other Sim&amp;#8217;s beds&lt;/li&gt;
&lt;li&gt;WooHoo with someone&lt;/li&gt;
&lt;li&gt;Get a promotion&lt;/li&gt;
&lt;li&gt;Reach the top of the career ladder&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Maniac Personal Goals (4)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use everyone&amp;#8217;s toilet at least once&lt;/li&gt;
&lt;li&gt;Use everyone&amp;#8217;s shower at least once&lt;/li&gt;
&lt;li&gt;Creep out five people&lt;/li&gt;
&lt;li&gt;Watch three people sleeping&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Sleaze Personal Goals (2)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Be romantically involved with three Sims&lt;/li&gt;
&lt;li&gt;WooHoo eight times in one day&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Power Seeker Personal Goals (3)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accumulate $5000&lt;/li&gt;
&lt;li&gt;Own the best house&lt;/li&gt;
&lt;li&gt;Own the best TV, stereo and stove&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Nice Guy Personal Goals (2)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Get married&lt;/li&gt;
&lt;li&gt;Be liked by all the Sims in town&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Jerk Personal Goals (4)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Be disliked by all the Sims in town&lt;/li&gt;
&lt;li&gt;Slap four people&lt;/li&gt;
&lt;li&gt;Insult five people&lt;/li&gt;
&lt;li&gt;Kick over all the trash cans in town&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Jack of All Trades Personal Goals (3)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Achieve the highest fishing skill level&lt;/li&gt;
&lt;li&gt;Achieve the highest repairing skill level&lt;/li&gt;
&lt;li&gt;Achieve the highest cooking skill level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are six Sim classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jack of All Trades&lt;/li&gt;
&lt;li&gt;Nice Guy&lt;/li&gt;
&lt;li&gt;Jerk&lt;/li&gt;
&lt;li&gt;Sleaze&lt;/li&gt;
&lt;li&gt;Power Seeker&lt;/li&gt;
&lt;li&gt;Maniac&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As previously mentioned, you will need to complete every Goal to unlock the Pawn Shop.  Of the 73 total Goals, 55 randomly appear as Wishes, no matter which Sim class you choose, and they&amp;#8217;re generally easy to complete.&lt;/p&gt;

&lt;p&gt;On the other hand, each Sim&amp;#8217;s Personal Goals are relatively difficult.  You&amp;#8217;ll need to create at least six Sims, one of each type.  For the optimal path through the game, you should complete their personal goals from hardest to easiest.  I will give an efficient play sequence below.&lt;/p&gt;

&lt;h2&gt;Play Order&lt;/h2&gt;

&lt;h3&gt;Jack of All Trades&lt;/h3&gt;

&lt;p&gt;Create six Sims, and designate one as your &amp;#8220;main&amp;#8221; Sim.  Your main Sim is the one with which you most identify.&lt;/p&gt;

&lt;p&gt;Your main Sim is a Jack of All Trades (you&amp;#8217;ll later need its Repair skill at the Pawn Shop).  Play him or her first, building up skill levels as rapidly as possible.  Learn to fish, because fishing is the best way to make money.  As you accumulate money, buy as many of the cheapest stereos you can afford, filling your house.  Each time you enter the house to eat or rest, turn them all on.  Eventually, they will start breaking down, allowing you to practice repairing.&lt;/p&gt;

&lt;p&gt;Practicing cooking is easy &amp;#8211; simply buy bread, cheese, and the Grilled Cheese recipe and make it over and over again.&lt;/p&gt;

&lt;p&gt;Once fishing, repairing, and cooking are level 5, save, quit and move to the next Sim.&lt;/p&gt;

&lt;h3&gt;Power Seeker&lt;/h3&gt;

&lt;p&gt;Your second Sim is your Power Seeker.  Fish until you have $5000 and tool around town until you have the option to upgrade your house twice and buy the most expensive TV, stereo, and stove.  Furniture and home upgrades simply take time.  This is a good opportunity to accumulate general Goals.&lt;/p&gt;

&lt;p&gt;At this point, you should have most of the 55 general Goals.&lt;/p&gt;

&lt;h3&gt;The Other Sim Types&lt;/h3&gt;

&lt;p&gt;Sleaze, Nice Guy, Jerk, and Maniac have fairly easy Personal Goals.  The order in which you complete them does not matter.&lt;/p&gt;

&lt;p&gt;At this point, you should have almost all of the Personal Goals.  If not, keep playing &amp;#8212; they&amp;#8217;ll eventually show up.&lt;/p&gt;

&lt;h3&gt;Goal Tips&lt;/h3&gt;

&lt;p&gt;If you need the &amp;#8220;Buy XXX&amp;#8221; goal but you already have XXX, then try selling it.  Eventually the Goal should appear as a Wish.  Lock it in and repurchase the item.&lt;/p&gt;

&lt;p&gt;If you need the &amp;#8220;Gain a skill point at XXX&amp;#8221; goal and you&amp;#8217;re maxed out, switch to a Sim that is not maxed out.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re having trouble Meeting all Sims, double-check all of the houses at different times of the day.  I&amp;#8217;ve noticed Bernie can be hard to find.  Most Sims are sleeping in the middle of the night &amp;#8211; try breaking into their houses, waking them up, and meeting them.&lt;/p&gt;

&lt;p&gt;If you need to befriend a Sim but you&amp;#8217;re already friends with all of the Sims, start a new Sim or insult a Sim until it becomes an enemy, then befriend him or her.&lt;/p&gt;

&lt;p&gt;The best way to annoy, insult, and creep-out other Sims is to find a house with two Sims (e.g. Marcell and Theresa), barge in, and start flirting with one of them.  Both will be creeped out and annoyed, and the flirting will insult the other and make him or her jealous.  If that doesn&amp;#8217;t work, start using their toilet, shower, and fridge.&lt;/p&gt;

&lt;h2&gt;Tips and Tricks&lt;/h2&gt;

&lt;p&gt;Fishing is the best way to make money.  Each tuna sells at QuickMart for $100, and salmon for $65.&lt;/p&gt;

&lt;p&gt;Besides the Pawn Shop, working at the Town Hall is the best.  It&amp;#8217;s easy to get promotions (both Ruth and the Town Hall are nearby) and you just need to be friends with everyone in town.  As Vice President, you can make $300 per day.&lt;/p&gt;

&lt;p&gt;Creating romantic relationships is easy.  It sounds rude, but keep pestering the Sim with Flirt, Tender Embrace, Hot Smooch, and WooHoo.  You should be able marry a Sim within two conversations.&lt;/p&gt;

&lt;p&gt;Too many WooHoos and your Sim will die!  Don&amp;#8217;t overdo it in the bedroom!&lt;/p&gt;

&lt;p&gt;If you get married, give your spouse a phone call and invite him or her over.  Once your spouse arrives, you can invite him or her to move in.&lt;/p&gt;

&lt;p&gt;Since the Town Hall is right by your house, it&amp;#8217;s the best job until the Pawn Shop is open.&lt;/p&gt;

&lt;h2&gt;The Sims&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nina&lt;/li&gt;
&lt;li&gt;Ruth&lt;/li&gt;
&lt;li&gt;Johnny&lt;/li&gt;
&lt;li&gt;Kia&lt;/li&gt;
&lt;li&gt;Jake&lt;/li&gt;
&lt;li&gt;Maggie&lt;/li&gt;
&lt;li&gt;Jack&lt;/li&gt;
&lt;li&gt;Jill&lt;/li&gt;
&lt;li&gt;Walter&lt;/li&gt;
&lt;li&gt;Luke&lt;/li&gt;
&lt;li&gt;Bernie&lt;/li&gt;
&lt;li&gt;Marcell&lt;/li&gt;
&lt;li&gt;Theresa&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Jobs&lt;/h2&gt;

&lt;h3&gt;Town Hall (boss: Ruth)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Campaign Intern ($100/day) M-F 8:30-18:00&lt;/li&gt;
&lt;li&gt;City Council Member ($150/day) M-F 8:30-18:00&lt;/li&gt;
&lt;li&gt;Local Representative ($200/day) M-F 9:00-18:00&lt;/li&gt;
&lt;li&gt;Mayor ($250/day) M-F 10:00-18:00&lt;/li&gt;
&lt;li&gt;Vice President ($300/day) M-F 10:00-17:00&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Corsican Bistro (boss: Marcell)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kitchen Scullion ($100/day) M-F 10:30-18:30&lt;/li&gt;
&lt;li&gt;Ingredient Taster ($150/day) M-F 10:30-18:30&lt;/li&gt;
&lt;li&gt;Line Chef ($200/day) Tue-Sat 11:00-17:00&lt;/li&gt;
&lt;li&gt;Sous-Chef ($250/day) Tue-Sat 11:00-17:00&lt;/li&gt;
&lt;li&gt;Chef de Cuisine ($300/day) Tue-Fri 11:00-17:00&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Laboratory (boss: Kia)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Test Subject ($100/day) M-F 9:00-16:00&lt;/li&gt;
&lt;li&gt;Lab Tech ($150/day) M-F 09:00-16:00&lt;/li&gt;
&lt;li&gt;Fertilizer Analyst ($200/day) M-F 09:00-16:00&lt;/li&gt;
&lt;li&gt;Carnivorous Plant Tender ($250/day) M-F 09:00-16:00&lt;/li&gt;
&lt;li&gt;Genetic Resequencer ($300/day) M-F 10:00-16:00&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Quickmart (boss: Bernie)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Filing Clerk ($100/day) M-F 08:30-18:30&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s not worth getting promotions at Quickmart.  Bernie is a dick and you have to work there FOREVER before he&amp;#8217;ll promote you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Pawn Shop (boss: Nina)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Con Artist ($300/day) M-F 16:30-23:55&lt;/li&gt;
&lt;li&gt;Safecracker ($400/day) M-F 16:30-23:55&lt;/li&gt;
&lt;li&gt;Cat Burglar ($500/day) M-F 17:00-23:55&lt;/li&gt;
&lt;li&gt;Master Thief ($600/day) M-F 17:00-23:00&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;In the End&lt;/h2&gt;

&lt;p&gt;With the information given above, you should have no problem achieving 73 goals and as much money as you need to decorate your dream home.&lt;/p&gt;

&lt;p&gt;If you get stuck at any point, feel free to leave a comment on this page and I&amp;#8217;ll update the document.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/3jQmia_I1bg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 05 Jan 2010 03:56:25 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: Avoid Manual Initialization</title>
	<guid>http://chadaustin.me/?p=1487</guid>
	<link>http://chadaustin.me/2010/01/avoid-manual-initialization/</link>
	<description>&lt;p&gt;Too many software libraries require that you manually initialize them before use.  As illustration:&lt;/p&gt;

&lt;pre&gt;
library.initialize()
window = library.createLibraryObject()
&lt;/pre&gt;

&lt;p&gt;Why require your users to remember initialization busywork?  createLibraryObject should initialize the library, refcounting the initialization if necessary.&lt;/p&gt;

&lt;p&gt;The primary benefit is cognitive.  If a library requires initialization, its objects and functions have an additional, externally-visible behavior: &amp;#8220;If not initialized, return error.&amp;#8221;&lt;/p&gt;

&lt;p&gt;If the library&amp;#8217;s internal state is managed implicitly, it does not leak out of the API.  createLibraryObject should lazily initialize the library on object construction.  Optionally, on object destruction, it can deinitialize the library.&lt;/p&gt;

&lt;p&gt;A secondary benefit of lazy initialization is performance: interactive desktop applications rarely need immediate access to all of its subsystems.  By deferring as much initialization as possible, application startup time is reduced.&lt;/p&gt;

&lt;p&gt;[This post is a test of my new host: &lt;a href=&quot;http://prgmr.com/xen/&quot;&gt;prgmr.com&lt;/a&gt;]&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/8W6-l9uG03c&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Fri, 01 Jan 2010 07:20:39 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Verge Files Directory</title>
	<guid>http://www.egometry.com/?p=934</guid>
	<link>http://www.egometry.com/gruedorf/verge-files-directory/</link>
	<description>&lt;p&gt;If all went well, this will only show up on my gruedorf feed and not on the main site rss feed.&lt;/p&gt;
&lt;p&gt;Yesterday, I got the file directory view completed for beta.verge-rpg.com.  See it at &lt;a href=&quot;http://beta.verge-rpg.com/downloads/directory/&quot;&gt;http://beta.verge-rpg.com/downloads/directory/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next up will be the file redirects!  Whee.&lt;/p&gt;
&lt;p&gt;Hey Kildorf, where&amp;#8217;s your post?&lt;/p&gt;</description>
	<pubDate>Wed, 30 Dec 2009 08:53:06 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Gruedorf: Sandbox Sitta</title>
	<guid>http://www.egometry.com/?p=931</guid>
	<link>http://www.egometry.com/gruedorf/gruedorf-sandbox-sitta/</link>
	<description>&lt;p&gt;This week I completed the autoschema tool that&amp;#8217;s been long overdue to maintain a healthy database state across the four sandboxes used for development.&lt;/p&gt;
&lt;p&gt;I also cleaned up layout errors and corrected a bug in screenshot uploading.  Also improved the search result page.&lt;/p&gt;
&lt;p&gt;Three minor files section tasks left: A directory link/listing, build the legacy 301 redirect table, and give the files frontpage some polish.&lt;/p&gt;
&lt;p&gt;Next major task after that: the Gallery Controller.&lt;/p&gt;</description>
	<pubDate>Wed, 30 Dec 2009 06:47:26 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: How to argue the case for webhooks</title>
	<guid>http://blog.webhooks.org/?p=202</guid>
	<link>http://blog.webhooks.org/2009/12/22/how-to-argue-for-webhooks/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Push/callbacks are better than polling.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This should be an easy argument. It&amp;#8217;s not just more efficient, it&amp;#8217;s more real-time. I once heard something like 40% of delicious.com requests returned 304 Not Modified. I imagine similar numbers for other popular sites. The more real-time you try to be with polling, the worse it gets. Don&amp;#8217;t call us, we&amp;#8217;ll call you. It&amp;#8217;s more efficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RPC solutions provide more value than messaging solutions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Although you can argue that RPC can be powered by messaging, and messaging can be used for RPC, the point is that they are different mindsets. RPC is about triggering code that &lt;em&gt;does&lt;/em&gt; something. Messaging is about putting a piece of data in another bucket. When you try to call somebody, you usually don&amp;#8217;t want to get their voicemail, right? This analogy goes even further in that, like voicemail, it must be checked on the other end. Messaging just pushes polling somewhere else. &lt;/p&gt;
&lt;p&gt;More importantly, the focus on triggering code is central to this value proposition. Generative systems are more valuable than sterile systems. When did the web get interesting? When it became about more than just static content, and code was put in the loop to generate dynamic content. The point is that if you prioritize code to receive a message before humans, you open up many more possibilities. &lt;/p&gt;
&lt;p&gt;RPC is about making things happen. Messaging stops short short of that by just moving data around.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP is the defacto RPC protocol.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP is everywhere. There are powerful free servers, clients in every major programming environment, and people know it well. It&amp;#8217;s proven and it just works. HTTTP&amp;#8217;s simple design also allows it to be extremely versatile. It&amp;#8217;s basically the TCP of the application layer.&lt;/p&gt;
&lt;p&gt;However, the best thing is that HTTP &lt;em&gt;is&lt;/em&gt; RPC. This subtle fact has been true ever since CGI was introduced. We&amp;#8217;ve gone through building RPC on top of it with XML-RPC and SOAP, but wisely settled on a form of RPC that&amp;#8217;s just HTTP and is even aligned with HTTP semantics: REST. &lt;/p&gt;
&lt;p&gt;If HTTP is RPC and HTTP is everywhere, it &lt;em&gt;is&lt;/em&gt; our defacto RPC protocol. Especially for web applications that breath HTTP, it almost doesn&amp;#8217;t make sense to think of any kind of inter-application communication that isn&amp;#8217;t HTTP. Turtles all the way down!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP RPC + Indirection = Webhooks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;David Wheeler said, &amp;#8220;All problems in computer science can be solved by another level of indirection.&amp;#8221; Webhooks, and all callbacks, are about taking a procedure call and performing it on a variable function. This is indirection and this is very powerful. This is why Unix pipes work. STDIN and STDOUT are not hardcoded values, they&amp;#8217;re variables that you can control. &lt;/p&gt;
&lt;p&gt;Now imagine if all the web applications you used had extension points that you could effectively hook together with &lt;em&gt;any&lt;/em&gt; other application. Well, that&amp;#8217;s what webhooks are about. &lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/webhooks.wordpress.com/202/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/webhooks.wordpress.com/202/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/webhooks.wordpress.com/202/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/webhooks.wordpress.com/202/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/webhooks.wordpress.com/202/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/webhooks.wordpress.com/202/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/webhooks.wordpress.com/202/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/webhooks.wordpress.com/202/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/webhooks.wordpress.com/202/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/webhooks.wordpress.com/202/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.webhooks.org&amp;amp;blog=5379000&amp;amp;post=202&amp;amp;subd=webhooks&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 22 Dec 2009 23:28:58 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Webhooks finally explained for regular people!</title>
	<guid>http://blog.webhooks.org/?p=198</guid>
	<link>http://blog.webhooks.org/2009/12/16/webhooks-finally-explained-for-regular-people/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Although it&amp;#8217;s not the most compelling story, &lt;a href=&quot;http://blogrium.wordpress.com/2009/12/12/twitter-as-a-stockbroker-with-webhooks/&quot;&gt;this blog post&lt;/a&gt; is a terribly effective analogy. So effective, non-techies can read it and &amp;#8220;get webhooks&amp;#8221; &amp;#8230; in some cases leading them to rally for webhooks as much as I do! The analogy focuses on a non-computer, real-world analogy based on telephone calls. Then it follows up with a more concrete example that helps explain the possibilities:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A concrete example of a story made possible from webhooks that might be a useful scenario for many of you involves Twitter. Let’s say Twitter supported webhook callbacks for when somebody follows you. Right now you get an email, and from there you can decide what to do manually: follow them back, block them, or do nothing. I used to go out of my way to block users that I knew were spam bots, but now there’s so many it’s not worth the time. And of course I also generally follow back people that I actually know. If Twitter would simply call a script of mine whenever somebody followed me passing along the user ID, I could very easily run this logic in a PHP script or a simple App Engine app. Or perhaps I’d use Scriptlets (ahem, which was made exactly for these kinds of web scripts). It would work like this:&lt;/p&gt;
&lt;p&gt;First, use the Twitter API to look up the user from the ID, and grab their name. Then use the Facebook API to check if that name shows up in my list of friends on Facebook. If so, use the Twitter API to follow them back. Otherwise, if they’re following over 1000 users and that number is more than twice the number that’s following them (which is roughly the heuristic I use manually), use the Twitter API to block them. All automatic.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Definitely worth the read, if I do say so myself. It&amp;#8217;s also worth pointing people that want a quick understanding of webhooks. What kind of analogies have you come up with?&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/webhooks.wordpress.com/198/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/webhooks.wordpress.com/198/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/webhooks.wordpress.com/198/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/webhooks.wordpress.com/198/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/webhooks.wordpress.com/198/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/webhooks.wordpress.com/198/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/webhooks.wordpress.com/198/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/webhooks.wordpress.com/198/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/webhooks.wordpress.com/198/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/webhooks.wordpress.com/198/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.webhooks.org&amp;amp;blog=5379000&amp;amp;post=198&amp;amp;subd=webhooks&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Tue, 22 Dec 2009 23:17:46 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Unprecedented State of Busy</title>
	<guid>http://progrium.livejournal.com/235763.html</guid>
	<link>http://progrium.livejournal.com/235763.html</link>
	<description>Both now and in general. 2009 is probably the most notable year I can recall. It must have something to do with how busy I've been. Too busy to write in my LiveJournal, that's for sure. And there's been growth and development on all fronts: intellectual, financial, personal, interpersonal, professional, physical, etc. &lt;br /&gt;&lt;br /&gt;At the same time, there are daily issues to overcome, stress of many projects and upcoming deadlines, and the occasional bout of exhaustion. I still need to pull my finances into better order, get my semi-professional brand out there as an umbrella for all my projects, and figure out at what point will I retire from pure technology. Most of my major projects are so long-term and require a constant stream of smaller projects to support them, I'm not sure I'll know when I've succeeded. &lt;br /&gt;&lt;br /&gt;It may be that what I'll ultimately end up doing is moving where there are more people doing what I really want to do. Living here means I'm completely surrounded by startups and technology, so I can't help but spend cycles thinking about that. It frames my thinking and inspiration.&lt;br /&gt;&lt;br /&gt;We'll see.</description>
	<pubDate>Tue, 15 Dec 2009 06:54:56 +0000</pubDate>
</item>
<item>
	<title>Michael Rooney: Launchpad is now an automatic, magical translation factory!</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-635648295426617392</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/5qUhy_mlPD4/launchpad-is-now-automatic-magical.html</link>
	<description>I've been using Launchpad to host my personal finance application &lt;a href=&quot;https://launchpad.net/wxbanker&quot;&gt;wxBanker&lt;/a&gt; for a few years now. The thing I was hearing most often was that it wasn't localized; people wanted currencies to look the way they should in their country, and the application to be in their language. Let me explain how Launchpad helped me provide translations for my application, and how much of an utterly slothful breeze it has recently become.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_HU7L5oFDSeA/SnKYTL6ff1I/AAAAAAAAAT0/DHLdJZYT5nM/s320/slothful.png&quot; border=&quot;0&quot; alt=&quot;Image courtesy of shirt.woot.com&quot; id=&quot;BLOGGER_PHOTO_ID_5364517561534742354&quot; /&gt;&lt;br /&gt;Normally to handle translations, an application has to wrap strings with &lt;a href=&quot;http://en.wikipedia.org/wiki/Gettext&quot;&gt;gettext&lt;/a&gt;, create a template, find translators and give the template to them, collect translation files back, and integrate them into the project. This is painful and is why many applications aren't localized, and shut out most of the world as a result. One of the amazing features of Launchpad however, happens to be Rosetta, which brings translators TO your translations via a simple web interface, and then makes those translations available to the developer. With Rosetta, translators don't need to understand gettext or translation file formats; they just need to know two languages!&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/SnKLUdixHfI/AAAAAAAAATs/z36K46Y4p3M/s1600-h/ss_rosetta.png&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/SnKLUdixHfI/AAAAAAAAATs/z36K46Y4p3M/s400/ss_rosetta.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364503289795780082&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So that's what a translator sees. Notice how Launchpad even shows how other applications translated the same string. So once you generate a template and upload it, you can assign a translation group to your project such as &quot;Ubuntu Translators&quot; so that your strings will be translated by volunteers on the Ubuntu project; if your project isn't relevant to the Ubuntu project, you can use the more generic Launchpad Translators group. Now all you have to do is wait for some translations, then download them and check it in to your code. Not too bad, right?&lt;br /&gt;&lt;br /&gt;It isn't, but Launchpad has recently made it so much better. They started by adding an option to &lt;a href=&quot;https://help.launchpad.net/Translations/ImportingFromBazaarBranches&quot;&gt;automatically import translation templates&lt;/a&gt; from your project. This means as you are developing, all you have to do is regenerate the template and commit, and new strings will show up for translators in Rosetta and be translated automatically (from the developer's perspective). Then today, &lt;a href=&quot;http://blog.launchpad.net/general/exporting-translations-to-a-bazaar-branch&quot;&gt;they announced the other side of this&lt;/a&gt;, which is automatically committing those translations back into your code on a daily basis. This means that all I have to do is commit templates as I change strings, and Launchpad handles everything else. This is a profound tool for developers.&lt;br /&gt;&lt;br /&gt;What's the next step? Well, from a developer's perspective the translation template is a tool to give to the translators or in this case Launchpad. In the future Launchpad could eliminate this by generating the template itself from the code (this is what developers are doing themselves, after all), so that truly all you have to do after you set up the initial i18n/l10n framework is commit code as normal, and Launchpad magically commits back translations.&lt;br /&gt;&lt;br /&gt;All this work Launchpad is doing gives developers more time to develop while still having localized applications at a very minimal cost. This is continuous translation integration, and boy is it cool!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-635648295426617392?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/5qUhy_mlPD4&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 30 Nov 2009 12:55:44 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Jessy Cowan-Sharp: Deriving Organizational Structures from Evolutionary Algorithms</title>
	<guid>http://blog.quaternio.net/?p=461</guid>
	<link>http://blog.quaternio.net/2009/11/08/deriving-organizational-structures-from-evolutionary-algorithms/</link>
	<description>A couple of weeks ago I had the pleasure of sitting in on an  Organicities design studio at EPFL, focused on &amp;#8220;the digital generation of architecture using biological paradigms.&amp;#8221; It was an exploration of the potential these paradigms might hold for generating effective public, corporate, and community spaces in urban environments.  
Compared to [...]</description>
	<pubDate>Sun, 22 Nov 2009 07:55:02 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: PostGIS Beginner Notes</title>
	<guid>http://blog.quaternio.net/?p=308</guid>
	<link>http://blog.quaternio.net/2009/03/10/postgis-beginner-notes/</link>
	<description>&lt;p&gt;these are basically my notes as a total n00b coming to postgres and postgis from previous experience with mysql. hopefully, they will be useful to others as well in finding their feet. i am using ubuntu, but except for the package names below these instructions should be rather generic for non-windozz systems. &lt;/p&gt;
&lt;p&gt;first thing&amp;#8217;s is first.&lt;/p&gt;
&lt;p&gt;1. install postgres (&lt;em&gt;sudo apt-get install postgresql&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;2. install postgis libraries and postgres postgis support (&lt;em&gt;sudo apt-get install postgis&lt;/em&gt; &lt;em&gt;postgresql-8.3-postgis&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;the approach to postgis is a little different than something like mysql, which many people (like me) are used to. the default postgres user is called postgres (usually) and this is the default superuser. the first time you connect to the postgres manager, you need to su to the postgres user. it will connect to he default database (also named postgres). in general, if you are connecting as user x, and you do not specify a database name it will default to a database of the same name as the current user.&lt;/p&gt;
&lt;p&gt;another subtle difference is that postgres has several distinct commands which you can run from the command line, which arent necessarily obvious. where mysql uses mysqladmin &amp;lt;some command&amp;gt;, postgres just uses separate commands without a common prefix- eg. &lt;em&gt;createdb&lt;/em&gt; (create a database, assuming the user you connect as has sufficient privileges), &lt;em&gt;createuser&lt;/em&gt;, etc. i find this a little weird since in some cases it&amp;#8217;s not really obvious that, for example, createuser has anything to do with postgis.&lt;/p&gt;
&lt;p&gt;3. you might want to &lt;a href=&quot;http://www.postgresql.org/docs/8.3/interactive/database-roles.html&quot;&gt;create a user&lt;/a&gt; with the same username as your regular account username to simplify interacting with postgres. to do this you can either connect to postgres and do this from within the DBMS, or you can use the createuser postgres command from the command line:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ &lt;span&gt;sudo&lt;/span&gt; &lt;span&gt;-u&lt;/span&gt; postgres createuser &lt;span&gt;-s&lt;/span&gt; new_superuser&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or better yet:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ &lt;span&gt;sudo&lt;/span&gt; &lt;span&gt;-u&lt;/span&gt; postgres createuser &lt;span&gt;-s&lt;/span&gt; &lt;span&gt;$USER&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;where $USER is the environment variable that set on most unix style machines that will expand to your username. some people recommend for maximum convenience to also create a database with the same name, to enable connecting to postgres without specifying a database explicitly.&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ createdb &lt;span&gt;$USER&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;so now we&amp;#8217;re set up, and you can connec to postgres by just typing&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ psql&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;in general to connect as an arbitrary user to an arbitrary database (for which you have permissions of course):&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ psql &lt;span&gt;-U&lt;/span&gt; username &lt;span&gt;-d&lt;/span&gt; dbname&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you&amp;#8217;re logged in, these commands will come in handy.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; \du lists existing roles (users)&lt;/li&gt;
&lt;li&gt;\l list all databases&lt;/li&gt;
&lt;li&gt;\d tablename (of current database- like &amp;#8216;describe&amp;#8217; in mysql)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;each database that will use postgis has to explicitly enable the postgis functions and datatypes. yes&amp;#8211; even though postgis &lt;em&gt;support&lt;/em&gt; has been enabled through the packages you installed, you still have to manually enable the specific functions and data types for each database that will use them. there is a standard procedure for doing this. standard enough, in fact, that you can simplify the process by using postgres&amp;#8217; notion of database &lt;a href=&quot;http://www.postgresql.org/docs/8.1/static/manage-ag-templatedbs.html&quot;&gt;templates&lt;/a&gt;. think of it like creating templates in an office program&amp;#8211; like a template for an invoice, or a newsletter. even the default new database is an instantiation of a template: the basic or raw template, called &lt;em&gt;template1&lt;/em&gt;. as you can see from the instructions below, a template database is not anything different or special from a regular database.&lt;/p&gt;
&lt;p&gt;to create a spatially enabled template, do the following (ref: clear and simple instructions from this blog &lt;a href=&quot;http://www.paolocorti.net/2008/01/30/installing-postgis-on-ubuntu/&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ &lt;span&gt;sudo&lt;/span&gt; &lt;span&gt;su&lt;/span&gt; postgres &lt;span&gt;#optional, if your current user is not a superuser&lt;/span&gt;
$ createdb postgistemplate
$ createlang plpgsql postgistemplate
$ psql &lt;span&gt;-d&lt;/span&gt; postgistemplate &lt;span&gt;-f&lt;/span&gt; &lt;span&gt;/&lt;/span&gt;usr&lt;span&gt;/&lt;/span&gt;share&lt;span&gt;/&lt;/span&gt;postgresql-&lt;span&gt;8.2&lt;/span&gt;-postgis&lt;span&gt;/&lt;/span&gt;lwpostgis.sql
$ psql &lt;span&gt;-d&lt;/span&gt; postgistemplate &lt;span&gt;-f&lt;/span&gt; &lt;span&gt;/&lt;/span&gt;usr&lt;span&gt;/&lt;/span&gt;share&lt;span&gt;/&lt;/span&gt;postgresql-&lt;span&gt;8.2&lt;/span&gt;-postgis&lt;span&gt;/&lt;/span&gt;spatial_ref_sys.sql&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;we then have to make sure the correct users have permissions on the template database (important or they wont be able to use it!), optionally create a &lt;a href=&quot;http://www.postgresql.org/docs/8.3/interactive/ddl-schemas.html&quot;&gt;schema&lt;/a&gt;, and then test it!&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ psql &lt;span&gt;-d&lt;/span&gt; postgistemplate&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;plsql&quot;&gt;# &lt;span&gt;ALTER&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; geometry_columns OWNER &lt;span&gt;TO&lt;/span&gt; youruser&lt;span&gt;;&lt;/span&gt;
# &lt;span&gt;ALTER&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; spatial_ref_sys OWNER &lt;span&gt;TO&lt;/span&gt; youruser&lt;span&gt;;&lt;/span&gt;
# &lt;span&gt;CREATE&lt;/span&gt; SCHEMA gis_schema AUTHORIZATION gis&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;now to create a spatially enabled database (note: this can be &lt;a href=&quot;http://www.postgresql.org/docs/8.3/interactive/tutorial-createdb.html&quot;&gt;done&lt;/a&gt; from inside or outside psql):&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;plsql&quot;&gt;# &lt;span&gt;CREATE&lt;/span&gt; DATABASE gis_test TEMPLATE &lt;span&gt;=&lt;/span&gt; postgistemplate&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;finally, make sure all is good by defining a table for the new database. here&amp;#8217;s a simple example which defines a table that maps to the &lt;a href=&quot;http://www.gpsinformation.org/dale/nmea.htm&quot;&gt;NMEA gps sentence&lt;/a&gt; &lt;a href=&quot;http://www.gpsinformation.org/dale/nmea.htm#GGA&quot;&gt;GPGGA.&lt;/a&gt; put these commands in a file, or enter them in on the psql command line:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;plsql&quot;&gt;&lt;span&gt;CREATE&lt;/span&gt; &lt;span&gt;TABLE&lt;/span&gt; gpgga &lt;span&gt;&amp;#40;&lt;/span&gt;
       pk serial PRIMARY KEY&lt;span&gt;,&lt;/span&gt;
       utc &lt;span&gt;TIME&lt;/span&gt; &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       gps_fix int &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       sats_in_view int &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       horiz_error &lt;span&gt;FLOAT&lt;/span&gt; &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       alt_asl &lt;span&gt;FLOAT&lt;/span&gt; &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       height_above_WGS84 &lt;span&gt;FLOAT&lt;/span&gt; &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
       DGPS_ref_id int &lt;span&gt;NOT&lt;/span&gt; &lt;span&gt;NULL&lt;/span&gt;
&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;SELECT&lt;/span&gt; AddGeometryColumn&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;'gis_schema'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'gpgga'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'latlong'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;4326&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;'POINT'&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;2&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that you &lt;a href=&quot;http://postgis.refractions.net/documentation/manual-1.3/ch04.html#id2742764&quot;&gt;create the table&lt;/a&gt; with all its non-spatial columns first, and then add the POINT (or other spatial) column. The arguments to the &lt;em&gt;AddGeometryColumn&lt;/em&gt; are, respectively (schema, table_name, column_name, SRID or spatial reference id, data_type, dimensions). the SRID is required by open GIS, and is actually a foreign key into the &lt;tt class=&quot;varname&quot;&gt;SPATIAL_REF_SYS&lt;/tt&gt; table. it tells the table what the reference system or projection of the data is. you can look these up depending on your data type.&lt;/p&gt;
&lt;p&gt;To read this in from the command line is pretty standard:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ psql &lt;span&gt;-d&lt;/span&gt; gis_test &lt;span&gt;&amp;lt;&lt;/span&gt; table_definition.sql&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;upon execution, you will likely see output like the following:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;$ psql &lt;span&gt;-d&lt;/span&gt; gis_test &lt;span&gt;&amp;lt;&lt;/span&gt; table_definition.sql
NOTICE:  CREATE TABLE will create implicit sequence &lt;span&gt;&amp;quot;gpgga_pk_seq&amp;quot;&lt;/span&gt; &lt;span&gt;for&lt;/span&gt; serial column &lt;span&gt;&amp;quot;gpgga.pk&amp;quot;&lt;/span&gt;
NOTICE:  CREATE TABLE &lt;span&gt;/&lt;/span&gt; PRIMARY KEY will create implicit index &lt;span&gt;&amp;quot;gpgga_pkey&amp;quot;&lt;/span&gt; &lt;span&gt;for&lt;/span&gt; table &lt;span&gt;&amp;quot;gpgga&amp;quot;&lt;/span&gt;
CREATE TABLE
                addgeometrycolumn
&lt;span&gt;--------------------------------------------------&lt;/span&gt;
 public.gpgga.latlong SRID:&lt;span&gt;4326&lt;/span&gt; TYPE:POINT DIMS:&lt;span&gt;2&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt; row&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Congrats! Coming soon&amp;#8211; parsing your nmea files.&lt;/p&gt;</description>
	<pubDate>Sun, 22 Nov 2009 04:58:06 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: NASA Image of the Day as Gnome background</title>
	<guid>http://blog.quaternio.net/?p=339</guid>
	<link>http://blog.quaternio.net/2009/04/13/nasa-image-of-the-day-as-gnome-background/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.nasa.gov/images/content/327037main_soyuz_full.JPG&quot;&gt;&lt;img class=&quot;alignright&quot; title=&quot;soyuz-big&quot; src=&quot;http://www.nasa.gov/images/content/327037main_soyuz_full.JPG&quot; alt=&quot;&quot; width=&quot;200&quot; height=&quot;192&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lately I&amp;#8217;ve really been enjoying the &lt;a href=&quot;http://www.nasa.gov/multimedia/imagegallery/iotd.html&quot;&gt;NASA Image of the Day&lt;/a&gt;, and so tonight I decided to make a quick and dirty script to update my gnome background daily with the new images. I thought of making a nice python script using the elegant &lt;a href=&quot;http://feedparser.org/&quot;&gt;universal feed parser&lt;/a&gt;; something able to handle generic image feeds, but as soon as i realized how differently the different image feeds were implemented, i quickly gave up in favour of a much more terse solution in bash.&lt;/p&gt;
&lt;p&gt;the script below just pulls the rss entry down using wget, and then uses grep to mine out the necessary components of the RSS entry. once it has the image url, it saves that to a directory ~/.backgrounds in your home directory, and then uses gnome&amp;#8217;s gconftool-2 to set the value of the background image. add this to your /etc/cron.daily/ directory and you should be good to go.&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;pre class=&quot;bash&quot;&gt;&lt;span&gt;#!/bin/bash&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;# grabs the nasa image of the day by RSS feed and updates the gnome&lt;/span&gt;
&lt;span&gt;# background. add this to your cron jobs to have this happen daily.&lt;/span&gt;
&lt;span&gt;# eg. in your /etc/cron.daily/ directory, add a one line script that&lt;/span&gt;
&lt;span&gt;# simply executes this script (dont forget to make it executable):&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;# #!/bin/sh&lt;/span&gt;
&lt;span&gt;# exec /path/to/this/file/nasabg&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;# note the nasa image of the day only returns one RSS entry, so we are&lt;/span&gt;
&lt;span&gt;# not concerned with parsing multiple entries.&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;# this is, obviously, a hack, that is likely to break at the slightest&lt;/span&gt;
&lt;span&gt;# change of NASA's RSS implementation. yay standards!                                       &lt;/span&gt;
&amp;nbsp;
&lt;span&gt;rss&lt;/span&gt;=&lt;span&gt;`&lt;/span&gt;&lt;span&gt;wget&lt;/span&gt; &lt;span&gt;-q&lt;/span&gt; &lt;span&gt;-O&lt;/span&gt; - http:&lt;span&gt;//&lt;/span&gt;www.nasa.gov&lt;span&gt;/&lt;/span&gt;rss&lt;span&gt;/&lt;/span&gt;lg_image_of_the_day.rss&lt;span&gt;`&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;img_url&lt;/span&gt;=&lt;span&gt;`&lt;/span&gt;&lt;span&gt;echo&lt;/span&gt; &lt;span&gt;$rss&lt;/span&gt; &lt;span&gt;|&lt;/span&gt; &lt;span&gt;grep&lt;/span&gt; &lt;span&gt;-o&lt;/span&gt; &lt;span&gt;'&amp;lt;enclosure [^&amp;gt;]*&amp;gt;'&lt;/span&gt; &lt;span&gt;|&lt;/span&gt; &lt;span&gt;grep&lt;/span&gt; &lt;span&gt;-o&lt;/span&gt; &lt;span&gt;'http://[^\&amp;quot;]*'&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;img_name&lt;/span&gt;=&lt;span&gt;`&lt;/span&gt;&lt;span&gt;echo&lt;/span&gt; &lt;span&gt;$img_url&lt;/span&gt; &lt;span&gt;|&lt;/span&gt; &lt;span&gt;grep&lt;/span&gt; &lt;span&gt;-o&lt;/span&gt; &lt;span&gt;&amp;#91;&lt;/span&gt;^&lt;span&gt;/&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;\.\&lt;span&gt;w&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;$&lt;span&gt;`&lt;/span&gt;
&amp;nbsp;
&lt;span&gt;mkdir&lt;/span&gt; &lt;span&gt;-p&lt;/span&gt; ~&lt;span&gt;/&lt;/span&gt;.backgrounds
&amp;nbsp;
&lt;span&gt;wget&lt;/span&gt; &lt;span&gt;-q&lt;/span&gt; &lt;span&gt;-O&lt;/span&gt; ~&lt;span&gt;/&lt;/span&gt;.backgrounds&lt;span&gt;/&lt;/span&gt;&lt;span&gt;$img_name&lt;/span&gt; &lt;span&gt;$img_url&lt;/span&gt;
&amp;nbsp;
gconftool-&lt;span&gt;2&lt;/span&gt; &lt;span&gt;-t&lt;/span&gt; string &lt;span&gt;--set&lt;/span&gt; &lt;span&gt;/&lt;/span&gt;desktop&lt;span&gt;/&lt;/span&gt;gnome&lt;span&gt;/&lt;/span&gt;background&lt;span&gt;/&lt;/span&gt;picture_filename ~&lt;span&gt;/&lt;/span&gt;.backgrounds&lt;span&gt;/&lt;/span&gt;&lt;span&gt;$img_name&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From a developer&amp;#8217;s standpoint, I think &lt;a href=&quot;http://www.nasa.gov/rss/index.html&quot;&gt;NASA&amp;#8217;s RSS feeds&lt;/a&gt; are a great step in the right direction. but this is also an example of an area that, by going just a few steps farther, we could expose hundreds of gigabytes of images a day in ways that would allow developers to actually &lt;em&gt;build&lt;/em&gt; on this content, and not just view or scrape it. A rest API where you could query based on mission, image size, instrument, image type, planet, year, etc. would be truly amazing!&lt;/p&gt;</description>
	<pubDate>Sun, 22 Nov 2009 04:57:49 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: Colourizing Python Print Statements</title>
	<guid>http://blog.quaternio.net/?p=380</guid>
	<link>http://blog.quaternio.net/2009/05/18/colourizing-python-print-statements/</link>
	<description>Lately I find myself writing a lot of python scripts that involves a ton of text flying by, and me inventing increasingly creative combinations of obscure symbols to delineate different portions of the output. Luckily, if you&amp;#8217;re not using windows using a sensible operating system, then you probably have an underappreciated tool at your disposal&amp;#8211; [...]</description>
	<pubDate>Sun, 22 Nov 2009 04:57:43 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: JSON Encoding and Decoding with Custom Objects in Python</title>
	<guid>http://blog.quaternio.net/?p=355</guid>
	<link>http://blog.quaternio.net/2009/07/16/json-encoding-and-decoding-with-custom-objects-in-python/</link>
	<description>The JSON module supports encoding (aka serializing) for all the basic built-in python types&amp;#8211; strings, lists, dictionaries, tuples,  etc. but if you have your own user-defined class that you want to store, I found the documentation to be pretty ambiguous. And since I also didnt see any complete examples out there of custom object [...]</description>
	<pubDate>Sun, 22 Nov 2009 04:57:36 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: Ssh-Agent Forwarding</title>
	<guid>http://blog.quaternio.net/?p=434</guid>
	<link>http://blog.quaternio.net/2009/11/04/ssh-agent-forwarding/</link>
	<description>For some reason this seems confusing&amp;#8211; but it isn&amp;#8217;t! That said, I always forget the specifics. Here&amp;#8217;s how you use ssh-agent to do key forwarding to remove machines. 
On your local machine, execute:

eval `ssh-agent`

Note the back ticks around ssh-agent. you need to eval this, not run it!
Now you need to add the identities you want [...]</description>
	<pubDate>Sun, 22 Nov 2009 04:57:28 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: Direct Data</title>
	<guid>http://blog.quaternio.net/?p=433</guid>
	<link>http://blog.quaternio.net/2009/11/15/direct-data/</link>
	<description>It is the end of science. Science as hypothesis is giving way to science as statistically derived by large data sets. We&amp;#8217;re finding in many cases that data mining algorithms applied to loosely specified models leads to better results than finely tuned models derived from theoretical equations [see the unreasonable effectiveness of data (pdf)]. 
It&amp;#8217;s [...]</description>
	<pubDate>Sun, 15 Nov 2009 09:03:07 +0000</pubDate>
</item>
<item>
	<title>Jessy Cowan-Sharp: Cities are Human Settlements</title>
	<guid>http://blog.quaternio.net/?p=448</guid>
	<link>http://blog.quaternio.net/2009/11/05/cities-are-human-settlements/</link>
	<description>My two passions have always been the quantitative study of social dynamics, and community. How can we detect and understand patterns in human social interactions? What does that say about their role in, or relationship to, natural properties of the universe? If we can use observed patterns in human dynamics to reverse engineer properties of [...]</description>
	<pubDate>Fri, 06 Nov 2009 07:57:45 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Please date food</title>
	<guid>http://progrium.livejournal.com/235267.html</guid>
	<link>http://progrium.livejournal.com/235267.html</link>
	<description>At the Dojo, somebody left a note on the fridge:&lt;br /&gt;&lt;br /&gt;&quot;Please date food.&quot;&lt;br /&gt;&lt;br /&gt;Somebody crossed out date and wrote &quot;marry.&quot; &lt;br /&gt;&lt;br /&gt;Later, somebody crossed out marry and wrote, &quot;cheat on.&quot; &lt;br /&gt;&lt;br /&gt;Somebody else wrote along the side &quot;+1 for marrying food.&quot;</description>
	<pubDate>Fri, 06 Nov 2009 04:33:36 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: 9 Reasons Why MinTTY is the Best Terminal on Windows</title>
	<guid>http://chadaustin.me/?p=1473</guid>
	<link>http://chadaustin.me/2009/10/reasons-why-mintty-is-the-best-terminal-on-windows/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/mintty/&quot;&gt;MinTTY&lt;/a&gt; is a fantastic piece of software that smoothes some of the edges of the Windows command line experience.  You should use it and here&amp;#8217;s why:&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;1&quot;&gt;&lt;li&gt;MinTTY comes with Cygwin&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Installing MinTTY is trivial: just select the mintty package in Cygwin&amp;#8217;s setup.exe and point your Cygwin shortcut to &lt;code&gt;C:\cygwin\bin\mintty.exe -&lt;/code&gt;.  The trailing hyphen is important.&lt;/p&gt;

&lt;a href=&quot;http://aegisknight.org/wp-uploads/mintty_setup.png&quot;&gt;&lt;img src=&quot;http://aegisknight.org/wp-uploads/mintty_setup-300x215.png&quot; alt=&quot;MinTTY Setup&quot; title=&quot;MinTTY Setup&quot; width=&quot;300&quot; height=&quot;215&quot; class=&quot;aligncenter size-medium wp-image-1474&quot; /&gt;&lt;/a&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;2&quot;&gt;&lt;li&gt;Sane copy and paste&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;By default, MinTTY copies on select and pastes on right-click, just like Linux.  However, you can make it behave like a typical Windows application and show a context menu upon right-click.&lt;/p&gt;

&lt;a href=&quot;http://aegisknight.org/wp-uploads/mintty_right_click.png&quot;&gt;&lt;img src=&quot;http://aegisknight.org/wp-uploads/mintty_right_click-300x146.png&quot; alt=&quot;MinTTY Context Menu&quot; title=&quot;MinTTY Context Menu&quot; width=&quot;300&quot; height=&quot;146&quot; class=&quot;aligncenter size-medium wp-image-1481&quot; /&gt;&lt;/a&gt;

&lt;p&gt;I won&amp;#8217;t bother explaining how difficult copying and pasting is in standard Windows consoles.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;3&quot;&gt;&lt;li&gt;Resizing&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;MinTTY supports arbitrary window sizes, including maximized.  Enough said.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;4&quot;&gt;&lt;li&gt;Works with less/emacs/ssh&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Because MinTTY is based on PuTTY, it doesn&amp;#8217;t display output strangely when running emacs over ssh, among other examples.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;5&quot;&gt;&lt;li&gt;It&amp;#8217;s &lt;em&gt;FAST&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Anyone who has done command line work on Windows has surely noticed that, when a program spews output to the console, system performance nosedives.  Sometimes, even the mouse cursor skips, making it hard to kill the program responsible.&lt;/p&gt;

&lt;p&gt;MinTTY doesn&amp;#8217;t have this problem &amp;#8212; it uses minimal CPU, even under heavy load.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;6&quot;&gt;&lt;li&gt;Doesn&amp;#8217;t bypass RSI Guard&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Five years ago, I was diagnosed with repetitive stress injuries from programming.  To make matters worse, I get obsessive when I work, and nothing can pull me away from the keyboard.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.rsiguard.com/&quot;&gt;RSI Guard&lt;/a&gt; keeps my wrists and elbows pain-free by enforcing short, periodic breaks.  However&amp;#8230;  years of exposure to RSI Guard has caused me to discover its holes.  For example, native console windows bypass RSI Guard&amp;#8217;s protection, so when RSI Guard blocked keyboard and mouse input, I would quickly switch to typing in a console window and continue to work.  Because MinTTY is a standard Windows application, it closes this backdoor.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;7&quot;&gt;&lt;li&gt;Closes even when programs are backgrounded&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Open a fresh Cygwin and type &lt;code&gt;notepad &amp;amp;&lt;/code&gt; followed by &lt;code&gt;exit&lt;/code&gt;.  The Cygwin console sticks open until you close Notepad.&lt;/p&gt;

&lt;p&gt;In MinTTY, you can always close the window, no matter how many background processes you&amp;#8217;ve started.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;8&quot;&gt;&lt;li&gt;Alt-F2 opens a new terminal window&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;Pure convenience: Alt-F2 opens a new terminal.  No need to reach for the mouse.&lt;/p&gt;

&lt;ol class=&quot;boldbullets&quot; start=&quot;9&quot;&gt;&lt;li&gt;Shift-PageUp and Shift-PageDown!&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;For rapidly paging through previous lines of output, you can press Shift-PageUp and Shift-PageDown, just like the Linux console.  Another huge convenience.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/4KpZNox6Axw&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 20 Oct 2009 08:33:42 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Page One</title>
	<guid>http://progrium.livejournal.com/235194.html</guid>
	<link>http://progrium.livejournal.com/235194.html</link>
	<description>Hacker Dojo == Hacker Heaven&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/progrium/4017351989/&quot; title=&quot;Dojo on front of Mercury News by progrium, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2630/4017351989_c068b32395.jpg&quot; width=&quot;375&quot; height=&quot;500&quot; alt=&quot;Dojo on front of Mercury News&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also, the city of Mountain View sent us their congratulations. They say the Major wants to meet us.</description>
	<pubDate>Sat, 17 Oct 2009 00:21:57 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Combat Tanks</title>
	<guid>http://progrium.livejournal.com/234978.html</guid>
	<link>http://progrium.livejournal.com/234978.html</link>
	<description>I'm bringing back the game developer within. I will now develop a series of awesome, simple, but increasingly scoped networked multiplayer games in Flash using Flixel. First on the list is Combat Tanks. &lt;a href=&quot;http://combat-tanks.com&quot;&gt;Play the alpha preview!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mostly developed in the 3 days of &lt;a href=&quot;http://tigjam.com&quot;&gt;TIGJam&lt;/a&gt;, it's a remake of a favorite Windows 3.1 game. There are still bugs and major features missing, but it will be awesome and it will take the Internet by storm. &lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/progrium/4003230235/&quot; title=&quot;Combat Tanks by progrium, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2596/4003230235_ba3181fbe5.jpg&quot; width=&quot;500&quot; height=&quot;360&quot; alt=&quot;Combat Tanks&quot; /&gt;&lt;/a&gt;</description>
	<pubDate>Fri, 16 Oct 2009 09:45:41 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Johnny 5</title>
	<guid>http://progrium.livejournal.com/234466.html</guid>
	<link>http://progrium.livejournal.com/234466.html</link>
	<description>&lt;center&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3466/3978751381_298a6e74b7.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href=&quot;http://johnnysegway.ytmnd.com/&quot;&gt;See it in action.&lt;/a&gt;&lt;/strong&gt;&lt;/center&gt;</description>
	<pubDate>Sun, 04 Oct 2009 09:02:48 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Fatty</title>
	<guid>http://www.egometry.com/?p=924</guid>
	<link>http://www.egometry.com/magic-slang/fatty/</link>
	<description>&lt;p&gt;Fatty. (Noun)&lt;/p&gt;
&lt;p&gt;A big creature. Fatness starts around 4/4 and never ends from there.&lt;/p&gt;
&lt;p&gt;&amp;#8220;I love the fatties.&amp;#8221;&lt;/p&gt;</description>
	<pubDate>Thu, 24 Sep 2009 09:21:56 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Files, and the editing thereof.</title>
	<guid>http://www.egometry.com/?p=905</guid>
	<link>http://www.egometry.com/gruedorf/files-and-the-editing-thereof/</link>
	<description>&lt;div&gt;&lt;a href=&quot;http://www.egometry.com/i/2009/09/2009-09-22.jpg&quot; rel=&quot;lightbox[pics905]&quot; title=&quot;A screenshot of a control panel page.  Woo?&quot;&gt;&lt;img src=&quot;http://www.egometry.com/i/2009/09/2009-09-22.thumbnail.jpg&quot; alt=&quot;2009-09-22&quot; width=&quot;169&quot; height=&quot;200&quot; class=&quot;attachment wp-att-906 alignleft&quot; /&gt;&lt;/a&gt;
&lt;p class=&quot;wp-caption-text&quot;&gt;The most pedestrian screenshot ever.  To what depths has this once-mighty work-journal fallen?&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;My &lt;a href=&quot;http://www.johnweng.com/gruedorf/&quot;&gt;gruedorf&lt;/a&gt; showings are shameful of late, and so are all of yours.  The only one holding the line at this moment is Ustor.  Perhaps this should be called &amp;#8220;UstorUstor&amp;#8221;.  Or &amp;#8220;TorUs&amp;#8221;.&lt;/p&gt;
&lt;p&gt;At any rate, my small token to personal projects this week is the file management section&amp;#8217;s edit page.  Woo, now you can edit your files once they exist.  Necessary, and very quotidian to a web developer.&lt;/p&gt;
&lt;p&gt;Up next on this mystical journey is the upload section&amp;#8217;s frontpage, featuring most downloaded recently, newest files, and staff picks (aka, &lt;a href=&quot;http://verge-rpg.com/demoalarm/&quot;&gt;Demo Alarms&lt;/a&gt;).  After that, we&amp;#8217;re a docs section from release.  At this point, I think I should screen-scrape my old site&amp;#8217;s documentation and import all of that into a wiki.  Anyone have objections?&lt;/p&gt;</description>
	<pubDate>Tue, 22 Sep 2009 07:27:31 +0000</pubDate>
</item>
<item>
	<title>Michael Rooney: wxBanker 0.6 preview available, now with recurring transactions!</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-4135404130931013098</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/F1K-WmSUlgo/wxbanker-06-preview-available-now-with.html</link>
	<description>I've just released wxBanker 0.5.9 in &lt;a href=&quot;https://launchpad.net/~mrooney/+archive/wxbanker-testing&quot;&gt;the wxbanker-testing PPA&lt;/a&gt;, which is a preview release for 0.6. If you aren't familiar with wxBanker already, it is a cross-platform, lightweight personal finance application, and you can find more info at &lt;a href=&quot;https://launchpad.net/wxbanker&quot;&gt;https://launchpad.net/wxbanker&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;While there are &lt;a href=&quot;https://launchpad.net/wxbanker/+milestone/0.6&quot;&gt;many improvements and fixes&lt;/a&gt; in 0.6, the main feature is recurring transactions, allowing you to automate repetitive transactions. They are functional in 0.5.9 with one caveat and the purpose of this preview release: there's no way (besides sqlitebrowser :) to modify existing recurring transactions. As such I'd love to get feedback on your impressions of recurring transactions, ideas on a nice configuration UI for them, and of course general feedback. With this I can implement the configuration UI and release 0.6.&lt;br /&gt;&lt;br /&gt;Here's an example of a simple quarterly transaction:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_HU7L5oFDSeA/Srcm3zebZLI/AAAAAAAAAX4/Ui32D2TBg88/s1600-h/wxbanker-recurring-simple.png&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_HU7L5oFDSeA/Srcm3zebZLI/AAAAAAAAAX4/Ui32D2TBg88/s400/wxbanker-recurring-simple.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5383814619697210546&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and here is a more complex one, with specific days chosen, as well as the transaction being a transfer from another account:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_HU7L5oFDSeA/Srcl91BFwWI/AAAAAAAAAXw/ANaBFZ7W9PI/s1600-h/wxbanker-recurring.png&quot;&gt;&lt;img src=&quot;http://2.bp.blogspot.com/_HU7L5oFDSeA/Srcl91BFwWI/AAAAAAAAAXw/ANaBFZ7W9PI/s400/wxbanker-recurring.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5383813623678615906&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When you start up wxBanker and there is a recurring transaction due, you will see something like:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/SrcqtaCE55I/AAAAAAAAAYI/FsSU097v09M/s1600-h/Screenshot-wxBanker-1.png&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/SrcqtaCE55I/AAAAAAAAAYI/FsSU097v09M/s400/Screenshot-wxBanker-1.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5383818839115229074&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I didn't reinvent recurrence rules but instead (luckily) found the dateutil module for python which includes rrule, an &quot;implementation of the recurrence rules documented in the &lt;a href=&quot;http://www.ietf.org/rfc/rfc2445.txt&quot;&gt;iCalendar RFC&lt;/a&gt;&quot;, so it should behave quite well.&lt;br /&gt;&lt;br /&gt;As far as the needed configuration UI goes, there are a couple ideas that I've had so far. Below is the current top-left portion of the UI, for reference:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/Srco-UL023I/AAAAAAAAAYA/MvdtcqO5lwc/s1600-h/wxbanker-topleft.png&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_HU7L5oFDSeA/Srco-UL023I/AAAAAAAAAYA/MvdtcqO5lwc/s400/wxbanker-topleft.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5383816930580028274&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One idea was to have a third &quot;Recurring Transactions&quot; tab after the &quot;Transactions&quot; and &quot;Summary&quot; tabs, which appears if and only if recurring transactions exist. This would provide a list of recurring transactions and allow editing them via the same UI used for creation, as well as changing the account or removing them altogether. A second idea is to add another button next to the Add/Rename/Remove account buttons in the upper-left, for account configuration (this will be necessary for future features anyway), and allow modifying recurring transactions for that account there.&lt;br /&gt;&lt;br /&gt;Another perhaps complementary way would be to provide a right-click action on existing transactions which were recurred, for editing. I'd also like to implement functionality similar to Google Calendar where editing a value on an existing transaction caused by a recurring transaction will ask you if you want to apply that change to just this transaction, all existing, or all future.&lt;br /&gt;&lt;br /&gt;If you have ideas, please feel free to leave comments here or drop by #wxbanker on irc.freenode.net any time this week after 10AM PDT, to have a more interactive chat about them. &lt;br /&gt;&lt;br /&gt;Please do let me know what you think from either just the screenshots here or actually playing around with the application!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-4135404130931013098?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/F1K-WmSUlgo&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 21 Sep 2009 01:29:01 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Chuck Rector: I don't like IDEs anymore.</title>
	<guid>tag:blogger.com,1999:blog-3327768276254607141.post-4880304400563548920</guid>
	<link>http://choosetheforce.blogspot.com/2009/09/i-dont-like-ides-anymore.html</link>
	<description>&lt;p&gt;I spent seven or eight years using Eclipse as my primary development environment. I never really questioned it until I switched jobs and saw some of the mavericks using Emacs, Vim, and command shells. I decided to become fluent in Emacs, and have been using it daily for the past couple years now.&lt;/p&gt;

&lt;p&gt;Thinking about it now, it's most interesting to me that I never looked back and said &quot;Gee, life was so much better back in the IDE days.&quot; Hell no. In my mind, Eclipse is a sofa and Emacs is a treadmill. I have a goal, I'm on task, I know what I want to do and I do it.&lt;/p&gt;

&lt;p&gt;My big fancy IDE mentality was all about victimization, blame, and laziness. &quot;Big fancy IDE crash! No my fault.&quot; &quot;Big fancy IDE get confoozed and lie! I do bad thing, oops!!&quot; &quot;Big fancy IDE slow on big project, me play while wait!&quot; &quot;Big fancy IDE big and fancy! It break, I no no why. I confoozed.&quot;

&lt;p&gt;My Emacs mentality is scientific, hands-on, and active. I can count on one hand the number of times GNU Emacs has ever crashed on me. Emacs doesn't happily chew on gigs of files in the background, caching data that I could give two shits about. When I want something, I ask for it explicitly. My UX isn't impacted by background tasks that are attempting to read my mind, because there's only ever one task: the one I'm doing right now.&lt;/p&gt;

&lt;p&gt;Being born into royalty and pampered for so many years feels nice, but over time it just turned me into a fat lazy slob with a soft mushy brain. It trained me to surrender my critical thinking skills. Emacs and command shells forced me to learn how to tie my own shoes and make my own meals. I enjoy the independence and self-reliance.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I tried Komodo today, at the recommendation of a coworker, and it has a nice polished look, but it reminds me too much of Eclipse. The editor looks as though it is based on Scintilla, which is cool. I am a fan of SciTE. The background churn as it attempts to cache everything under the sun makes the UI sluggish and choppy, which blows my mind. I'm running a quad core with buttloads of memory on an SSD. Come on, man. Seriously?&lt;/p&gt;

&lt;p&gt;These are only my first impressions, so I'm going to keep at it for at least a couple weeks to get a real feel for it. Maybe I can right some wrongs, but I get the sense it's never going to feel as light and razor sharp as Emacs.&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3327768276254607141-4880304400563548920?l=choosetheforce.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;/p&gt;</description>
	<pubDate>Sun, 20 Sep 2009 03:41:00 +0000</pubDate>
	<author>noreply@blogger.com (卡车 Chuck)</author>
</item>
<item>
	<title>Jeff Lindsay: Interview on the uses of webhooks</title>
	<guid>http://blog.webhooks.org/?p=195</guid>
	<link>http://blog.webhooks.org/2009/09/18/interview-on-the-uses-of-webhooks/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;A while back I was &lt;a href=&quot;http://www.nearsoft.com/blog/Introduction-to-Webhooks-and-An-Evangelist.html&quot;&gt;interviewed on the Nearsoft blog&lt;/a&gt; about webhooks. It goes into more details on the whole push, pipes and plugin use cases. Real-time web is a hot topic these days, so I had to mention how the webhooks movement relates to that trend. Here&amp;#8217;s an excerpt about using webhooks for real-time notifications:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Notifications seem to be [a big draw for webhooks] &amp;#8230; as in, tell me when something new has been posted, or when something has changed. But with your code on the receiving end of the notification, you can decide exactly how you get notified. For example, tell me about changes over Twitter, not email. In fact, no, use this other hook script that uses cloud telephony to call my cell phone and use text-to-speech to tell me.&lt;/p&gt;
&lt;p&gt;Real-time notifications, exactly how you want them.&lt;/p&gt;&lt;/blockquote&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/webhooks.wordpress.com/195/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/webhooks.wordpress.com/195/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/webhooks.wordpress.com/195/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/webhooks.wordpress.com/195/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/webhooks.wordpress.com/195/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/webhooks.wordpress.com/195/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/webhooks.wordpress.com/195/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/webhooks.wordpress.com/195/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/webhooks.wordpress.com/195/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/webhooks.wordpress.com/195/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.webhooks.org&amp;amp;blog=5379000&amp;amp;post=195&amp;amp;subd=webhooks&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sat, 19 Sep 2009 00:49:24 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: HookPress brings webhooks to WordPress!</title>
	<guid>http://blog.webhooks.org/?p=191</guid>
	<link>http://blog.webhooks.org/2009/09/18/hookpress-brings-webhooks-to-wordpress/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;So much has been going on in the world of webhooks that it&amp;#8217;s hard to keep up. From &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/wiki/Companies&quot;&gt;PubSubHubbub developments&lt;/a&gt;, to new services supporting webhooks &amp;#8230; to this plugin for WordPress called &lt;a href=&quot;http://wordpress.org/extend/plugins/hookpress/&quot;&gt;HookPress&lt;/a&gt;. HookPress opens the WordPress plugin API over webhooks! It was developed by my new buddy &lt;a href=&quot;http://mitcho.com/&quot;&gt;Mitcho&lt;/a&gt;. He made an excellent &lt;a href=&quot;http://wordpress.tv/2009/09/13/introduction-to-hookpress/&quot;&gt;screencast&lt;/a&gt; to demonstrate the power of HookPress, and the power of the emerging webhooks ecosystem. Check it out:&lt;/p&gt;
&lt;ins&gt;
&lt;div class=&quot;video-player&quot; id=&quot;x-video-0&quot;&gt;
&lt;/div&gt;&lt;/ins&gt;
&lt;br /&gt;&lt;a href=&quot;http://blog.webhooks.org/2009/09/18/hookpress-brings-webhooks-to-wordpress/&quot;&gt;&lt;img width=&quot;160&quot; height=&quot;120&quot; src=&quot;http://cdn.videos.wordpress.com/25KHD2dF/hookpress-webhooks-intro_std.original.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/webhooks.wordpress.com/191/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/webhooks.wordpress.com/191/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/webhooks.wordpress.com/191/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/webhooks.wordpress.com/191/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/webhooks.wordpress.com/191/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/webhooks.wordpress.com/191/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/webhooks.wordpress.com/191/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/webhooks.wordpress.com/191/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/webhooks.wordpress.com/191/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/webhooks.wordpress.com/191/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.webhooks.org&amp;amp;blog=5379000&amp;amp;post=191&amp;amp;subd=webhooks&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sat, 19 Sep 2009 00:40:16 +0000</pubDate>
</item>
<item>
	<title>Joseph Mathes: Maybe this will get me posting again</title>
	<guid>http://joblivious.wordpress.com/?p=615</guid>
	<link>http://joblivious.wordpress.com/2009/09/16/maybe-this-will-get-me-posting-again/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;3k hits a day&amp;#8217;s what this blog struck&lt;br /&gt;
down to none now; it&amp;#8217;s run by a slack schmuck&lt;br /&gt;
so I picked a slick schmuck cure; &lt;br /&gt;
strict limerick structure&lt;br /&gt;
if it works, &lt;a href=&quot;http://joblivious.wordpress.com/2009/03/29/restrictions-fuel-creativity-and-thats-why-stealth-games-were-invented/&quot;&gt;I was right&lt;/a&gt;. Wish me luck!&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/joblivious.wordpress.com/615/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/joblivious.wordpress.com/615/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/joblivious.wordpress.com/615/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/joblivious.wordpress.com/615/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/joblivious.wordpress.com/615/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/joblivious.wordpress.com/615/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/joblivious.wordpress.com/615/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/joblivious.wordpress.com/615/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/joblivious.wordpress.com/615/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/joblivious.wordpress.com/615/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=joblivious.wordpress.com&amp;amp;blog=6486443&amp;amp;post=615&amp;amp;subd=joblivious&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 16 Sep 2009 13:52:23 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: vrpg beta work continues</title>
	<guid>http://www.egometry.com/?p=902</guid>
	<link>http://www.egometry.com/gruedorf/vrpg-beta-work-continues/</link>
	<description>&lt;p&gt;I&amp;#8217;ve mainly been dealing with code concerning the files section.  I&amp;#8217;ve improved the quality of the upload process, corrected the file lineage graph and made strides towards a saner system, have made it so you can comment upon file entries, and made it so anyone can upload screenshots of any file.&lt;/p&gt;
&lt;p&gt;Also I made an schema-application tool to keep track of which .sql files have been applied in what environment.  Trust me, this is useful.&lt;/p&gt;
&lt;p&gt;So where did I go for two months, far, far away from Gruedorf?  I honestly can say I was shocked to crack open this dev folder to find the last svn log from &lt;em&gt;July 10&lt;/em&gt;.  So wherever I went, it didn&amp;#8217;t seem as long as it was. :(&lt;/p&gt;</description>
	<pubDate>Mon, 07 Sep 2009 20:59:13 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: mp3</title>
	<guid>http://blogrium.wordpress.com/?p=71</guid>
	<link>http://blogrium.wordpress.com/2009/08/28/need-icons-for-filetypes-hotlink-from-stdicon-com/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;This is about ten days old, but still worth mentioning. I was working on &lt;a href=&quot;http://www.postbin.org&quot;&gt;PostBin&lt;/a&gt; trying to support file uploads. I realized I really wanted to have icons for the files to help differentiate them from other POST params and make it feel more polished. Of course, this would mean I&amp;#8217;d have to find icons for the popular file/mime types &amp;#8230; and if I were going to do that, I might as well build a service &amp;#8230; but I didn&amp;#8217;t want to build a service. &lt;/p&gt;
&lt;p&gt;I turned to Twitter. In that past, I&amp;#8217;d mentioned wanting something and somebody actually built it (using my tools no less). I figured this was a bit more work than last time, but it couldn&amp;#8217;t be that much more. So I gave it a shot and &lt;a href=&quot;http://twitter.com/progrium/status/3373976979&quot;&gt;tweeted it&lt;/a&gt;. Next thing I know, &lt;a href=&quot;http://blog.paulisageek.com/&quot;&gt;Paul Tarjan&lt;/a&gt; is on it. Some hours later: &lt;a href=&quot;http://stdicon.com&quot;&gt;stdicon.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m credited at the bottom, but really, I just had the idea and came up with the domain. Paul wrote all the code and even collected all the icons (and manually uploaded them to the app). We discussed implementation details over IM, but that was it. Pretty rad! &lt;/p&gt;
&lt;p&gt;The idea is that given a file extension (&amp;#8221;txt&amp;#8221;, &amp;#8220;gif&amp;#8221;, etc) or a mimetype (&amp;#8221;text/plain&amp;#8221;, &amp;#8220;application/zip&amp;#8221;, etc) you can get a resizable icon by putting together a simple URL, like &lt;code&gt;http://www.stdicon.com/mp3?size=16&lt;/code&gt; or from a particular icon set &lt;code&gt;http://www.stdicon.com/neu/html?size=64&lt;/code&gt;. Here are some examples from various sets:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.stdicon.com/nuvola/&quot;&gt;Nuvola set&lt;/a&gt;: &lt;img src=&quot;http://www.stdicon.com/nuvola/text/plain?size=32&quot; alt=&quot;text/plain&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/nuvola/jpg?size=32&quot; alt=&quot;jpg&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/nuvola/application/pdf?size=32&quot; alt=&quot;application/pdf&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/nuvola/mp3?size=32&quot; alt=&quot;mp3&quot; /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.stdicon.com/apache/&quot;&gt;Apache set&lt;/a&gt;: &lt;img src=&quot;http://www.stdicon.com/apache/text/plain?size=32&quot; alt=&quot;text/plain&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/apache/jpg?size=32&quot; alt=&quot;jpg&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/apache/application/pdf?size=32&quot; alt=&quot;application/pdf&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/apache/mp3?size=32&quot; alt=&quot;mp3&quot; /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.stdicon.com/crystal/&quot;&gt;Crystal set&lt;/a&gt;: &lt;img src=&quot;http://www.stdicon.com/crystal/text/plain?size=32&quot; alt=&quot;text/plain&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/crystal/jpg?size=32&quot; alt=&quot;jpg&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/crystal/application/pdf?size=32&quot; alt=&quot;application/pdf&quot; /&gt; &lt;img src=&quot;http://www.stdicon.com/crystal/mp3?size=32&quot; alt=&quot;mp3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s it! &lt;a href=&quot;http://blog.paulisageek.com/2009/08/stdicon.html&quot;&gt;Paul wrote a post about it.&lt;/a&gt; Somebody requested a simple API for just doing the mimetype to file extension conversion, so Paul added it. Strangely, the same day, &lt;a href=&quot;http://www.mimeapi.org/&quot;&gt;MIME API&lt;/a&gt; was released. That&amp;#8217;s fine. Just means stdicon can focus on icons. &lt;/p&gt;
&lt;p&gt;Anyway, I pulled this same stunt just the other day, using Twitter to get more cool infrastructure built, but I&amp;#8217;ll have to write about it later.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/71/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/71/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/71/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/71/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/71/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/71/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/71/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/71/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/71/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/71/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=71&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 28 Aug 2009 21:42:23 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: progrium</title>
	<guid>http://blogrium.wordpress.com/?p=67</guid>
	<link>http://blogrium.wordpress.com/2009/08/26/what-are-webhooks-really-about/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Oh, webhooks. What have you become? Just another buzzword for the rising realtime web trend? I admit, without a spec or obvious definition, it seems to lend itself to such a fate. It&amp;#8217;s kind of like AJAX. Although, those that know the true meaning of AJAX exists mostly in first letter, and know that it is actually a significant and useful pattern, should know the same of webhooks. &lt;/p&gt;
&lt;p&gt;In fact, those that are familiar with the heart of AJAX can even compare webhooks mechanically to AJAX. It&amp;#8217;s like an inverted, backend, server-to-server version. Yeah? Okay, that&amp;#8217;s a stretch. Maybe I won&amp;#8217;t open my SXSW talk with that description. &lt;/p&gt;
&lt;p&gt;Actually, I do want to start my SXSW talk backwards. What I usually leave until the end of &lt;a href=&quot;http://www.slideshare.net/progrium&quot;&gt;my webhooks talks&lt;/a&gt;, and as such tend to skim over for lack of time, I&amp;#8217;m going to make the focus on my next major talk. You see, some people just don&amp;#8217;t get it. I think starting with the mechanism and extrapolating doesn&amp;#8217;t work if people get stuck on the mechanism.  &lt;/p&gt;
&lt;p&gt;I questioned both &lt;a href=&quot;http://dashes.com/anil/2009/07/the-pushbutton-web-realtime-becomes-real.html&quot;&gt;Anil Dash&lt;/a&gt; and &lt;a href=&quot;http://blogmaverick.com/2009/08/25/the-internet-is-about-to-change/&quot;&gt;Mark Cuban&lt;/a&gt;&amp;#8217;s posts about webhooks and &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot;&gt;PubSubHubbub&lt;/a&gt;. It turns out they both do actually get it, they just realize they need to simplify it for people to understand. The same reason PubSubHubbub is focusing on feeds for now as opposed to general HTTP pubsub. &lt;/p&gt;
&lt;p&gt;It&amp;#8217;s not that people are stupid. Or even that we&amp;#8217;re smarter than others. The magic of webhooks is in the emergence of an event-driven programmable web, something that&amp;#8217;s not terribly obvious when looking at what webhooks are in of themselves: callbacks over HTTP. Most people don&amp;#8217;t even see that; they see notifications over HTTP.&lt;/p&gt;
&lt;p&gt;You can compare it to &lt;a href=&quot;http://en.wikipedia.org/wiki/Go_(game)&quot;&gt;Go&lt;/a&gt;. A game you can learn to play so quickly, but can spend a lifetime to master. More importantly, after you learn the rules and do some simple scenarios, you think you get the game&amp;#8230; but as you play more, it becomes something else. What it&amp;#8217;s &amp;#8220;really about&amp;#8221; emerges as you actually experience it. &lt;/p&gt;
&lt;p&gt;It reminds me of some people that say &amp;#8220;Well, you can do that with XMPP; that&amp;#8217;s what you should really use,&amp;#8221; when it turns out they&amp;#8217;ve never really programmed a system with XMPP, and definitely not with webhooks. They have no idea the convenience of webhooks over XMPP, or what that affords. Even for those that believe webhooks sound nice in theory, they&amp;#8217;ll go implement it and come out going, &amp;#8220;Wow, this really is quite cool,&amp;#8221; as &lt;a href=&quot;http://pbworks.com/&quot;&gt;PBworks&lt;/a&gt; CTO said after implementing webhooks in PBworks.&lt;/p&gt;
&lt;p&gt;Anyway, I haven&amp;#8217;t even gotten to answering my question: What are webhooks really about? The real answer is that they&amp;#8217;re about something completely different!&lt;/p&gt;
&lt;p&gt;I was standing next to my long-time colleague Adam Smith (we built &lt;a href=&quot;http://www.youtube.com/watch?v=-cHKFsnnAYw&quot;&gt;AjaxWar&lt;/a&gt; together in 2005, before Comet had a name) as he read Mark Cuban&amp;#8217;s post. After, he remarked, &amp;#8220;Well it&amp;#8217;s good to know you&amp;#8217;re still two steps ahead.&amp;#8221; Yep. ^_^&lt;/p&gt;
&lt;p&gt;You see, the funny thing is that webhooks aren&amp;#8217;t even the ultimate goal. They&amp;#8217;re a means to an end. That&amp;#8217;s what my next talk is about, only I decided against &amp;#8220;Beyond WebHooks&amp;#8221; &amp;#8230; instead I went with &lt;a href=&quot;http://panelpicker.sxsw.com/ideas/view/3233&quot;&gt;&amp;#8220;How WebHooks Will Make Us All Programmers.&amp;#8221;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Have I been pushing an agenda to subvert the masses and make us all programmers? I&amp;#8217;ll admit that&amp;#8217;d be nice, but really I just think it&amp;#8217;s the most interesting outcome of the progression I see going on. Honestly, if explained properly, I think it&amp;#8217;s something we can all get behind. In fact, I explained webhooks to &lt;a href=&quot;http://americanathena.wordpress.com/&quot;&gt;Cheri Renee&lt;/a&gt; at the last &lt;a href=&quot;http://superhappydevhouse.org/&quot;&gt;DevHouse&lt;/a&gt; from this perspective and it actually got her excited. She&amp;#8217;s not even a programmer.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s the angle for my next talk on webhooks. The real big picture. At least for me, that&amp;#8217;s what webhooks are really about. Hopefully I&amp;#8217;ll find some time to get into more details before the talk. Until then, please &lt;a href=&quot;http://panelpicker.sxsw.com/ideas/view/3233&quot;&gt;vote for the proposal&lt;/a&gt; so I can finally make it to SXSW (and give this talk)! &lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/67/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/67/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/67/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/67/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/67/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/67/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/67/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/67/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/67/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/67/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=67&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 26 Aug 2009 07:09:40 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: OpenCL Rocks: Why You Care</title>
	<guid>http://chadaustin.me/?p=1467</guid>
	<link>http://chadaustin.me/2009/08/opencl-rocks-why-you-care/</link>
	<description>&lt;p&gt;Today I attended the &lt;a href=&quot;http://www.hotchips.org/hc21/program/tutorials.htm&quot;&gt;Hot Chips 2009&lt;/a&gt; conference, where I was introduced to OpenCL*.  I&amp;#8217;d never heard of &lt;a href=&quot;http://www.khronos.org/opencl/&quot;&gt;OpenCL&lt;/a&gt; before, but it&amp;#8217;s totally hot and I will tell you why.&lt;/p&gt;

&lt;h2&gt;What is OpenCL?&lt;/h2&gt;

&lt;p&gt;OpenCL (Open Computing Library) is an open and free API that lets your programs efficiently leverage all of the computing power in your computer, including multiple CPU cores, vector computation units, GPUs, Cell coprocessors, DSPs, etc.  OpenCL programs, called kernels, are written in a variant of C and are automatically scheduled across your available hardware.  Your customers don&amp;#8217;t have a GPU but their processor has 2 or 4 cores?  No problem: OpenCL will utilize that spare power.&lt;/p&gt;

&lt;p&gt;In addition, OpenCL specifies 4-, 8-, and 16-wide SIMD vector types, meaning it can easily leverage both the vector computation units on GPUs and extended vector instruction sets on CPUs, such as SSE and AVX.  (Looking forward to Larrabee.)&lt;/p&gt;

&lt;p&gt;With OpenCL, Apple and the Khronos Group are cleanly solving two clear market needs: we have increasing amounts of computational hardware available to us, but each bit of hardware is a bit different, with separate APIs, performance, and instruction sets.  As much as possible, OpenCL unifies the interface to this hardware.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s true that GPUs and CPUs have different performance characteristics, but the same types of programs run efficiently on both: do way more math than memory loads and split your program into large parallel chunks.&lt;/p&gt;

&lt;h2&gt;Where do I get it?&lt;/h2&gt;

&lt;p&gt;The major vendors are starting to provide OpenCL implementations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.apple.com/macosx/technology/&quot;&gt;Apple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nvidia.com/object/cuda_opencl.html&quot;&gt;NVIDIA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amd.com/us/press-releases/Pages/amd-delivers-and-submits-2009aug04.aspx&quot;&gt;AMD/ATI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Intel&amp;#8217;s on the way, I&amp;#8217;m sure.  I expect we&amp;#8217;ll see an OpenCL implementation on Larrabee as well.&lt;/p&gt;

&lt;h2&gt;How do I use it?&lt;/h2&gt;

&lt;p&gt;OpenCL programs are called kernels &amp;#8212; functions that run in parallel across large amounts of data.  You&amp;#8217;re given a lot of freedom: OpenCL uses a variant of the C99 programming language, with only a handful of restrictions.&lt;/p&gt;

&lt;p&gt;If you find that too onerous, you can use OpenCL with native functions you&amp;#8217;ve already written!  Just let it schedule your tasks and manage task dependencies to easily get started running code on multiple cores.&lt;/p&gt;

&lt;p&gt;I won&amp;#8217;t go into the details of the memory model or API; you can look that up on &lt;a href=&quot;http://www.google.com/search?q=&amp;quot;opencl&amp;quot;+tutorial&quot;&gt;Google&lt;/a&gt;.  However, here&amp;#8217;s an example kernel:&lt;/p&gt;

&lt;pre&gt;
kernel void square(
    global float* input,
    global float* output
) {
    int i = get_global_id(0);
    output[i] = input[i] * input[i];
}
&lt;/pre&gt;

&lt;p&gt;It squares a bunch of numbers in an array, storing the results in an output array.  This trivial example will easily consume all of the compute power in your system.  (Defining compute to mean ALU + memory, of course&amp;#8230;)&lt;/p&gt;

&lt;h2&gt;Next Steps&lt;/h2&gt;

&lt;p&gt;I hope that&amp;#8217;s enough information to get you excited about OpenCL!  OpenCL is a huge step towards transparently leveraging additional cores, vector instructions, and GPUs.&lt;/p&gt;

&lt;p&gt;* Full disclaimer: I have never actually used OpenCL, but I&amp;#8217;ve definitely struggled with the problems it solves.  The IMVU client has some optimized inner loops that we&amp;#8217;ve hand-implemented for the GPU, SSE, or C-compiled x87 code.  Unfortunately, we have had to manually select between those code paths based on the capabilities of the hardware.  This sucks.  With even decent OpenCL implementations, we could avoid all of that work and transparently benefit from future hardware improvements.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/_klnp1zNgmE&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 24 Aug 2009 05:28:08 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: progrium</title>
	<guid>http://blogrium.wordpress.com/?p=63</guid>
	<link>http://blogrium.wordpress.com/2009/08/13/getting-webhook-callbacks-when-people-click-through-links/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;So I recently put this blog&amp;#8217;s feed through FeedBurner. If I recall, I think I wanted to get subscriber statistics, as well as to try out their integration of &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot;&gt;PubSubHubbub&lt;/a&gt; publishing. But since I didn&amp;#8217;t think I would get new subscribers often and I&amp;#8217;m too lazy to check stats, I really wanted a way to be notified when people subscribed. Since the means of subscribing would be a link, it hit me: click-through webhooks.&lt;/p&gt;
&lt;p&gt;I wanted a link wrapper that would trigger a URL callback (aka a webhook) when people clicked through the link. Similar to a URL shortener, you&amp;#8217;d just give it a URL and it would give you another URL, but instead of being shorter, it would be tied to a callback that would run as it redirected the user to the original URL. What could you do with this, you ask? It&amp;#8217;s a webhook; you can do anything with this event.&lt;/p&gt;
&lt;p&gt;Coming back to my original use case, I&amp;#8217;d probably tie it to a script that sent me an IM that somebody subscribed. Or better yet, with something like &lt;a href=&quot;http://github.com/progrium/yapper/tree/master&quot;&gt;Yapper&lt;/a&gt;, I could get a Growl notification. Sweet, right?&lt;/p&gt;
&lt;p&gt;I knew it would be trivial to build, and even though it was a feature that I really wanted, it was still just a feature. I thought, it really doesn&amp;#8217;t need its own app, does it? So I went to my URL shortener of choice, &lt;a href=&quot;http://tr.im/&quot;&gt;tr.im&lt;/a&gt;, and &lt;a href=&quot;http://feedback.tr.im/pages/7238-tr-im/suggestions/250390-add-a-clickthrough-callback-url&quot;&gt;suggested it as a feature&lt;/a&gt;. I also happened to mention to all my friends they should vote it up. Well, it ended up being the 6th most requested feature because of that. I thought for sure they&amp;#8217;d implement it. I mean it was so much easier than the others, and I gave them code to help do it and everything.&lt;/p&gt;
&lt;p&gt;A couple weeks went by and nothing happened. I got no response. I emailed them and got nothing back. They didn&amp;#8217;t even mark it as &amp;#8220;under review.&amp;#8221; It may have had to do with the fact they were then deciding to shut down &amp;#8230; which I hear they&amp;#8217;ve changed their mind about. Nevertheless, it still hadn&amp;#8217;t happened. And I really wanted to be able to do this notification on subscription thing!&lt;/p&gt;
&lt;p&gt;Along came my &lt;a href=&quot;http://upcoming.yahoo.com/event/4049111&quot;&gt;WebHooks and PubSubHubbub meetup&lt;/a&gt; where I wanted to demo this bit of plumbing. Of course, I had no way to do it because nobody had implemented it. So I figured I&amp;#8217;d just build it that day before the meetup. Twenty minutes later, I had it live: &lt;a href=&quot;http://www.clickhooks.com/&quot;&gt;ClickHooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Okay, so that part&amp;#8217;s done. How do I get it to IM me? Well, &lt;a href=&quot;http://www.scriptlets.org/&quot;&gt;Scriptlets&lt;/a&gt; was made to write the glue code to use with these kinds of webhooks. And my project &lt;a href=&quot;http://github.com/progrium/protocol-droid/tree/master&quot;&gt;Protocol Droid&lt;/a&gt; was made to make it easy to use other protocols from HTTP. So I just threw this little baby on Scriptlets and I was &lt;strong&gt;done&lt;/strong&gt;:&lt;/p&gt;
&lt;pre name=&quot;code&quot; class=&quot;python&quot;&gt;

import urllib

payload = {
 &amp;#039;username&amp;#039;: &amp;#039;demo@progrium.com&amp;#039;,
 &amp;#039;password&amp;#039;: &amp;#039;secret&amp;#039;,
 &amp;#039;to&amp;#039;: &amp;#039;progrium@gmail.com&amp;#039;,
 &amp;#039;body&amp;#039;: &quot;You got a new subscriber on blogrium!&quot;
}

fetch(&quot;http://pdroid.progrium.com/xmpp:talk.google.com/send&quot;, urllib.urlencode(payload), &quot;POST&quot;)
&lt;/pre&gt;
&lt;p&gt;Yes, that pdroid endpoint is live. No, I don&amp;#8217;t recommend using it for production. Stand up your own Protocol Droid gateway. ;)&lt;/p&gt;
&lt;p&gt;Anyway, simple enough to understand though, right? It should be. And it was simple to get set up. That&amp;#8217;s the whole point of a world of webhooks: you can easily do so much cool stuff if this simple infrastructure is there.&lt;/p&gt;
&lt;p&gt;As an aside, later I realized I could generalize my IM scriptlet to use a GET param for the body of the message, allowing me to make a personal messaging micro-webservice: &lt;code&gt;http://www.scriptlets.org/abcdef?body=Hello, world!&lt;/code&gt; The data in this URL could then be hidden behind a URL shortener, giving me a regular looking URL that I could then give to people that would IM me the message when they clicked it. Kind of silly, but I almost set up a link that would IM me &amp;#8220;At the door!&amp;#8221; that people could click from their phone browsers as a doorbell for the WebHooks meetup.&lt;/p&gt;
&lt;p&gt;Ah, fun with infrastructure.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/63/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/63/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/63/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/63/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/63/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/63/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/63/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/63/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/63/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/63/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=63&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 13 Aug 2009 09:21:35 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: PHP, Language of Mystery</title>
	<guid>http://www.egometry.com/?p=896</guid>
	<link>http://www.egometry.com/tech/php-language-of-mystery/</link>
	<description>&lt;p&gt;PHP seems so arbitrary sometimes.&lt;/p&gt;
&lt;pre&gt;
function test_nine() {
	$$&quot;9&quot; = 22;
}
&lt;/pre&gt;
&lt;p&gt;fails to parse.&lt;br /&gt;
(which is good, I suppose)&lt;/p&gt;
&lt;p&gt;This passes:&lt;/p&gt;
&lt;pre&gt;
function test_nine() {
	$n = 9;
	$$n = 22;
	$this-&gt;assertEqual($$n, 22);
}
&lt;/pre&gt;
&lt;p&gt;-Andy Friesen,&lt;br /&gt;
of &lt;a href=&quot;http://giant-communist-robots.com/&quot;&gt;giant-communist-robots.com&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Tue, 21 Jul 2009 17:08:48 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Gruedorf: the Swampening</title>
	<guid>http://www.egometry.com/?p=894</guid>
	<link>http://www.egometry.com/gruedorf/gruedorf-the-swampening/</link>
	<description>&lt;p&gt;Between putting in incredible hours at work, and a few Magic: the Gathering pre-release events in the last week, I haven&amp;#8217;t had much time for gruedorfing.&lt;/p&gt;
&lt;p&gt;However, I still got 14 commits in.  (All of them Friday morning.)&lt;/p&gt;
&lt;p&gt;The work done was all in finalizing the /downloads/complete-new-os/ page, and tracking down and fixing errors that had cropped up in the upload process.&lt;/p&gt;
&lt;p&gt;The second item distresses me, presently, since a solid upload system was the main impetus for the rewrite.  finding out that uploads are still fragile and very prone to breaking with forward development, combined with the fact that I don&amp;#8217;t have a testing strategy for roundtrip uploads, means I&amp;#8217;m kinda nervous.&lt;/p&gt;
&lt;p&gt;So, anyone out there have a good solution for a round-trip integration test where you upload, via flash and javascript, a unique file, and then verify that the file exists on a unix filesystem, and then verify that a corresponding database entry and further corresponding webpage works?&lt;/p&gt;
&lt;p&gt;Moving forward, I&amp;#8217;ll be working on an administrative page to allow file owners/admins to associate file instances as older/newer versions of the same file.&lt;/p&gt;</description>
	<pubDate>Wed, 15 Jul 2009 20:49:23 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Uploads, Downloads, and the Management Thereof.</title>
	<guid>http://www.egometry.com/?p=890</guid>
	<link>http://www.egometry.com/gruedorf/uploads-downloads-and-the-management-thereof/</link>
	<description>&lt;p&gt;After some prodding, I managed to get the &lt;a href=&quot;http://www.gearleaf.com/node/39&quot; target=&quot;_blank&quot;&gt;dorf&lt;/a&gt; back into &lt;a href=&quot;http://www.johnweng.com/gruedorf/&quot; target=&quot;_blank&quot;&gt;gruedorf&lt;/a&gt;.  Let the games resume.&lt;/p&gt;
&lt;p&gt;Since last I posted about &lt;a href=&quot;http://beta.verge-rpg.com/&quot; target=&quot;_blank&quot;&gt;beta.vrpg&lt;/a&gt;, 58 revisions have occurred.  In that time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I got file submissions up.&lt;/li&gt;
&lt;li&gt;I got (simple, title-based) file searches up.&lt;/li&gt;
&lt;li&gt;I got most of the file details page up (thread spawning, screenshot uploading pending).&lt;/li&gt;
&lt;li&gt;I did a &lt;i&gt;lot&lt;/i&gt; of database reworking and massaging, mainly to get to a point where&amp;#8230;&lt;/li&gt;
&lt;li&gt;&amp;#8230;single file entries can have multiple physical files attached, so one game can have file links to every OS it&amp;#8217;s released on&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oh, and I made a &lt;a rel=&quot;nofollow&quot; href=&quot;http://beta.verge-rpg.com/simulated-bad-error&quot; target=&quot;_blank&quot;&gt;Silly 500 Internal Service Error page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Definitely the most important part of this work.&lt;/p&gt;
&lt;p&gt;Going forward will be finishing the file management side of things (letting you deprecate old versions of files in favor of new ones, showing a browsable history, letting you edit and delete files you own), and cranking out the community-based side of things (ie, image uploading and talkback threads on file pages.)  After that, advanced search options and a browsable file index, and the section should be complete.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m mainly excited to see a upload system that hasn&amp;#8217;t seen a failure yet.  This was one of the major failures of the current vrpg that prompted the rewrite.  I used &lt;a target=&quot;_blank&quot; href=&quot;http://www.swfupload.org/&quot;&gt;swfupload&lt;/a&gt; for the actual UI/handling of the upload, and integrating it went very smoothly.&lt;/p&gt;</description>
	<pubDate>Wed, 08 Jul 2009 16:36:57 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: PHP5, you king of bastards (setting an instance member inside a static class call)</title>
	<guid>http://www.egometry.com/?p=888</guid>
	<link>http://www.egometry.com/tech/php5-you-king-of-bastards-setting-an-instance-member-inside-a-static-class-call/</link>
	<description>&lt;p&gt;If I&amp;#8217;m in an instanced class, and I call another class&amp;#8217;s method statically inside of a method in the first class, and that static method should happen to &lt;i&gt;(erroneously)&lt;/i&gt; have $this-&gt;whatever inside of it&amp;#8230;&lt;/p&gt;
&lt;p&gt;&amp;#8230;it sets $whatever on my outer instanced class.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s some illustrative code:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&amp;nbsp;Inner_Static&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;burrito()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;_member&amp;nbsp;=&amp;nbsp;‘A&amp;nbsp;keyboard.&amp;nbsp;How&amp;nbsp;quaint.’;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&amp;nbsp;Outer_Instance&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;taco()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Inner_Static::burrito();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$my_guy&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Outer_Instance();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$my_guy-&amp;gt;taco();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;‘$my_guy-&amp;gt;_member:&amp;nbsp;‘&amp;nbsp;.&amp;nbsp;$my_guy-&amp;gt;_member;&amp;nbsp;
&lt;/pre&gt;
&lt;p&gt;This boggles my mind a bit.  Tracking it down cost me a bit of time.  Is there actually a sane use for this little tidbit, or am I justified in thinking that a good language would warn you that scope shenanigans are going on here?&lt;/p&gt;</description>
	<pubDate>Wed, 08 Jul 2009 13:48:58 +0000</pubDate>
</item>
<item>
	<title>Michael Rooney: Simple timing of Python code</title>
	<guid>tag:blogger.com,1999:blog-3369913276619133519.post-6311104075784755550</guid>
	<link>http://feedproxy.google.com/~r/mrooney/~3/3GI_AshsioU/simple-timing-of-python-code.html</link>
	<description>Often when I am writing in Python, I find that I want to see how long a particular function call or set of statements are taking to execute.  Let's say I have the following code that gets executed frequently:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for i in range(10000000):&lt;br /&gt;   x = 934.12 ** 32.61 * i / 453.12 ** 0.23&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and I want to know how long it takes to execute to see if it is slowing down my app and should be optimized. Previously I would surround it as such:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import time; x = time.time()&lt;br /&gt;for i in range(10000000):&lt;br /&gt;   x = 934.12 ** 32.61 * i / 453.12 ** 0.23&lt;br /&gt;print time.time() - x&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will print out the duration in seconds of that code segment, but is more work and typing than I want, and more cleaning up later. I realized that the new &quot;with&quot; statement in Python could probably help me out. Let's create a little timer class that cooperates with it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Timer():&lt;br /&gt;   def __enter__(self): self.start = time.time()&lt;br /&gt;   def __exit__(self, *args): print time.time() - self.start&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now all we have to do is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;with Timer():&lt;br /&gt;   for i in range(1000000):&lt;br /&gt;       x = 934.12 ** 32.61 * i / 453.12 ** 0.23&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can also try:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;with Timer():&lt;br /&gt;   time.sleep(1.5)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For these, 0.28738 and 1.50169 are what I get, respectively. While something like this couldn't really replace application-wide profiling via &lt;a href=&quot;http://docs.python.org/library/profile.html&quot;&gt;a module like cProfile&lt;/a&gt;, it can be an extremely useful and quick way to see if your prototype is scalable or not. I usually end up having a debug.py or helpers.py file in my larger projects with little tools like this, and I'll probably end up adding this one as well.&lt;br /&gt;&lt;br /&gt;Let me know if you are doing something similar, or if I've reinvented something that already exists. I'd also love to hear from people profiling their python code and what techniques they are using, as I am just starting to learn about it.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3369913276619133519-6311104075784755550?l=mrooney.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/mrooney/~4/3GI_AshsioU&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Tue, 07 Jul 2009 00:12:08 +0000</pubDate>
	<author>noreply@blogger.com (Michael)</author>
</item>
<item>
	<title>Benjamin McGraw: Simple scripts always ship.</title>
	<guid>http://www.egometry.com/?p=862</guid>
	<link>http://www.egometry.com/gruedorf/simple-scripts-always-ship/</link>
	<description>&lt;h2&gt;Simple needs, simple deeds.&lt;/h2&gt;
&lt;p&gt;A need for a simple one-off occurred Monday evening at work.  Some non-engineer coworkers needed to be shown how to make some non-&lt;a href=&quot;http://en.wikipedia.org/wiki/ISO_8859-1&quot; target=&quot;_blank&quot;&gt;Latin-1&lt;/a&gt; text into html entities.  &lt;/p&gt;
&lt;p&gt;Basically, they needed a 5 line php script.&lt;/p&gt;
&lt;p&gt;Right before sending them to &lt;a href=&quot;http://www.google.com/search?q=html+entity+converter&quot; target=&quot;_blank&quot;&gt;any number of sites that already do this 5-line operation&lt;/a&gt;, I decide: &lt;i&gt;what the hell, I&amp;#8217;ll just make one of my own&lt;/i&gt;.  And so, that night after unwinding, &lt;a href=&quot;http://www.egometry.com/html-entitizer/&quot; target=&quot;_blank&quot;&gt;I did&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s my &lt;a href=&quot;http://www.egometry.com/html-entitizer/&quot; target=&quot;_blank&quot;&gt;HTML Entitizer&lt;/a&gt;.  Suitable for all your HTML entitizing needs, large &lt;i&gt;or&lt;/i&gt; small!&lt;/p&gt;
&lt;h2&gt;PHP in &lt;u&gt;Escape from &amp;amp;#76;&amp;amp;#46;&amp;amp;#65;&amp;amp;#46;&lt;/u&gt;&lt;a href=&quot;http://www.zefrank.com/thewiki/the_show:_05-10-06&quot; target=&quot;_blank&quot;&gt;(jokesfornerds)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the reasons PHP is so popular is the fact that it&amp;#8217;s got so many handy little functions.  In this case, &lt;a href=&quot;http://php.net/manual/en/function.htmlentities.php&quot;&gt;htmlentities()&lt;/a&gt; is the blade of PHP&amp;#8217;s swiss army knife that we&amp;#8217;re using.  Of course, indiscriminate use of functions like this cause problems like double-escaped characters (&amp;amp;amp;amp;) showing up in databases. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.egometry.com/i/2009/07/swiss-army-everything.jpg&quot; rel=&quot;lightbox[pics862]&quot; title=&quot;PHP, the swiss-army knife.&quot;&gt;&lt;img src=&quot;http://www.egometry.com/i/2009/07/swiss-army-everything.thumbnail.jpg&quot; alt=&quot;PHP, the swiss-army knife.&quot; width=&quot;200&quot; height=&quot;152&quot; class=&quot;attachment wp-att-864 alignright&quot; /&gt;&lt;/a&gt;PHP&amp;#8217;s solution to this sort of thing is generally to throw new corkscrews and toothpicks onto it&amp;#8217;s ever-growing pile of tools on it&amp;#8217;s knife.  If you look at the &lt;a href=&quot;http://php.net/manual/en/function.htmlentities.php&quot;&gt;documentation page for htmlentities()&lt;/a&gt;, you can see that as of version 5.2.3 of PHP, another optional parameter was added: double_encode. Which will&lt;/p&gt;
&lt;p&gt;Getting the right escape order can be hard, especially for novices or small teams inheriting code from other small teams.  To date I don&amp;#8217;t think I&amp;#8217;ve inherited work on a webapp whose database wasn&amp;#8217;t littered with extraneous &amp;amp;amp;&amp;#8217;s and rogue \\&amp;#8217;s. It&amp;#8217;s only by virtue of verge-rpg.com having a single developer who is really, &lt;i&gt;really&lt;/i&gt; annoyed by this problem the the point of neuroticism that &amp;amp;amp;amp; never appears in the database except in &lt;a href=&quot;http://verge-rpg.com/boards/display_thread.php?id=131844#post131851&quot; target=&quot;_blank&quot;&gt;posts that actually wanted to display &amp;amp;amp;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Although even this level of OCD-database-cleansing didn&amp;#8217;t prevent &lt;a href=&quot;http://verge-rpg.com/boards/display_thread.php?id=131844#post131850&quot; target=&quot;_blank&quot;&gt;escaping-related errors on the first go-round&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Teh (sic) Implementation.&lt;/h2&gt;
&lt;p&gt;So, the only time-consuming part of getting this script into my wordpress site (other than me taking a bloody half hour to blog about a 2-minute job) was convincing wordpress that it should allow &lt;span&gt;&amp;lt;?php&lt;/span&gt; fragments into my posts.&lt;/p&gt;
&lt;p&gt;Luckily, other people before me have wanted this very thing.  Wordpress&amp;#8217;s biggest strength is again one of PHP&amp;#8217;s: if you want it, it&amp;#8217;s already been made for you.  In this case the &lt;a href=&quot;http://bluesome.net/post/2005/08/18/50/%20Exec-PHP&quot; target=&quot;_blank&quot;&gt;Exec-PHP&lt;/a&gt; module will let admin-level users of your blog post for-reals, actual PHP into your posts!  You&amp;#8217;d better hope your admins don&amp;#8217;t have their accounts compromised! &lt;span&gt;(&amp;#8230;one moment.  Changing my password.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In PHP&amp;#8217;s case, the code that you want that&amp;#8217; already been written for you is &lt;a href=&quot;http://www.php.net/manual/en/function.htmlentities.php#84612&quot;&gt;in every single function&amp;#8217;s talkback thread&lt;/a&gt;.  These functions may not be hyper-optimized or the best solution for any given problem, but they generally are what you want to prove a point.  You scan the docs, you grab the code, you put it in your site, and you move on to the next problem in your own app.&lt;/p&gt;
&lt;p&gt;Quick and dirty, the way PHP likes it.&lt;/p&gt;
&lt;p&gt;For the curious, here&amp;#8217;s the solution I spat out (copy included):&lt;/p&gt;
&lt;pre&gt;
&amp;lt;h1&amp;gt;Escape html&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;This is a simple script to give the escaped codes for some html. Useful
for making foreign languages play nice with html, regardless of how the
server handles string encoding.&amp;lt;/p&amp;gt;
&amp;lt;?
if( isset($_POST['escape_me']) ) {
echo('&amp;lt;h2&amp;gt;Your escaped html&amp;lt;/h2&amp;gt;&amp;lt;div'.
     'style=&quot;background-color: #ddd; padding: 8px;&quot;&amp;gt;');
echo(str_replace('&amp;amp;','&amp;amp;amp;',htmlentities(stripslashes($_POST['escape_me']),
     ENT_NOQUOTES,'UTF-8')));
echo( '&amp;lt;/div&amp;gt;' );
}
?&amp;gt;
&amp;lt;form action='/html-entitizer/' method='POST'&amp;gt;
Text to escape:
&amp;lt;textarea name='escape_me' style='width: 550px; height: 200px;'&amp;gt;&amp;lt;/textarea&amp;gt;
&amp;lt;input type='submit' value='Create my html entities'&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;(weird formatting so it doesn&amp;#8217;t run off the side of the screen; I don&amp;#8217;t actually code like that.  Mostly. ;)&lt;/p&gt;
&lt;h2&gt;Coda&lt;/h2&gt;
&lt;p&gt;It is of note that this &lt;i&gt;tiny&lt;/i&gt; amount of effort got me two really sincere &amp;#8220;thank yous&amp;#8221; from the non-engineers.  It&amp;#8217;s important to note that things that are mindlessly trivial to a programmer can be tedious tasks to someone without the power to bully the computer into doing labor for them.  One of the guys, a computer saavy guy who had access to lists of what each escaped character translated to, insisted that he&amp;#8217;d just search/replace the offensive characters by hand.  &lt;/p&gt;
&lt;p&gt;Ostensibly, this was offered to save me work.&lt;/p&gt;
&lt;p&gt;How much time did my 2 minutes of code save him?&lt;/p&gt;
&lt;p&gt;(&lt;a href=&quot;http://www.google.com/search?q=html+entity+converter&quot; target=&quot;_blank&quot;&gt;Don&amp;#8217;t forget a google for &amp;#8220;html entity converter&amp;#8221; would&amp;#8217;ve saved even that, had I cared to not make the tiny toy script of my own&lt;/a&gt;.  I&amp;#8217;ll ramble on about re-using other people&amp;#8217;s work more later, but it&amp;#8217;s key to remember even what little work I did end up doing was extraneous and largely an exercise in vanity.)&lt;/p&gt;</description>
	<pubDate>Wed, 01 Jul 2009 11:18:32 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: beta is the new gamma</title>
	<guid>http://www.egometry.com/?p=853</guid>
	<link>http://www.egometry.com/gruedorf/beta-is-the-new-gamma/</link>
	<description>&lt;p&gt;Work continues apace on beta.verge-rpg.com.&lt;/p&gt;
&lt;p&gt;Actually, it&amp;#8217;s quite brisk now.  Almost 60 revisions have passed in the last week.&lt;/p&gt;
&lt;p&gt;Gayo and crew have banged on the forums, and I patched several oversights.  Locally I&amp;#8217;ve moved on to the new downloads section, which I&amp;#8217;m looking forward greatly to finishing.  Mainly so there can be an upload script that works for most users and gives progress feedback.&lt;/p&gt;
&lt;p&gt;Are all webapps 98% mundane crap?  I&amp;#8217;ve been doing them for almost a decade now, and I think I have an answer.&lt;/p&gt;
&lt;p&gt;(The answer is &amp;#8220;yes&amp;#8221;.)&lt;/p&gt;</description>
	<pubDate>Mon, 29 Jun 2009 12:38:44 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Yapper, a Jabber/XMPP interface for Growl</title>
	<guid>http://blogrium.wordpress.com/?p=51</guid>
	<link>http://blogrium.wordpress.com/2009/06/28/yapper-a-jabberxmpp-interface-for-growl/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;&lt;img class=&quot;size-full wp-image-57 aligncenter&quot; title=&quot;Yapper, a Jabber/XMPP interface for Growl&quot; src=&quot;http://blogrium.files.wordpress.com/2009/06/yapper_example.png?w=418&amp;#038;h=133&quot; alt=&quot;Yapper, a Jabber/XMPP interface for Growl&quot; width=&quot;418&quot; height=&quot;133&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Today I released &lt;a href=&quot;http://github.com/progrium/yapper/tree/master&quot;&gt;Yapper&lt;/a&gt;, a full featured Jabber/XMPP interface for Growl. It was based on the &lt;a href=&quot;http://gist.github.com/133361&quot;&gt;simple Twisted script&lt;/a&gt; I wrote while building my &lt;a href=&quot;http://blogrium.wordpress.com/2009/06/22/fun-with-internet-plumbing/&quot;&gt;notification email to Growl piping&lt;/a&gt;. Although it&amp;#8217;s limited to OS X users, I still think this is a big deal. Let me explain.&lt;/p&gt;
&lt;p&gt;If you haven&amp;#8217;t heard of &lt;a href=&quot;http://growl.info/&quot;&gt;Growl&lt;/a&gt;, it&amp;#8217;s a global notification system that lets applications notify you of events in a consistent, customizable way. It&amp;#8217;s been around for a while and is integrated or has plugins for &lt;a href=&quot;http://growl.info/applications.php&quot;&gt;lots of popular apps&lt;/a&gt; like iTunes, Adium, and Tweetie. It has bindings for a bunch of languages and also has a command line tool that you shell scripters can use to pipe notifications into. For example, I used this recently for my &lt;a href=&quot;http://blogrium.wordpress.com/2009/06/13/reminders-with-quicksilver-and-growl/&quot;&gt;reminder system&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think Growl is great particularly because it very nicely solves &lt;em&gt;&lt;strong&gt;passive&lt;/strong&gt;&lt;/em&gt; real-time notifications. That is, you want to be notified, but you don&amp;#8217;t want it to interrupt you by requiring action. This is why I hate email notifications.&lt;/p&gt;
&lt;p&gt;However, the major problem with Growl is that for the most part, it&amp;#8217;s limited to local notifications. Sure, you can get notifications from &amp;#8220;out there,&amp;#8221; like Twitter or IRC or Gmail &amp;#8230; but it requires you to have a local application that pushes them into Growl. One for each, in fact.&lt;/p&gt;
&lt;p&gt;It turns out, I don&amp;#8217;t actually care about most local notifications. Telling me a file is done downloading or what song is playing in iTunes is not terribly notification worthy. If I&amp;#8217;m sitting there to get the notification, I probably already know. The most useful notifications are  of events important to me that I&amp;#8217;m nowhere near &amp;#8230; events from things out on the Internet.&lt;/p&gt;
&lt;p&gt;So Growl needs a network interface. Oh, wait! It has one! Well, what&amp;#8217;s the problem? Two things: it&amp;#8217;s a non-standard protocol, and it requires a direct connection. That not only raises the bar for things &amp;#8220;out there&amp;#8221; to notify you with Growl, but it literally makes it impossible if you&amp;#8217;re constantly changing IPs, sitting behind a firewall or NAT, etc.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s see&amp;#8230; who&amp;#8217;s solved this problem already? Right, IM! &lt;a href=&quot;http://xmpp.org/&quot;&gt;XMPP&lt;/a&gt;, the open standard for IM and real-time message passing (also known as Jabber), seems to have everything we need. It&amp;#8217;s a popular protocol, fairly accessible from any language, and doesn&amp;#8217;t require a direct point to point connection. So it&amp;#8217;s a perfect transport for network Growl notifications!&lt;/p&gt;
&lt;p&gt;Since I&amp;#8217;m not one to wait around for people to implement what I think they should implement, I solved this problem by making Yapper. Yapper is a lightweight Jabber client made specifically to receive Growl notifications. It starts when your machine starts and sits in the background just waiting for whatever you have sent to it so it can pop it up with Growl.&lt;/p&gt;
&lt;p&gt;You can now easily have Growl notifications sent to you from anywhere. Websites have less of a reason not to directly notify you with Growl for events that are important to you. More importantly for me, I can more easily set up Growl notifications for whatever I want. With the rise of &lt;a href=&quot;http://blog.webhooks.org/&quot;&gt;webhooks&lt;/a&gt;, so can you. Anyway, to me this generally makes Growl much more useful.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://github.com/progrium/yapper/tree/master&quot;&gt;Give Yapper a look&lt;/a&gt;. It&amp;#8217;s on GitHub under MIT license. It&amp;#8217;s the first release, but it should work fine. If not, &lt;a href=&quot;http://github.com/progrium/yapper/issues&quot;&gt;drop off an issue&lt;/a&gt; and it&amp;#8217;ll likely be taken care of.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/51/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/51/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/51/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/51/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/51/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/51/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/51/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/51/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/51/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/51/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=51&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 28 Jun 2009 08:12:02 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: progrium</title>
	<guid>http://blogrium.wordpress.com/?p=47</guid>
	<link>http://blogrium.wordpress.com/2009/06/26/why-minimalist-software-wins-at-workflow/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Recently I&amp;#8217;ve been evaluating software to help support agile/scrum development on our team, and ideally to roll into our NASA Code product for others to use. We&amp;#8217;re already married to &lt;a href=&quot;http://trac.edgewall.org/&quot;&gt;Trac&lt;/a&gt;, so we&amp;#8217;ve been playing with &lt;a href=&quot;http://www.agile42.com/cms/pages/agilo/&quot;&gt;Agilo&lt;/a&gt; and are looking at some of the other agile plugins for Trac. Unfortunately they&amp;#8217;re all so heavyweight, despite some that claim not to be.&lt;/p&gt;
&lt;p&gt;I came back to a realization I&amp;#8217;m sure a lot of us have had: most software sucks. Especially software that&amp;#8217;s intended to augment some real-life process. When asking &lt;a href=&quot;http://timothyfitz.wordpress.com/&quot;&gt;Timothy Fitz&lt;/a&gt; (my insight into the amazing continuous improvement processes used at IMVU) about recommendations on agile tools, he said: &amp;#8220;a board and post-its (seriously)&amp;#8221;&lt;/p&gt;
&lt;p&gt;This is part of the reason most enterprise software sucks so terribly. Enterprise is about lots of real-life process and workflow, and given that process augmentation software even in small doses generally sucks, large amounts of it will suck exponentially.&lt;/p&gt;
&lt;p&gt;A lot of us have learned that less software is more effective. One major attraction of Trac was their goal of staying out of the way through minimalism. The trick with minimalism, in general, is knowing what&amp;#8217;s actually important&amp;mdash;the essence of the message or design. This is a big part of my design process. Asking, &amp;#8220;How can I fold these requirements into fewer features and UI?&amp;#8221; instead of directly implementing a feature for every requirement.&lt;/p&gt;
&lt;p&gt;The other thing about minimalism is that, like abstraction (another form of compression), everything you leave in the design makes such a huge difference. In programming, when you make abstractions, you&amp;#8217;re deciding what you can assume. This means abstractions can go in different directions depending on the assumption requirements of what&amp;#8217;s going to use the abstraction. The risk with minimalist software is that a simple design choice can drastically change the direction of the abstraction and make or break whether the software fits your needs.&lt;/p&gt;
&lt;p&gt;Luckily, minimalism buys you a sort of abstraction that can enable projection. By this I mean that users can project their actual process and workflow onto the software. If it doesn&amp;#8217;t have features that impose a particular process, users are free to do what works for them. This is why wikis are so powerful.&lt;/p&gt;
&lt;p&gt;Coming back to Timothy&amp;#8217;s &amp;#8220;a board and post-its&amp;#8221; remark, why do you even need software? If you can do it without software, why would you want to bring software in to slow things down?&lt;/p&gt;
&lt;p&gt;Software does have a couple strengths. First, it encodes process in way that means you can automate parts of it. Nobody has to worry about manually typesetting when using a word processor. Second, it persists and organizes information that would normally be lost in handwritten notes, or worse, somebody&amp;#8217;s head. The trick is getting these advantages without getting in the way.&lt;/p&gt;
&lt;p&gt;A naive approach to software design is thinking that perfectly modeling a system, such as your development process, is the way to good software. I used to think this. It sounds great because then you can programmatically reason about every aspect of the system. But in the real-world, no two systems are exactly alike. In fact, a given system can change quite a bit in its lifetime. So there&amp;#8217;s really no point to modeling systems with that kind of precision.&lt;/p&gt;
&lt;p&gt;However, I&amp;#8217;m seeing a lot of this in agile/scrum software. Requirements have stories, stories have tasks, organized into iterations and releases. CRUD for every noun mentioned in scrum. This on top of abstractions in a direction different than we need. Numbers where it doesn&amp;#8217;t really matter. Nice pie chart breakdowns we&amp;#8217;ll rarely use. Top it off with horrible UI, since with all these features there isn&amp;#8217;t time to make them easy to use.&lt;/p&gt;
&lt;p&gt;Honestly, &lt;a href=&quot;http://www.pivotaltracker.com&quot;&gt;Pivotal Tracker&lt;/a&gt; seems to have the best abstraction of agile. It folds requirements, stories and tasks into just stories. It automatically and dynamically creates iterations and calculates velocity. It keeps you on a single page, keeping you focused on what&amp;#8217;s important.&lt;/p&gt;
&lt;p&gt;Unfortunately, we can&amp;#8217;t use Pivotal Tracker since we&amp;#8217;d need it on our servers and the licensing they offered doesn&amp;#8217;t scale if we want to essentially give it away as part of NASA Code. It&amp;#8217;s likely I&amp;#8217;ll want to just start nudging Trac in the right direction using Pivotal Tracker as a model reference, pulling together code from Agilo and other plugins. If there&amp;#8217;s one thing that complements minimalist design, it&amp;#8217;s an extension architecture, and Trac has an excellent plugin system.&lt;/p&gt;
&lt;p&gt;Anyway, as far as augmenting process and workflow, I&amp;#8217;ve always liked the idea of starting with a wiki and lazily formalizing the process into custom software as needed. As long as you can keep it under control, mind your requirement abstractions, and avoid writing too much software.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/47/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/47/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/47/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/47/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/47/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/47/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/47/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/47/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/47/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/47/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=47&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Fri, 26 Jun 2009 09:01:58 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Adam with my laptop and the Growl notice</title>
	<guid>http://blogrium.wordpress.com/?p=40</guid>
	<link>http://blogrium.wordpress.com/2009/06/22/fun-with-internet-plumbing/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;The other day I realized I hate notification emails. In particular I&amp;#8217;m talking about SVN commit notifications. I have them set up to skip my inbox and filter into a label on GMail, but this doesn&amp;#8217;t really help. They don&amp;#8217;t pollute my inbox, but I still have to go out of the way to read them. Or at the very least, mark them as read, which is still quite annoying!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.growl.info/&quot;&gt;Growl&lt;/a&gt; is supposed to help solve this problem. In fact, when I was retooling the notification system at work, I would have loved to integrate Growl &amp;#8230; except that Growl&amp;#8217;s network interface requires a direct connection.&lt;/p&gt;
&lt;p&gt;Taking a step back, it&amp;#8217;s not just work notifications. A lot of us get a lot of notification emails about a lot of things. Most of them are poorly designed, for example, without important details of the notice in the subject. Plus, as email they require disrupting action. Not just to open and read if you have to, but just to archive and/or mark as read.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s great to have an archive in email, but email is just not ideal for notifications. If I&amp;#8217;m around to receive them, I should get the important information passively and not have to do anything else until I need to reference it later, if ever. That means Growl.&lt;/p&gt;
&lt;h3&gt;Getting Notification Emails to Growl&lt;/h3&gt;
&lt;p&gt;I thought to myself, &amp;#8220;I &lt;em&gt;should&lt;/em&gt; be able to rig this up. And it &lt;em&gt;should&lt;/em&gt; be easy.&amp;#8221; And if the infrastructure and plumbing I&amp;#8217;ve wanted was in place, it &lt;em&gt;would&lt;/em&gt; be easy. So I decided to lay it down and make it happen. Here&amp;#8217;s what I needed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An email to webhook bridge, like my old &lt;a href=&quot;http://blogrium.com/2007/01/18/mailhook/&quot;&gt;Mailhook&lt;/a&gt; service.&lt;/li&gt;
&lt;li&gt;An XMPP to Growl bridge. We all want this anyway, right?&lt;/li&gt;
&lt;li&gt;An HTTP to XMPP bridge. Why? You&amp;#8217;ll see.&lt;/li&gt;
&lt;li&gt;Glue code that can run in the cloud. This is what &lt;a href=&quot;http://www.scriptlets.org&quot;&gt;Scriptlets&lt;/a&gt; is for.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;ve since turned off Mailhook, but I&amp;#8217;ve been planning to roll its code into my still early &lt;a href=&quot;http://github.com/progrium/protocol-droid/tree/master&quot;&gt;Protocol Droid&lt;/a&gt; project. This is an HTTP to anything bridge written in Python with Twisted that makes heavy use of webhooks. I&amp;#8217;d plan to roll the HTTP to XMPP bridge in there as well. For now, the XMPP to Growl bridge would be separate.&lt;/p&gt;
&lt;p&gt;Having all that, here was the pipeline I envisioned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A notification email would come into Gmail and get filtered&lt;/li&gt;
&lt;li&gt;It would forward to an address that points to Protocol Droid&lt;/li&gt;
&lt;li&gt;Protocol Droid would post the email to a script on Scriptlets&lt;/li&gt;
&lt;li&gt;The script would use Protocol Droid again to send an XMPP message&lt;/li&gt;
&lt;li&gt;The message would be sent to a JID for my laptop if online&lt;/li&gt;
&lt;li&gt;The XMPP to Growl bridge on my laptop would receive and notify me&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Building the Infrastructure&lt;/h3&gt;
&lt;p&gt;I decided to build all this last Friday night. I got caffeinated and went to work, starting with Protocol Droid. I hadn&amp;#8217;t touched it since I was trying to build an HTTP to SMTP module for it. It wasn&amp;#8217;t part of this project, but I decided to finish it off. You know, to get warmed up and have an early win.&lt;/p&gt;
&lt;p&gt;That happened pretty quickly, so I was excited get started on the next task: an email to webhook bridge. This was a little different. So far everything in Protocol Droid was for outgoing connections. This would be the first listening module. The idea was that it would be an SMTP server that would parse incoming email and post it to a callback URL registered for a recipient domain. I&amp;#8217;d written several of these before for mailhook.org, so I ported the code to Twisted for Protocol Droid. Another pretty easy win. I used &lt;a href=&quot;http://www.postbin.org/&quot;&gt;PostBin&lt;/a&gt; to debug this, obviously.&lt;/p&gt;
&lt;p&gt;At that point, I decided to take a break and watch an episode of &lt;a href=&quot;http://www.imdb.com/title/tt0925266/&quot;&gt;Pushing Daisies&lt;/a&gt;. I still haven&amp;#8217;t seen all of the second season!&lt;/p&gt;
&lt;p&gt;Then came the hard part. Well, I thought it would be easy. The HTTP to XMPP bridge. It turns out the XMPP support in Twisted isn&amp;#8217;t very well documented and slightly underdeveloped. I had to build a couple of prototypes to get the hang of it. Even then, building this module and the &lt;a href=&quot;http://gist.github.com/133361&quot;&gt;XMPP to Growl daemon&lt;/a&gt; took about 7 hours! Compared to the 3 hours spent doing the last two modules. XMPP is definitely a bit hard to really get into.&lt;/p&gt;
&lt;p&gt;By 8am I had all the pieces working. I thought about going the last mile and getting it all online and set up the pipeline &amp;#8230; but I decided I deserved some sleep. I&amp;#8217;d do it when I wake up.&lt;/p&gt;
&lt;h3&gt;Getting the Pipeline in Place&lt;/h3&gt;
&lt;p&gt;When I woke up on Saturday, I was still burnt out from coding. I spent the day &lt;a href=&quot;http://www.flickr.com/photos/progrium/3645570622/&quot;&gt;hanging out with friends&lt;/a&gt;. Then later I invited some more friends over for hacking at my place. There I spent more time than I wanted getting my code to run on my server. Apparently OpenSSL for Python wasn&amp;#8217;t installed and the Google Talk servers required TLS. It took a while to figure this out since no error was raised and Google would just drop my connection.&lt;/p&gt;
&lt;p&gt;I finally got all the infrastructure I built online and tested. Finally, I could work on the actual pipeline. It was supposed to be easy from that point on. And it was! Except for one bit &amp;#8230;&lt;/p&gt;
&lt;p&gt;I got almost all the pieces connected and it all came down to the glue code on Scriptlets. The script would parse the email however I like and set up the message that would end up on my laptop via Growl. It turns out Scriptlets is a bit of a pain to use. No edit, no debugging, crappy error messages. Since I built it as a proof of concept, I hadn&amp;#8217;t done much development on it, let alone with it. Anyway, I learned a lot and have some things to fix. But! I was still able to get everything working!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/progrium/3645697629/in/photostream/&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Adam with my laptop and the Growl notice&quot; src=&quot;http://farm4.static.flickr.com/3625/3645697629_97b7caa5b2.jpg&quot; alt=&quot;&quot; width=&quot;500&quot; height=&quot;375&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I had my friend Adam send the first test email that would go through the entire pipeline I outlined above. He sent it from his phone, just to add a little to the magic. Low and behold, it worked perfectly, quite quickly. It took 4 seconds from him sending to the notice appearing &amp;#8230; but about 3 of those seconds were the time it took for the phone to send the email. Nevertheless, brilliant!&lt;/p&gt;
&lt;h3&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve since found out about &lt;a href=&quot;http://github.com/dustin/wokkel/tree/master&quot;&gt;Wokkel&lt;/a&gt;, which might simplify some of my XMPP code. I have some other enhancements to make to each piece to make them more general. And I mentioned some of the things I need to add to Scriptlets.&lt;/p&gt;
&lt;p&gt;Functionally, the pipeline is pretty good. The only addition I can think of would require an HTTP to IMAP bridge in Protocol Droid (something &lt;a href=&quot;http://github.com/progrium/httpmail/tree/master&quot;&gt;I&amp;#8217;ve already prototyped&lt;/a&gt;). I&amp;#8217;d use this to mark the notification email as unread if it wasn&amp;#8217;t able to deliver the IM. But for now, I think I&amp;#8217;m done on this project. And you can all take advantage of the infrastructure I built out for rigging up your own cool hacks.&lt;/p&gt;
&lt;p&gt;Most of the code this weekend went into these two projects, so check them out!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/progrium/protocol-droid/tree&quot;&gt;Protocol Droid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://gist.github.com/133361&quot;&gt;XMPP to Growl daemon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/40/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/40/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/40/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/40/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/40/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/40/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/40/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/40/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/40/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/40/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=40&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 22 Jun 2009 08:31:01 +0000</pubDate>
</item>
<item>
	<title>Benjamin McGraw: Gruedorf: boards done.</title>
	<guid>http://www.egometry.com/?p=846</guid>
	<link>http://www.egometry.com/gruedorf/gruedorf-boards-done/</link>
	<description>&lt;p&gt;Even though I&amp;#8217;ve been lax in posting, I&amp;#8217;ve been working (when I can) on finishing the &lt;a href=&quot;http://beta.verge-rpg.com&quot;&gt;beta.verge-rpg.com boards&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As of revision 237, the section is good to go for this run-through.  I&amp;#8217;m going to now move on to the file section&lt;/p&gt;</description>
	<pubDate>Mon, 22 Jun 2009 05:45:53 +0000</pubDate>
</item>
<item>
	<title>Chad Austin: IMVU Crash Reporting: Stalls and Deadlocks</title>
	<guid>http://aegisknight.org/?p=1457</guid>
	<link>http://chadaustin.me/2009/06/imvu-crash-reporting-stalls-and-deadlocks/</link>
	<description>&lt;p&gt;By mid-2006, we&amp;#8217;d primarily focused on access violations and unhandled exceptions, the explosive application failures.  After extensive effort, we got our client&amp;#8217;s crash rate down to 2% or so, where 2% of all sessions ended in a crash.&lt;a href=&quot;http://chadaustin.me/2009/06/imvu-crash-reporting-stalls-and-deadlocks/#footnote_session_length&quot;&gt;*&lt;/a&gt;  Still the customers cried &amp;#8220;Fix the crashes!&amp;#8221;&lt;/p&gt;

&lt;p&gt;It turns out that when a customer says &amp;#8220;crash&amp;#8221; they mean &amp;#8220;it stopped doing what I wanted&amp;#8221;, but engineers hear &amp;#8220;the program threw an exception or caused an access violation&amp;#8221;.  Thus, to the customer, crash can mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the application was unresponsive for a period of time&lt;/li&gt;
&lt;li&gt;the UI failed to load, making the client unusable&lt;/li&gt;
&lt;li&gt;the application has been disconnected from the server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, any time the customer cannot make progress and it&amp;#8217;s not (perceived to be) their fault, the application has crashed.&lt;/p&gt;

&lt;p&gt;OK, we&amp;#8217;ve got our work cut out for us&amp;#8230;  Let&amp;#8217;s start by considering deadlocks and stalls.&lt;/p&gt;

&lt;p&gt;First, some terminology: in computer science, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Deadlock &quot;&gt;deadlock&lt;/a&gt; is a situation where two threads or processes are waiting for each other, so neither makes progress.  That definition is a bit academic for our purposes.  Let&amp;#8217;s redefine deadlock as any situation where the program becomes unresponsive for an unreasonable length of time.  This definition includes &lt;a href=&quot;http://en.wikipedia.org/wiki/Livelock&quot;&gt;livelock&lt;/a&gt;, slow operations without progress indication, and network (or disk!) I/O that blocks the program from responding to input.&lt;/p&gt;

&lt;p&gt;It actually doesn&amp;#8217;t matter whether the program will &lt;i&gt;eventually&lt;/i&gt; respond to input.  People get impatient quickly.  You&amp;#8217;ve only got a few seconds to respond to the customer&amp;#8217;s commands.&lt;/p&gt;

&lt;h2&gt;Detecting Deadlocks in C++&lt;/h2&gt;

&lt;p&gt;The embedded programming world has a &amp;#8220;&lt;a href=&quot;http://en.wikipedia.org/wiki/Watchdog_timer&quot;&gt;watchdog timer&lt;/a&gt;&amp;#8221; concept.  Your program is responsible for periodically pinging the watchdog, and if for several seconds you don&amp;#8217;t, the watchdog restarts your program and reports debugging information.&lt;/p&gt;

&lt;p&gt;Implementing this in C++ is straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a watchdog thread that wakes up every few seconds to check that the program is still responding to events.&lt;/li&gt;
&lt;li&gt;Add a heartbeat to your main event loop that frequently pings the watchdog.&lt;/li&gt;
&lt;li&gt;If the watchdog timer detects the program is unresponsive, record stack traces and log files, then report the failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IMVU&amp;#8217;s &lt;a href=&quot;http://aegisknight.org/2009/04/imvus-callstack-api-now-open-source/&quot;&gt;CallStack API&lt;/a&gt; allows us to grab the C++ call stack of an arbitrary thread, so, if the main thread is unresponsive, we report its current stack every couple of seconds.  This is often all that&amp;#8217;s needed to find and fix the deadlock.&lt;/p&gt;

&lt;h2&gt;Detecting Deadlocks in Python&lt;/h2&gt;

&lt;p&gt;In Python, we can take the same approach as above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start a watchdog thread.&lt;/li&gt;
&lt;li&gt;Ping the Python watchdog thread in your main loop.&lt;/li&gt;
&lt;li&gt;If the watchdog detects that you&amp;#8217;re unresponsive, record the main thread&amp;#8217;s Python stack (this time with &lt;a href=&quot;http://docs.python.org/library/sys.html#sys._current_frames&quot;&gt;sys._current_frames&lt;/a&gt;) and report it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Python&amp;#8217;s &lt;a href=&quot;http://docs.python.org/dev/glossary.html#term-global-interpreter-lock&quot;&gt;global interpreter lock&lt;/a&gt; (GIL) can throw a wrench in this plan.  If one thread enters an infinite loop while keeping the GIL held (say, in a native extension), the watchdog thread will never wake and so cannot report a deadlock.  In practice, this isn&amp;#8217;t a problem, because the C++ deadlock detector will notice and report a deadlock.  Plus, most common deadlocks are caused by calls that release the GIL: &lt;code&gt;threading.Lock.acquire&lt;/code&gt;, &lt;code&gt;socket.read&lt;/code&gt;, &lt;code&gt;file.read&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;It might help to think of the Python deadlock detector as a fallback that, if successful, adds richer information to your deadlock reports.  If it failed, whatever.  The C++ deadlock detector is probably enough to diagnose and fix the problem.&lt;/p&gt;

&lt;h2&gt;What did we learn?&lt;/h2&gt;

&lt;p&gt;It turned out the IMVU client had several bugs where we blocked the main thread on the network, sometimes for up to 30 seconds.  By that point, most users just clicked the close box [X] and terminated the process.  Oops.&lt;/p&gt;

&lt;p&gt;In addition, the deadlock detectors pointed out places where we were doing too much work in between message pumps.  For example, loading some assets into the 3D scene might nominally take 200ms.  On a computer with 256 MB of RAM, though, the system might start thrashing and loading the same assets would take 5s and report as a &amp;#8220;deadlock&amp;#8221;.  The solution was to reducing the program&amp;#8217;s working set and bite off smaller chunks of work in between pumps.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t recall seeing many &amp;#8220;computer science&amp;#8221; deadlocks, but these watchdogs were invaluable in tracking down important failure conditions in the IMVU client.&lt;/p&gt;

&lt;p&gt;Next time, we&amp;#8217;ll improve the accuracy of our crash metrics and answer the question &amp;#8220;How do you know your metrics are valid?&amp;#8221;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a id=&quot;footnote_session_length&quot;&gt;*&lt;/a&gt; Median session length is a more useful reliability metric.  It&amp;#8217;s possible to fix crashes and see no change in your percentage of failed sessions, if fixing crashes simply causes sessions to become longer.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/chadaustin/~4/aGQJcaBlKPM&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Thu, 18 Jun 2009 06:52:38 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: progrium</title>
	<guid>http://blogrium.wordpress.com/?p=35</guid>
	<link>http://blogrium.wordpress.com/2009/06/17/oh-no-hackers/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;That&amp;#8217;s right. Hide your floppies and cover your Ethernet ports. Virus-laden hackers are coming to take over your computer, steal your passwords, and do terrible things! Like hack your MySpace! Oh noes!&lt;/p&gt;
&lt;p&gt;I guess I&amp;#8217;m getting over the fact that we probably won&amp;#8217;t be able to undo the damage done with the public&amp;#8217;s perception of what a &amp;#8220;hacker&amp;#8221; is. Perhaps, though, we can overload it to the point of ambiguity, so there&amp;#8217;s at least some question of context whether it&amp;#8217;s the good kind or the bad kind.&lt;/p&gt;
&lt;p&gt;The problem is that positive connotations aren&amp;#8217;t enough. The people that would venture to understand &amp;#8220;hackers&amp;#8221; the slightest bit more than what they hear in the headlines are going to pretty quickly find the &amp;#8220;good hackers&amp;#8221; &amp;#8230; they&amp;#8217;re white hats, right?&lt;/p&gt;
&lt;p&gt;The other day I was questioned by somebody (that should know better) if I hacked somebody&amp;#8217;s website that was recently compromised. Seriously? My response was &amp;#8220;I barely have enough time to do important things, let alone something that would be a waste of my time.&amp;#8221;&lt;/p&gt;
&lt;p&gt;I self-identify as a hacker. I invite my friends over to &amp;#8220;hack.&amp;#8221; I started a party for &amp;#8220;hackers and thinkers&amp;#8221; (a very intentional choice of words). I&amp;#8217;m co-founding a community center called Hacker Dojo. What are we doing at all these functions? Building and learning.&lt;/p&gt;
&lt;p&gt;We use the term perhaps too liberally, but always implying tribute to the true hackers that, as Steven Levy put it, &amp;#8220;regard computing as the most important thing in the world.&amp;#8221;&lt;/p&gt;
&lt;p&gt;These people push the envelope of what&amp;#8217;s possible through hands-on exploration, driven by relentless curiosity and a desire to challenge the status quo. Steve Wozniak, Lee Felsenstein, Linus Torvalds, Tim Berners-Lee, John Carmack &amp;#8230;&lt;/p&gt;
&lt;p&gt;Hell, there&amp;#8217;s something big behind this idea, why stop at computing? Buckminster Fuller, Nikola Tesla, Richard Feynman, Alfred Kinsey, Ben Franklin &amp;#8230;&lt;/p&gt;
&lt;p&gt;Perhaps we&amp;#8217;re generalizing too far. Perhaps we&amp;#8217;re rendering &amp;#8220;hacker&amp;#8221; meaningless. Or are we giving it more meaning? Getting down to its essence. I wouldn&amp;#8217;t be defending this idea so strongly if I didn&amp;#8217;t think it had some great significance to humanity.&lt;/p&gt;
&lt;p&gt;What upsets me is that many who would identify as hackers in this sense seem to be afraid to claim it. Most likely in fear of confusing the layman that has the media&amp;#8217;s myopic view of hackers. You&amp;#8217;ve never heard of the canonical conference for real hackers. No, it&amp;#8217;s not DefCon. (Just get up and leave.) It&amp;#8217;s a conference called Hackers. You&amp;#8217;ve never heard of it because they keep it secret!&lt;/p&gt;
&lt;p&gt;This conference was started to gather everybody together that was mentioned in Steven Levy&amp;#8217;s book &lt;a href=&quot;http://www.amazon.com/Hackers-Computer-Revolution-Steven-Levy/dp/0141000511/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1245307316&amp;amp;sr=8-2&quot;&gt;Hackers: Heroes of the Computer Revolution&lt;/a&gt; (one of the last good publication on hackers, and it came out in 1984!). This conference holds all the values of true hackerism and it&amp;#8217;s been happening for 25 years. But they won&amp;#8217;t promote it! It goes by a fake name and even has all mentions of &amp;#8220;hacker&amp;#8221; on their website replaced with an image so it won&amp;#8217;t be indexed. Seriously??&lt;/p&gt;
&lt;p&gt;Trying to supplant public perception of hackers by just saying they&amp;#8217;re something different and providing a better name nobody uses (&amp;#8221;crackers&amp;#8221;) is not going to work. It hasn&amp;#8217;t worked. They need something to replace those visions of crackers with. We need tangible examples and stories. We need heroes. Heroes willing to wear the title.&lt;/p&gt;
&lt;p&gt;Luckily, we have a new generation of hackers. One that has started a global movement called &lt;a href=&quot;http://hackerspaces.org&quot;&gt;hackerspaces&lt;/a&gt;, probably one of the biggest things for hackers in years. Our local hackerscene fostered by Silicon Valley culture and events like &lt;a href=&quot;http://superhappydevhouse.org&quot;&gt;SuperHappyDevHouse&lt;/a&gt; have led to a hackerspace we hope will have a big impact. One that proudly wears the name hacker: &lt;a href=&quot;http://hackerdojo.com&quot;&gt;Hacker Dojo&lt;/a&gt;.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/35/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/35/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/35/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/35/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/35/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/35/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/35/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/35/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/35/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/35/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=35&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Thu, 18 Jun 2009 06:35:23 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Tweet in PostBin</title>
	<guid>http://blogrium.wordpress.com/?p=24</guid>
	<link>http://blogrium.wordpress.com/2009/06/15/twitter-hooks/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;When I first gave a public &lt;a href=&quot;http://flickr.com/photos/jessicamarrone/485946482/&quot;&gt;talk on webhooks&lt;/a&gt; in 2007, the guys at Twitter were the first ones to come up to me saying they wanted to implement them. Unfortunately it never happened, and this was well before they were as popular as they are now. It wouldn&amp;#8217;t scale, they said.&lt;/p&gt;
&lt;p&gt;As an alternative, just a few months ago, they released a stream API using long-running HTTP. It not only included a firehose stream, but a stream that allowed you to pull updates from selected users. I knew immediately from this I could build a webhook transformer, effectively giving Twitter webhooks. Unfortunately, the stream for selected users was behind a EULA that prevented that use of their API. Something about not redistributing data.&lt;/p&gt;
&lt;p&gt;Then a few weeks ago, they added a selective stream that was publicly available. I had already designed the system and started writing some code before when I found out about the EULA. It took me a while to find some time, but last night and today I did it. I finished a proof of concept service called &lt;a href=&quot;http://www.twitterhooks.com&quot;&gt;Twitter Hooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;size-full wp-image-26 aligncenter&quot; title=&quot;Twitter Hooks&quot; src=&quot;http://blogrium.files.wordpress.com/2009/06/picture-1.png?w=418&amp;#038;h=248&quot; alt=&quot;Twitter Hooks&quot; width=&quot;418&quot; height=&quot;248&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s very simple and is mostly about the plumbing behind it. You sign in with your Twitter account using OAuth, then you just give it a callback URL. Behind the scenes, it has a stream consumer listening for updates from the users that have a callback URL. When it gets an update from you, it posts it to your callback URL.&lt;/p&gt;
&lt;p&gt;Obviously, there is only so much you can do with your own tweets. The next step is to listen to updates from your friends and post them to your callback URL. After that, using some trickery not involving the stream API, it will post direct messages and new followers to your URL. Throw in keyword tracking, and you have hooks for almost every significant event in Twitter. &lt;a href=&quot;http://jhherren.wordpress.com/2009/03/05/twitter-and-the-case-for-web-hooks/&quot;&gt;John Herren&lt;/a&gt; would be proud.&lt;/p&gt;
&lt;p&gt;The problem is&amp;#8230; Twitter is still too limiting with their stream API. As it stands, the non-EULA stream only allows following 200 users. That means Twitter Hooks can only support 200 users. It also means there&amp;#8217;s no way we can roll out the friend update hook because some people have over 200 friends by themselves. Until that&amp;#8217;s resolved, Twitter Hooks will remain a proof of concept demo.&lt;/p&gt;
&lt;p&gt;But I have to say, having this is pretty sweet. The stream API is about as real-time as you can get. While experimenting, I was getting updates from the stream quicker than the page reload from posting a new tweet. This is, of course, then posted to your URL immediately for you to do whatever you want with. Here&amp;#8217;s a tweet of mine posted to &lt;a href=&quot;http://www.postbin.org&quot;&gt;PostBin&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;size-full wp-image-28 aligncenter&quot; title=&quot;Tweet in PostBin&quot; src=&quot;http://blogrium.files.wordpress.com/2009/06/picture-2.png?w=418&amp;#038;h=170&quot; alt=&quot;Tweet in PostBin&quot; width=&quot;418&quot; height=&quot;170&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you want to play with Twitter Hooks, it&amp;#8217;s currently limited to users I authorize since it can only have 200 users and it&amp;#8217;s terribly early/rough. Just @ me on Twitter and I can get you set up.&lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/blogrium.wordpress.com/24/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/blogrium.wordpress.com/24/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/blogrium.wordpress.com/24/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/blogrium.wordpress.com/24/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/blogrium.wordpress.com/24/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/blogrium.wordpress.com/24/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/blogrium.wordpress.com/24/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/blogrium.wordpress.com/24/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/blogrium.wordpress.com/24/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/blogrium.wordpress.com/24/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blogrium.wordpress.com&amp;amp;blog=447831&amp;amp;post=24&amp;amp;subd=blogrium&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 15 Jun 2009 09:48:51 +0000</pubDate>
</item>
<item>
	<title>Jeff Lindsay: Convention for batching</title>
	<guid>http://blog.webhooks.org/?p=189</guid>
	<link>http://blog.webhooks.org/2009/06/14/convention-for-batching/</link>
	<description>&lt;div class=&quot;snap_preview&quot;&gt;&lt;br /&gt;&lt;p&gt;Last month I talked about webhooks at &lt;a href=&quot;http://gluecon.com/&quot;&gt;Glue&lt;/a&gt;, a new conference on the &amp;#8220;glue&amp;#8221; of the web. One of the other speakers was &lt;a href=&quot;http://twitter.com/joshelman&quot;&gt;Josh Elman&lt;/a&gt; of the Facebook Platform team. I ended up on the flight back with him, so we talked about webhooks. He seemed excited about them as a fan of the callback/hooking pattern in classical programming. In fact, he mentioned how they were experimenting with them already for notifications within the Facebook Platform, but he brought up the issue of batching. Something I hadn&amp;#8217;t thought of before, but is important for large-scale implementations that are likely to be posting a lot of events to a target endpoint.&lt;/p&gt;
&lt;p&gt;Later, when I read about Google Wave, and how they &lt;a href=&quot;http://code.google.com/apis/wave/extensions/robots/index.html&quot;&gt;use webhooks in their API for creating bots&lt;/a&gt;, they mentioned that they may batch events. I&amp;#8217;ve yet to crack open my Google Wave developer account and play with their implementation, but I&amp;#8217;ve since realized a very simple convention for batching: JSON lists as the outer structure.&lt;/p&gt;
&lt;p&gt;This works because an event object is ALWAYS going to be a key/pair object. So receiving code just has to check if the payload JSON is an array or an object. If it&amp;#8217;s an array, handle each object inside as separate events. If it&amp;#8217;s an object, handle as you would.&lt;/p&gt;
&lt;p&gt;This doesn&amp;#8217;t work for POST variables, since it&amp;#8217;s very difficult to do arrays in general, but particularly as the outer data structure. It&amp;#8217;s just not made to be able to do that. So this would require you to use at least JSON. It works in XML as well, but because there&amp;#8217;s more variety in XML payloads, it&amp;#8217;s probably harder to settle on such a simple convention as this. &lt;/p&gt;
&lt;p&gt;Let me know what you think. Or if any of you already know how Google Wave batches events in their Robot API. &lt;/p&gt;
  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/webhooks.wordpress.com/189/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/webhooks.wordpress.com/189/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/webhooks.wordpress.com/189/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/webhooks.wordpress.com/189/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/webhooks.wordpress.com/189/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/webhooks.wordpress.com/189/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/webhooks.wordpress.com/189/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/webhooks.wordpress.com/189/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/webhooks.wordpress.com/189/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/webhooks.wordpress.com/189/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=blog.webhooks.org&amp;amp;blog=5379000&amp;amp;post=189&amp;amp;subd=webhooks&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 14 Jun 2009 18:55:06 +0000</pubDate>
</item>

</channel>
</rss>
