<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description /><title>tom robinson</title><generator>Tumblr (3.0; @tlrobinson)</generator><link>http://blog.tlrobinson.net/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/tlrobinson" /><feedburner:info uri="tlrobinson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>Video</title><description>&lt;span id="video_player_11703728024"&gt;[&lt;a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" target="_blank"&gt;Flash 10&lt;/a&gt; is required to watch video.]&lt;/span&gt;&lt;script type="text/javascript"&gt;renderVideo("video_player_11703728024",'http://blog.tlrobinson.net/video_file/11703728024/tumblr_ltdt9eLlAZ1qaiucj',400,225,'poster=http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_ltdt9eLlAZ1qaiucj_r1_frame1.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_ltdt9eLlAZ1qaiucj_r1_frame2.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_ltdt9eLlAZ1qaiucj_r1_frame3.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_ltdt9eLlAZ1qaiucj_r1_frame4.jpg,http%3A%2F%2Fmedia.tumblr.com%2Ftumblr_ltdt9eLlAZ1qaiucj_r1_frame5.jpg')&lt;/script&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/bgRJboLG2rI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/bgRJboLG2rI/11703728024</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/11703728024</guid><pubDate>Thu, 20 Oct 2011 13:36:50 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/11703728024</feedburner:origLink></item><item><title>Luke, I am your recruiter.</title><description>&lt;embed type="application/x-shockwave-flash" src="http://assets.tumblr.com/swf/audio_player_black.swf?audio_file=http://www.tumblr.com/audio_file/11097351984/tumblr_lsn5pnoS7a1qaiucj&amp;color=FFFFFF&amp;logo=soundcloud" height="27" width="207" quality="best" wmode="opaque"&gt;&lt;/embed&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Luke, I am your recruiter.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/5LZ26Q8u1Do" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/5LZ26Q8u1Do/11097351984</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/11097351984</guid><pubDate>Thu, 06 Oct 2011 04:10:00 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/11097351984</feedburner:origLink></item><item><title>Dale Carnegie doesn't understand thermodynamics</title><description>&lt;p&gt;Pretty sure you can&amp;#8217;t add temperatures like this&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“‘Well, now look, Mr. Smith,’ I said. ‘I agree with you a hundred percent; if those motors are running too hot, you ought not to buy any more of them. You must have motors that won’t run any hotter than standards set by the National Electrical Manufacturers Association. Isn’t that so?’&lt;/p&gt;
&lt;p&gt;“He agreed it was. I had gotten my first ‘yes.’ &lt;/p&gt;
&lt;p&gt;“‘The Electrical Manufacturers Association regulations say that a properly designed motor may have a temperature of 72 degrees Fahrenheit above room temperature. Is that correct?’&lt;/p&gt;
&lt;p&gt;“‘Yes,’ he agreed. ‘That’s quite correct. But your motors are much hotter.’ &lt;/p&gt;
&lt;p&gt;“I didn’t argue with him. I merely asked, ‘How hot is the mill room?’&lt;/p&gt;
&lt;p&gt;“‘Oh,’ he said, ‘about 75 degrees Fahrenheit.’ &lt;/p&gt;
&lt;p&gt;“‘Well,’ I replied, ‘if the mill room is 75 degrees and you add 72 to that, that makes a total of 147 degrees Fahrenheit. Wouldn’t you scald your hand if you held it under a spigot of hot water at a temperature of &lt;/p&gt;
&lt;p&gt;147 degrees Fahrenheit?’ &lt;/p&gt;
&lt;p&gt;“Again he had to say ‘yes.’ &lt;/p&gt;
&lt;p&gt;“‘Well,’ I suggested, ‘wouldn’t it he a good idea to keep your hands off those motors?’&lt;/p&gt;
&lt;p&gt;“‘Well, I guess you’re right,’ he admitted. We continued to chat for a while. Then he called his secretary and lined up approximately $35,000 worth of business for the ensuing month.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/How_to_Win_Friends_and_Influence_People"&gt;How to Win Friends and Influence People&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/141RTVS_mdI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/141RTVS_mdI/8768983066</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/8768983066</guid><pubDate>Wed, 10 Aug 2011 23:05:01 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/8768983066</feedburner:origLink></item><item><title>Remap Caps Lock to "Search" on OS X (Google Cr-48 style)</title><description>&lt;p&gt;One of the more intriguing features of Google&amp;#8217;s new Cr-48 Chrome OS laptop is the lack of replacement of the caps lock key with a search key. I wanted to try this on my Mac. Here&amp;#8217;s my hacky solution:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Install &lt;a href="http://pqrs.org/macosx/keyremap4macbook/extra.html"&gt;PCKeyboardHack&lt;/a&gt; to remap caps-lock to an unused key, for example one of the function keys (F1 is keycode 122 on my keyboard)&lt;/li&gt;
&lt;li&gt;Create an AppleScript to open a new tab in Chrome (or your browser of choice). Here&amp;#8217;s an &lt;a href="https://gist.github.com/740079"&gt;example AppleScript&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Assign the previously chosen key to this service. Unfortunately &lt;a href="http://airbladesoftware.com/notes/binding-osx-services-to-function-keys"&gt;OS X prevents you from assigning function keys to services directly&lt;/a&gt;. You can either create a Application Shortcut with the same name as the service (put the script in ~/Library/Services) in the Keyboard Shortcuts panel of the Keyboard pref pane, or you can use &lt;a href="http://www.red-sweater.com/fastscripts/"&gt;FastScripts&lt;/a&gt; (I had better luck with the latter)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Unfortunately there&amp;#8217;s some lag compared to simply hitting &amp;#8220;command-T&amp;#8221;. &lt;em&gt;Edit: saving the AppleScript as a script rather than an Automator action improved the lag considerably.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you have a better way of doing this please &lt;a href="http://twitter.com/tlrobinson/"&gt;send it my way&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="http://twitter.com/MSch/status/14534314003800064"&gt;@MSch&lt;/a&gt; for the PCKeyboardHack suggestion, and &lt;a href="http://twitter.com/ryannielsen/status/14553317011099648"&gt;@ryannielsen&lt;/a&gt; pointing me to FastScripts.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/I9HhHLEeNck" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/I9HhHLEeNck/2310125203</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/2310125203</guid><pubDate>Mon, 13 Dec 2010 22:41:00 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/2310125203</feedburner:origLink></item><item><title>Kindle 3</title><description>&lt;p&gt;When the iPad was announced I assumed it would eat the Kindle for lunch. After all, it had a large color touch screen and could do much more than just read books, right? Well, yes, but it turns out to be not very good at the one thing a tablet form factor is perfect for: reading.&lt;/p&gt;
&lt;p&gt;I finally picked up a Kindle 3 after reading &lt;a href="http://paulstamatiou.com/review-amazon-kindle-3-wi-fi-reading-device"&gt;Paul Stamatiou&amp;#8217;s great review&lt;/a&gt;. Here are my thoughts after a few weeks of nearly daily use with it.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Kindle does one thing, and one thing well: reading. iPad does a bunch of things mediocrely.&lt;/li&gt;
&lt;li&gt;Extremely readable display.&lt;/li&gt;
&lt;li&gt;Lightweight and easy to hold. Not awkward to hold at any angle. No fumbling with folding the pages over trying to find a comfortable grip. This makes reading more enjoyable.&lt;/li&gt;
&lt;li&gt;Carry many books with you. No upfront decision on which book to bring on a trip. Read whatever you&amp;#8217;re in the mood for. This is also a downside, as I find myself buying new books before finishing the ones I&amp;#8217;ve already started. Currently I have 5 unread books on my Kindle.&lt;/li&gt;
&lt;li&gt;Satisfying mechanical click when going to the next page. No gratuitous virtual page flipping animation.&lt;/li&gt;
&lt;li&gt;I find I&amp;#8217;ve been reading much more than I used too. I never read books daily before, but I do now.&lt;/li&gt;
&lt;li&gt;The built-in dictionary is useful, as is the highlighter feature (iPad has both of these features)&lt;/li&gt;
&lt;li&gt;Amazon now has access to lots of interesting data. So far they&amp;#8217;ve only given us access to popular highlighted excerpts. Two things I&amp;#8217;d like to see are the average time it takes to read a given book, and my personal words-per-minute rate. A speed-reading training mode would be neat too.&lt;/li&gt;
&lt;li&gt;Excellent battery life&amp;#8230; if you turn off wireless. iPad&amp;#8217;s battery life isn&amp;#8217;t bad compared to a laptop, but Kindle will last a &lt;em&gt;long&lt;/em&gt; time. It died after a few days of heavy use with the wireless turned on, but then I turned off wireless and it hasn&amp;#8217;t run out of juice yet.&lt;/li&gt;
&lt;li&gt;Fewer distractions than iPad. With so many apps and websites just a button press away I found I had a hard time focusing on reading on the iPad. Not so on Kindle. While Kindle does have an &amp;#8220;experimental&amp;#8221; web browser (WebKit based) it&amp;#8217;s not very useful, so I don&amp;#8217;t find it distracting.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;After several months of frustration trying to use the iPad as a travel computer I&amp;#8217;ve given up. For now I&amp;#8217;ll be sticking with a MacBook plus a Kindle and recommend anyone who does serious work on their computer do the same.&lt;/p&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/CnoYGTUZnJ8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/CnoYGTUZnJ8/1454822868</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/1454822868</guid><pubDate>Mon, 01 Nov 2010 11:46:14 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/1454822868</feedburner:origLink></item><item><title>Fucking telemarketers</title><description>&lt;p&gt;&lt;strong&gt;Telemarketer&lt;/strong&gt;: Hi. I&amp;#8217;m calling today about your credit ca-&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: &lt;em&gt;[suspecting it&amp;#8217;s a telemarketer]&lt;/em&gt; Is this about a credit card I already have?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Telemarketer&lt;/strong&gt;: Yes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: Oh ok. Which one?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Telemarketer&lt;/strong&gt;: All of them, sir.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: &lt;em&gt;[click]&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/8U7aII7PH20" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/8U7aII7PH20/975481966</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/975481966</guid><pubDate>Wed, 18 Aug 2010 21:17:00 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/975481966</feedburner:origLink></item><item><title>Installation log, iPhone edition</title><description>&lt;p&gt;Following up on my &lt;a href="http://blog.tlrobinson.net/post/360281269/installation-log"&gt;desktop installation log&lt;/a&gt;, I&amp;#8217;ve declared iPhone app bankruptcy and will be posting the apps I install on my fresh iPhone 4.

&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Twitter - formerly Tweetie 2&lt;/li&gt;
&lt;li&gt;FourSquare - social location thing of choice&lt;/li&gt;
&lt;li&gt;Facebook - most popular iPhone app&lt;/li&gt;
&lt;li&gt;Meebo - multiple IM client with push notifications&lt;/li&gt;
&lt;li&gt;Skype - cheap international calls + for when AT&amp;amp;T sucks but WiFi is available&lt;/li&gt;
&lt;li&gt;Pandora - Internet radio that&amp;#8217;s actually useful thanks to iOS 4&amp;#8217;s background apps&lt;/li&gt;
&lt;li&gt;Boxcar and Prowl - various push notifications (Twitter, Facebook, email)&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/8lMrH9vquDU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/8lMrH9vquDU/828026330</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/828026330</guid><pubDate>Sun, 18 Jul 2010 08:03:50 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/828026330</feedburner:origLink></item><item><title>Video</title><description>&lt;iframe width="400" height="225" src="http://www.youtube.com/embed/69aNhA6wJlM?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/EhHuXQi9KEY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/EhHuXQi9KEY/391148985</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/391148985</guid><pubDate>Mon, 15 Feb 2010 10:37:28 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/391148985</feedburner:origLink></item><item><title>Installation log.</title><description>&lt;p&gt;To keep myself from installing too much crap on my freshly formatted system I&amp;#8217;m keeping a log of what I&amp;#8217;ve installed and why:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edit: I&amp;#8217;ve struck out a few applications I decided I didn&amp;#8217;t need/like&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://build.chromium.org/buildbot/snapshots/chromium-rel-mac/"&gt;Chromium&lt;/a&gt; - latest builds of Chrome, includes Chrome extensions on OS X.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nightly.webkit.org/"&gt;WebKit Nightly Build&lt;/a&gt; - latest builds of WebKit for Safari.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.irradiatedsoftware.com/cinch/"&gt;Cinch&lt;/a&gt; - Windows 7 &lt;em&gt;[gasp]&lt;/em&gt; style window manager enhancement.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; - text editor of choice.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dropbox.com/"&gt;Dropbox&lt;/a&gt; - the best cloud storage/backup service.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.atebits.com/tweetie-mac/"&gt;Tweetie&lt;/a&gt; - the only not crappy Twitter client for OS X.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://adium.im/"&gt;Adium&lt;/a&gt; - multi-protocol IM client.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://colloquy.info/"&gt;Colloquy&lt;/a&gt; - IRC client.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.utorrent.com/"&gt;uTorrent&lt;/a&gt; - a slim torrent client.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/"&gt;Xcode&lt;/a&gt; - developer tools.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/mxcl/homebrew"&gt;Homebrew&lt;/a&gt; - package manager for OS X. In the past I&amp;#8217;ve used MacPorts, but I hear good things about Homebrew so I&amp;#8217;m giving it a try.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/git-osx-installer/"&gt;git&lt;/a&gt; - version control of choice.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.levien.com/type/myfonts/inconsolata.html"&gt;Inconsolata&lt;/a&gt; - programming / terminal font.&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;a href="http://www.griffintechnology.com/software/"&gt;PowerMate driver&lt;/a&gt; - what can I say, I love shiny knobs.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.videolan.org/"&gt;VLC&lt;/a&gt; - video player that can play just about any format.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tapbots.com/software/pastebot/"&gt;Pastebot Sync&lt;/a&gt; - copy/paste between Mac and iPhone.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt; - free virtualization software for running Windows, Linux, etc.&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;a href="http://www.apple.com/quicktime/broadcaster/"&gt;QuickTime Broadcaster&lt;/a&gt; - for &lt;a href="http://tlrobinson.net/projects/haightcam"&gt;HaightCam&lt;/a&gt; on &lt;a href="http://justin.tv/"&gt;Justin.tv&lt;/a&gt;.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.panic.com/TRANSMIT/"&gt;Transmit&lt;/a&gt; - best FTP/SFTP/S3 client.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.macruby.org/"&gt;MacRuby&lt;/a&gt; - Ruby implementation on Objective-C runtime.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pixelglow.com/graphviz/"&gt;GraphViz&lt;/a&gt; - graph layout tools.&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;a href="http://refit.sourceforge.net/"&gt;rEFIt&lt;/a&gt; - boot menu for dual booting.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ciaranwal.sh/projectplus"&gt;ProjectPlus&lt;/a&gt; - various TextMate enhancements (version control, sidebar)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://macrabbit.com/cssedit/"&gt;CSSEdit&lt;/a&gt; - nice CSS editor.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.charlesproxy.com/"&gt;Charles&lt;/a&gt; - web debugging proxy.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.omnigroup.com/products/omnigraffle/"&gt;OmniGraffle&lt;/a&gt; - diagramming tool.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fluidapp.com/"&gt;Fluid&lt;/a&gt; - site specific browser (currently used for &lt;a href="http://pivotaltracker.com/"&gt;Pivotal Tracker&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ridiculousfish.com/hexfiend/"&gt;Hex Fiend&lt;/a&gt; - a hex editor&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;a href="http://visor.binaryage.com/"&gt;Visor&lt;/a&gt; (and &lt;a href="http://www.culater.net/software/SIMBL/SIMBL.php"&gt;SIMBL&lt;/a&gt;) - hot-key accessible terminal. Plus pretty terminal colors.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sequelpro.com/"&gt;Sequel Pro&lt;/a&gt; - MySQL admin interface&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kaleidoscopeapp.com/"&gt;Kaleidoscope&lt;/a&gt; - A beautiful diff-ing tool made by Sofa.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.getcloudapp.com/"&gt;CloudApp&lt;/a&gt; - share images, links, etc on the web&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;&lt;a href="http://www.alfredapp.com/"&gt;Alfred&lt;/a&gt; - quick launcher &lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://embercode.com/tvshows/"&gt;TVShows&lt;/a&gt; - downloads TV shows torrents automatically&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/3qeqvsz9zzg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/3qeqvsz9zzg/360281269</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/360281269</guid><pubDate>Fri, 29 Jan 2010 15:06:00 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/360281269</feedburner:origLink></item><item><title>CommonJS/JSGI: The Emerging JavaScript Application Server Platform</title><description>&lt;a href="http://www.sitepen.com/blog/2010/01/19/commonjsjsgi-the-emerging-javascript-application-server-platform/"&gt;CommonJS/JSGI: The Emerging JavaScript Application Server Platform&lt;/a&gt;: &lt;p&gt;A nice summary of the state of affairs of server-side JavaScript by Kris Zyp.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/ESw9x27xCUs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/ESw9x27xCUs/344754919</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/344754919</guid><pubDate>Wed, 20 Jan 2010 12:53:49 -0800</pubDate><category>ssjs</category><category>commonjs</category><category>jsgi</category><category>narwhal</category><feedburner:origLink>http://blog.tlrobinson.net/post/344754919</feedburner:origLink></item><item><title>Hello world, again!</title><description>&lt;p&gt;Along with my &lt;a href="http://tlrobinson.net/"&gt;new personal website&lt;/a&gt;, I’m starting a new blog, located at &lt;a href="http://blog.tlrobinson.net"&gt;&lt;a href="http://blog.tlrobinson.net"&gt;http://blog.tlrobinson.net&lt;/a&gt;&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/0PCbRmgpC4M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/0PCbRmgpC4M/336763758</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336763758</guid><pubDate>Fri, 15 Jan 2010 19:36:00 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336763758</feedburner:origLink></item><item><title>Using OLPC XO as an ebook reader for O'Reilly's Safari Books Online</title><description>&lt;p&gt;A year ago I received an &lt;a href="http://laptop.org/"&gt;OLPC&lt;/a&gt; XO (the “$100 laptop”) through their Give One Get One program. I played with it for a few days and found it essentially useless due to unstable and slow software (and lack of WPA support), so it quickly began gathering dust on a shelf (it has since improved).&lt;/p&gt;

&lt;p&gt;Last week I was thinking about how &lt;a href="http://www.amazon.com/Kindle-Safari-Online-Access-Support/forum/FxBVKST06PWP9B/Tx13VFZZSWRC994/1?_encoding=UTF8&amp;amp;asin=B000FI73MA"&gt;cool it would be&lt;/a&gt; if &lt;a href="http://amazon.com/kindle"&gt;Amazon’s Kindle&lt;/a&gt; supported &lt;a href="http://www.safaribooksonline.com/"&gt;O’Reilly’s Safari Books Online&lt;/a&gt; service, and I decided to dust off the XO to see if it could be used as an ebook reader for Safari Books. With a little help, it can.&lt;/p&gt;

&lt;p&gt;In ebook mode you can scroll in all four directions, page up/down, and jump to the top or bottom of a page, but you cannot click the next/previous buttons within Safari Books. However, GreaseMonkey and a simple userscript can solve that.&lt;/p&gt;

&lt;p&gt;The first step is to install the &lt;a href="http://wiki.laptop.org/go/Activities/All#General_Search_and_Discovery"&gt;Firefox “Activity”&lt;/a&gt;, or a &lt;a href="http://www.olpcnews.com/forum/index.php?topic=4053.0l"&gt;version of Linux&lt;/a&gt; that runs a stock Firefox. Then install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;GreaseMonkey&lt;/a&gt;. Finally, install this userscript:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://tlrobinson.net/userscripts/xo-safari.user.js"&gt;&lt;/a&gt;&lt;a href="http://tlrobinson.net/userscripts/xo-safari.user.js"&gt;&lt;a href="http://tlrobinson.net/userscripts/xo-safari.user.js"&gt;http://tlrobinson.net/userscripts/xo-safari.user.js&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple userscript intercepts page up and page down (the “O” and “X” game pad) buttons and maps them to “previous” and “next” actions in Safari Books, allowing you to easily switch pages in ebook mode.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/iBeju-Dx9HM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/iBeju-Dx9HM/336828945</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336828945</guid><pubDate>Sun, 05 Apr 2009 22:37:15 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336828945</feedburner:origLink></item><item><title>ropen: Remote "open" command for opening remote files locally on OS X</title><description>&lt;p&gt;The Problem&lt;br/&gt;
—————-&lt;/p&gt;

&lt;p&gt;Most Mac OS X power users know about the [“open”](&lt;a href="http://tuvix.apple.com/documentation/Darwin/Reference/ManPages/man1/open.1.html"&gt;&lt;a href="http://tuvix.apple.com/documentation/Darwin/Reference/ManPages/man1/open.1.html"&gt;http://tuvix.apple.com/documentation/Darwin/Reference/ManPages/man1/open.1.html&lt;/a&gt;&lt;/a&gt;) command line tool which opens the files specified as arguments in their default (or a specified) OS X application. Additionally, many OS X text editors, such as TextMate (“mate”) and SubEthaEdit (“see”), come with command line tools which can be used to open files.&lt;/p&gt;

&lt;p&gt;These are great when working locally, but obviously do no work remotely. Often when working on remote servers you end up using command line editors which you may not be as familiar with.&lt;/p&gt;

&lt;p&gt;ropen’s Solution&lt;br/&gt;
————————&lt;/p&gt;

&lt;p&gt;The [ropen](&lt;a href="http://github.com/tlrobinson/ropen"&gt;&lt;a href="http://github.com/tlrobinson/ropen"&gt;http://github.com/tlrobinson/ropen&lt;/a&gt;&lt;/a&gt;) tool solves this problem using two simple shell scripts, which make use of MacFuse’s sshfs. You run the “ropen” program on your remote machine(s) when you want to open a remote file locally (this is equivalent to the OS X “open” command). The “ropend” daemon runs on your local OS X machine waiting for open requests, and the “ropen.php” PHP script proxies requests from ropen to ropend.&lt;/p&gt;

&lt;p&gt;How it works&lt;br/&gt;
——————&lt;/p&gt;

&lt;p&gt;1. When ropen is executed it makes an HTTP request to ropen.php with the paths to be opened and application to open them with, if any, as well as the SSH user, host, and port of the remote machine.&lt;br/&gt;
2. ropen.php stores this open request in a queue that is tied to ROPEN_SECRET via PHP’s sessions.&lt;br/&gt;
3. ropend polls ropen.php every 1 second waiting for open requests. When it receives one it mounts the remote filesystem using sshfs (if it’s not already mounted) and opens the files or directories specified.&lt;/p&gt;

&lt;p&gt;More information&lt;br/&gt;
——————&lt;/p&gt;

&lt;p&gt;See more information about ropen on the [ropen project page](&lt;a href="http://github.com/tlrobinson/ropen"&gt;&lt;a href="http://github.com/tlrobinson/ropen"&gt;http://github.com/tlrobinson/ropen&lt;/a&gt;&lt;/a&gt;).&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/I6UcXZ-G4GQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/I6UcXZ-G4GQ/336828638</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336828638</guid><pubDate>Sat, 04 Apr 2009 18:40:15 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336828638</feedburner:origLink></item><item><title>Determining the absolute absolute path of a shell script</title><description>&lt;p&gt;In the course of working on projects like server-side &lt;a href="http://cappuccino.org"&gt;Objective-J&lt;/a&gt;, &lt;a href="http://jackjs.org"&gt;jack&lt;/a&gt;, and now &lt;a href="http://github.com/tlrobinson/narwhal"&gt;narwhal&lt;/a&gt;, I’ve often had to write shell scripts that needed to know their location in the filesystem. Rather than hardcoding it, I prefer to infer it automatically at runtime. Unfortunately this isn’t as easy as you would expect.&lt;/p&gt;

&lt;p&gt;If the script is invoked with an absolute path (“/foo/bar/baz”) or from your PATH (“baz”), then “$0” in the script will contain the absolute of the script (“/foo/bar/baz”). However, if it is invoked using a relative path (“./bar/baz” from “/foo”) then $0 will contain the relative path (“./bar/baz”). Furthermore, if the path to the script is actually a symbolic link, you’ll get the symlink’s path instead of the original.&lt;/p&gt;

&lt;p&gt;Surprisingly, I couldn’t find a definitive solution that handles all these cases, so I took the various ones I did find and created one which I think handles all the cases I’m aware of:&lt;/p&gt;

&lt;p&gt;&lt;script src="http://gist.github.com/87785.js"&gt;&lt;/script&gt;&lt;/p&gt;

&lt;p&gt;If you don’t want to resolve the symlinks remove the second half.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/YVj4TGLOlt8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/YVj4TGLOlt8/336828328</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336828328</guid><pubDate>Mon, 30 Mar 2009 05:04:24 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336828328</feedburner:origLink></item><item><title>Embedding and loading a JNI library from a jar</title><description>&lt;p&gt;When I searched for ways to load a JNI library from a jar there were numerous &lt;a href="http://forums.sun.com/thread.jspa?threadID=393971"&gt;hints&lt;/a&gt; of how to do it, but no code that I could find. So here’s my solution:

&lt;/p&gt;
&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881350;"&gt;import&lt;/span&gt;&lt;span style="color:#683821;"&gt; java.net.URL;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;import&lt;/span&gt;&lt;span style="color:#683821;"&gt; java.util.zip.ZipFile;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;import&lt;/span&gt;&lt;span style="color:#683821;"&gt; java.io.File;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;import&lt;/span&gt;&lt;span style="color:#683821;"&gt; java.io.FileOutputStream;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;import&lt;/span&gt;&lt;span style="color:#683821;"&gt; java.io.InputStream;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;public&lt;/span&gt; &lt;span style="color:#881350;"&gt;abstract&lt;/span&gt; &lt;span style="color:#881350;"&gt;class&lt;/span&gt; UnixDomainSocket {&lt;br/&gt;&lt;br/&gt;
    &lt;span style="color:#881350;"&gt;static&lt;/span&gt; {&lt;br/&gt;
        &lt;span style="color:#881350;"&gt;try&lt;/span&gt; {&lt;br/&gt;
            &lt;span style="color:#236e25;"&gt;// get the class object for this class, and get the location of it&lt;br/&gt;&lt;/span&gt;            &lt;span style="color:#881350;"&gt;final&lt;/span&gt; &lt;span style="color:#440088;"&gt;Class&lt;/span&gt; c = UnixDomainSocket.class;&lt;br/&gt;
            &lt;span style="color:#881350;"&gt;final&lt;/span&gt; &lt;span style="color:#440088;"&gt;URL&lt;/span&gt; location = c.&lt;span style="color:#003369;"&gt;getProtectionDomain&lt;/span&gt;().&lt;span style="color:#003369;"&gt;getCodeSource&lt;/span&gt;().&lt;span style="color:#003369;"&gt;getLocation&lt;/span&gt;();&lt;br/&gt;
            &lt;br/&gt;
            &lt;span style="color:#236e25;"&gt;// jars are just zip files, get the input stream for the lib&lt;br/&gt;&lt;/span&gt;            &lt;span style="color:#440088;"&gt;ZipFile&lt;/span&gt; zf = &lt;span style="color:#881350;"&gt;new&lt;/span&gt; &lt;span style="color:#440088;"&gt;ZipFile&lt;/span&gt;(location.&lt;span style="color:#003369;"&gt;getPath&lt;/span&gt;());&lt;br/&gt;
            &lt;span style="color:#440088;"&gt;InputStream&lt;/span&gt; in = zf.&lt;span style="color:#003369;"&gt;getInputStream&lt;/span&gt;(zf.&lt;span style="color:#003369;"&gt;getEntry&lt;/span&gt;(&lt;span style="color:#760f15;"&gt;“libunixdomainsocket.jnilib”&lt;/span&gt;));&lt;br/&gt;
            &lt;br/&gt;
            &lt;span style="color:#236e25;"&gt;// create a temp file and an input stream for it&lt;br/&gt;&lt;/span&gt;            &lt;span style="color:#440088;"&gt;File&lt;/span&gt; f = File.&lt;span style="color:#003369;"&gt;createTempFile&lt;/span&gt;(&lt;span style="color:#760f15;"&gt;“JARLIB-“&lt;/span&gt;, &lt;span style="color:#760f15;"&gt;“-libunixdomainsocket.jnilib”&lt;/span&gt;);&lt;br/&gt;
            &lt;span style="color:#440088;"&gt;FileOutputStream&lt;/span&gt; out = &lt;span style="color:#881350;"&gt;new&lt;/span&gt; &lt;span style="color:#440088;"&gt;FileOutputStream&lt;/span&gt;(f);&lt;br/&gt;
            &lt;br/&gt;
            &lt;span style="color:#236e25;"&gt;// copy the lib to the temp file&lt;br/&gt;&lt;/span&gt;            &lt;span style="color:#881350;"&gt;byte&lt;/span&gt;[] buf = &lt;span style="color:#881350;"&gt;new&lt;/span&gt; &lt;span style="color:#881350;"&gt;byte&lt;/span&gt;[&lt;span style="color:#0000ff;"&gt;1024&lt;/span&gt;];&lt;br/&gt;
            &lt;span style="color:#881350;"&gt;int&lt;/span&gt; len;&lt;br/&gt;
            &lt;span style="color:#881350;"&gt;while&lt;/span&gt;&lt;span style="color:#003369;"&gt; &lt;/span&gt;((len = in.&lt;span style="color:#003369;"&gt;read&lt;/span&gt;(buf)) &amp;gt; &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;)&lt;br/&gt;
                out.&lt;span style="color:#003369;"&gt;write&lt;/span&gt;(buf, &lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;, len);&lt;br/&gt;
            in.&lt;span style="color:#003369;"&gt;close&lt;/span&gt;();&lt;br/&gt;
            out.&lt;span style="color:#003369;"&gt;close&lt;/span&gt;();&lt;br/&gt;
    &lt;br/&gt;
            &lt;span style="color:#236e25;"&gt;// load the lib specified by it’s absolute path and delete it&lt;br/&gt;&lt;/span&gt;            System.&lt;span style="color:#003369;"&gt;load&lt;/span&gt;(f.&lt;span style="color:#003369;"&gt;getAbsolutePath&lt;/span&gt;());&lt;br/&gt;
            f.&lt;span style="color:#003369;"&gt;delete&lt;/span&gt;();&lt;br/&gt;
            &lt;br/&gt;
        } &lt;span style="color:#881350;"&gt;catch&lt;/span&gt;&lt;span style="color:#003369;"&gt; &lt;/span&gt;(&lt;span style="color:#440088;"&gt;Exception&lt;/span&gt; e) {&lt;br/&gt;
            e.&lt;span style="color:#003369;"&gt;printStackTrace&lt;/span&gt;();&lt;br/&gt;
            System.&lt;span style="color:#003369;"&gt;exit&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;1&lt;/span&gt;);&lt;br/&gt;
        }&lt;br/&gt;
    }&lt;br/&gt;
    &lt;br/&gt;
    &lt;span style="color:#236e25;"&gt;// …&lt;br/&gt;&lt;/span&gt;}&lt;/div&gt;

This particular example is for &lt;a href="http://code.google.com/p/juds/"&gt;JUDS&lt;/a&gt;.

It could be extended to load one of several libraries for different architectures, .jnilib or .dylib for Mac OS X, .so for Linux, and .dll for Windows.

This seems like a lot of hoops to jump through, but I couldn’t find an easier way to do it. If you know of a better way, please let me know in the comments.&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/0Z95vxRMG-Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/0Z95vxRMG-Y/336827938</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336827938</guid><pubDate>Sun, 08 Mar 2009 22:05:47 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336827938</feedburner:origLink></item><item><title>Game of Life text and image generator generator</title><description>&lt;p&gt;I saw this image the other day on &lt;a href="http://news.ycombinator.com"&gt;Hacker News&lt;/a&gt; and &lt;a href="http://www.reddit.com/"&gt;Reddit&lt;/a&gt;:

&lt;img src="http://golly.sourceforge.net/ticker.gif" alt="Golly Ticker"/&gt;

It’s a &lt;a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life"&gt;Game of Life&lt;/a&gt; pattern that prints out “Golly”. Neat, but I wanted my own. After about 5 minutes of playing around with the Golly logo pattern &lt;em&gt;in&lt;/em&gt; &lt;a href="http://golly.sourceforge.net/"&gt;Golly&lt;/a&gt; (a program for experimenting with the Game of Life), I gave up and wrote a program to do it.

The program takes the top and bottom portions of a template pattern (based on the Golly pattern) and positions them, then fills in the gliders between them for the correct number of columns. Then it duplicates the entire pattern for each row. Finally it “draws” some text (using the sample font from &lt;a href="http://pentacom.jp/soft/ex/font/"&gt;here&lt;/a&gt;) by deleting the gliders corresponding to empty space.

This was great, but I had essentially created a dot matrix printer that could draw anything, so it would be a waste to not draw images with it. A few lines of Ruby/RMagick code later, I had a program that did just that. Here’s an example using the Reddit Logo (&lt;a href="http://vimeo.com/3124876"&gt;watch it in HD&lt;/a&gt; for the best results):

&lt;object width="640" height="360"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3124876&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=FF7700&amp;amp;fullscreen=1"&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=3124876&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=FF7700&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="360"&gt;&lt;/embed&gt;&lt;/object&gt;

The code is &lt;a href="http://github.com/tlrobinson/life-gen/"&gt;available on GitHub&lt;/a&gt;. It requires Ruby, and RMagick for images. Pass it “-s yourtext” to generate a text based pattern, or “-i imagepath” for an image pattern.

Download &lt;a href="http://golly.sourceforge.net/"&gt;Golly&lt;/a&gt; to open up the generated “.rle” files.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/LpC6Y0Py1Hk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/LpC6Y0Py1Hk/336827397</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336827397</guid><pubDate>Sat, 07 Feb 2009 17:03:08 -0800</pubDate><category>Game of Life</category><feedburner:origLink>http://blog.tlrobinson.net/post/336827397</feedburner:origLink></item><item><title>Ant Tasks for Git</title><description>&lt;p&gt;Ant has tasks for CVS and Subversion, but none that I could find for Git. I threw together these simple Ant macros to get started:

&lt;/p&gt;
&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881280;"&gt;&amp;lt;macrodef &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git”&lt;/span&gt;&lt;span style="color:#881280;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;attribute &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“command”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;attribute &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“dir”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;default&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;””&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;element &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“args”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;optional&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“true”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;sequential&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;echo &lt;/span&gt;&lt;span style="color:#994500;"&gt;message&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git @{command}”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;exec &lt;/span&gt;&lt;span style="color:#994500;"&gt;executable&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;dir&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;”@{dir}”&lt;/span&gt;&lt;span style="color:#881280;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;
            &lt;span style="color:#881280;"&gt;&amp;lt;arg &lt;/span&gt;&lt;span style="color:#994500;"&gt;value&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;”@{command}”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
            &lt;span style="color:#881280;"&gt;&amp;lt;args/&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;/exec&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;/sequential&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881280;"&gt;&amp;lt;/macrodef&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span style="color:#881280;"&gt;&amp;lt;macrodef &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git-clone-pull”&lt;/span&gt;&lt;span style="color:#881280;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;attribute &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“repository”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;attribute &lt;/span&gt;&lt;span style="color:#994500;"&gt;name&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“dest”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;sequential&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;git &lt;/span&gt;&lt;span style="color:#994500;"&gt;command&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“clone”&lt;/span&gt;&lt;span style="color:#881280;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;
            &lt;span style="color:#881280;"&gt;&amp;lt;args&amp;gt;&lt;/span&gt;&lt;br/&gt;
                &lt;span style="color:#881280;"&gt;&amp;lt;arg &lt;/span&gt;&lt;span style="color:#994500;"&gt;value&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;”@{repository}”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
                &lt;span style="color:#881280;"&gt;&amp;lt;arg &lt;/span&gt;&lt;span style="color:#994500;"&gt;value&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;”@{dest}”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
            &lt;span style="color:#881280;"&gt;&amp;lt;/args&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;/git&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;git &lt;/span&gt;&lt;span style="color:#994500;"&gt;command&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“pull”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;dir&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;”@{dest}”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;/sequential&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881280;"&gt;&amp;lt;/macrodef&amp;gt;&lt;/span&gt;
&lt;/div&gt;

The first one, “git” just runs git with whatever command you provide to it (clone, pull, etc) along with any arguments you pass to it. Clone:

&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881280;"&gt;&amp;lt;git &lt;/span&gt;&lt;span style="color:#994500;"&gt;command&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“clone”&lt;/span&gt;&lt;span style="color:#881280;"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;args&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;arg &lt;/span&gt;&lt;span style="color:#994500;"&gt;value&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git://github.com/280north/ojunit.git”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span style="color:#881280;"&gt;&amp;lt;arg &lt;/span&gt;&lt;span style="color:#994500;"&gt;value&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“ojunit”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#881280;"&gt;&amp;lt;/args&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881280;"&gt;&amp;lt;/git&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;/div&gt;

And pull:

&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881280;"&gt;&amp;lt;git &lt;/span&gt;&lt;span style="color:#994500;"&gt;command&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“pull”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;dir&lt;/span&gt;&lt;span style="color:#881280;"&gt; = &lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“repository_path”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;
&lt;/div&gt;

(Other git command will likely work, these are just the ones I needed)

The second one, “git-clone-pull” uses the first one to clone a repository then pull from it. This effectively clones the repository if it hasn’t already been cloned, otherwise it pulls. However, since ant is fairly limited in what sorts of conditional execution you can perform, it just does both (clone will fail if it’s already been cloned, and pull will always be executed, even immediately after a the initial clone). Obviously not ideal, but it works, and I couldn’t figure out a better way without writing actual code.

&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881280;"&gt;&amp;lt;git-clone-pull &lt;/span&gt;&lt;span style="color:#994500;"&gt;repository&lt;/span&gt;&lt;span style="color:#881280;"&gt;=&lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“git://github.com/280north/ojunit.git”&lt;/span&gt;&lt;span style="color:#881280;"&gt; &lt;/span&gt;&lt;span style="color:#994500;"&gt;dest&lt;/span&gt;&lt;span style="color:#881280;"&gt;=&lt;/span&gt;&lt;span style="color:#1a1aa6;"&gt;“ojunit”&lt;/span&gt;&lt;span style="color:#881280;"&gt; /&amp;gt;&lt;/span&gt;
&lt;/div&gt;

There is plenty of room for improvement, but I suspect a proper Ant task written in Java is the right way to go.&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/xSfhAxGpPmU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/xSfhAxGpPmU/336827014</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336827014</guid><pubDate>Thu, 13 Nov 2008 20:20:30 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336827014</feedburner:origLink></item><item><title>"Mark Old As Read" for NetNewsWire</title><description>&lt;p&gt;I recently heard about an RSS reader (can’t remember which) that had a feature to mark all messages older than a certain threshold as “read”. I thought this was an incredibly useful feature, since I often forget to check my feeds for days at a time, and end up with hundreds of unread items that I don’t have time to read.

Luckily my current RSS reader, &lt;a href="http://www.newsgator.com/INDIVIDUALS/NETNEWSWIRE/"&gt;NetNewsWire&lt;/a&gt;, has AppleScript built in, so I whipped up this script that prompts for the number of days you want to keep as unread, and marks the rest as read.

&lt;/p&gt;
&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#0b0bff;"&gt;tell&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;application&lt;/span&gt; “NetNewsWire”&lt;br/&gt;
    display dialog “How many days old to mark read?” default answer “7”&lt;br/&gt;
    &lt;span style="color:#0b0bff;"&gt;set&lt;/span&gt; numDays &lt;span style="color:#0b0bff;"&gt;to&lt;/span&gt; text returned &lt;span style="color:#0b0bff;"&gt;of&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;result&lt;/span&gt;&lt;br/&gt;
    &lt;span style="color:#0b0bff;"&gt;set&lt;/span&gt; threshold &lt;span style="color:#0b0bff;"&gt;to&lt;/span&gt; (current date) - (numDays * &lt;span style="color:#0b0bff;"&gt;days&lt;/span&gt;)&lt;br/&gt;
    &lt;span style="color:#0b0bff;"&gt;set&lt;/span&gt; isRead &lt;span style="color:#0b0bff;"&gt;of&lt;/span&gt; (headlines &lt;span style="color:#0b0bff;"&gt;of&lt;/span&gt; subscriptions &lt;span style="color:#0b0bff;"&gt;where&lt;/span&gt; (isRead &lt;span style="color:#0b0bff;"&gt;is&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;equal&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;to&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;false&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;and&lt;/span&gt; date published &amp;lt; threshold)) &lt;span style="color:#0b0bff;"&gt;to&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;true&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#0b0bff;"&gt;end&lt;/span&gt; &lt;span style="color:#0b0bff;"&gt;tell&lt;/span&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/5a8UvpbLAss" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/5a8UvpbLAss/336826638</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336826638</guid><pubDate>Thu, 13 Nov 2008 15:58:28 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336826638</feedburner:origLink></item><item><title>A Better BugMeNot Bookmarklet</title><description>&lt;p&gt;&lt;a href="http://www.bugmenot.com/"&gt;BugMeNot&lt;/a&gt; is a great little service for bypassing the registration process for websites that really shouldn’t require it (ahem, nytimes.com). The bookmarklet brings up BugMeNot for the current website you’re viewing, and gives you login/password pairs which you can then copy and paste.

But wouldn’t it be better if it automagically filled in the username and password for you? I thought so, so I wrote a few lines of code in the form of a bookmarklet and a JSONP web service to do this.

BugMeNot doesn’t provide an API so I had to do a little screen scraping with &lt;a href="https://code.whytheluckystiff.net/hpricot/"&gt;Hpricot&lt;/a&gt;. They also try to obfuscate the usernames and passwords by shifting the characters by some offset calculated from a “key” then Base64 encoding the string, and prepending 4 characters. Luckily their obfuscation was no match for a single line of Ruby:

&lt;/p&gt;
&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#881350;"&gt;def&lt;/span&gt; bmn_decode(input, offset)&lt;br/&gt;
  &lt;span style="color:#236e25;"&gt;# decode base64, strip first 4 chars, convert chars to ints, substract offset, convert back ints back to chars&lt;br/&gt;&lt;/span&gt;  input.unpack(&lt;span style="color:#760f15;"&gt;“m*”&lt;/span&gt;)[&lt;span style="color:#0000ff;"&gt;0&lt;/span&gt;][&lt;span style="color:#0000ff;"&gt;4.&lt;/span&gt;.&lt;span style="color:#0000ff;"&gt;-1&lt;/span&gt;].unpack(&lt;span style="color:#760f15;"&gt;“C*”&lt;/span&gt;).map{|c| c - offset }.pack(&lt;span style="color:#760f15;"&gt;“C*”&lt;/span&gt;)&lt;br/&gt;&lt;span style="color:#881350;"&gt;end&lt;/span&gt;
&lt;/div&gt;

The bookmarklet makes the request via an injected &amp;lt;script&amp;gt; tag. When it’s callback gets called it finds the most likely input elements for the username and password and fills them in with the result.

The Rails app consists of a single action that makes a request to bugmenot.com for the specified site, extracts and decodes the usernames and passwords, and picks the one with the highest rating. It then returns the result as JSON wrapped in a function callback (i.e. JSONP)

&lt;p&gt;I’m not going to post the location of the live JSONP web service since BugMeNot limits the number of requests you can make, but the code is available &lt;a href="http://github.com/tlrobinson/tlrobinson/tree/master/bbmn"&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/a-ZMKPJm9BQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/a-ZMKPJm9BQ/336826349</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336826349</guid><pubDate>Sun, 09 Nov 2008 00:46:21 -0800</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336826349</feedburner:origLink></item><item><title>Open new Terminal tab in current directory (updated!)</title><description>&lt;p&gt;This is an updated shell script / AppleScript for opening a new &lt;em&gt;tab&lt;/em&gt; in your current directory (or the specified directory). The &lt;a href="http://tlrobinson.net/blog/2007/09/07/open-new-terminal-window-in-current-or-other-specified-directory/"&gt;last version&lt;/a&gt; was for the pre-tabbed version of Terminal.

&lt;/p&gt;
&lt;div style="text-align:left;color:#000000; background-color:#ffffff; border:solid black 1px; padding:0.5em 1em 0.5em 1em; overflow:auto;font-size:small; font-family:monospace; "&gt;
&lt;span style="color:#236e25;"&gt;#!/bin/sh -&lt;br/&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;if&lt;/span&gt; [ &lt;span style="color:#c4620a;"&gt;$#&lt;/span&gt; -ne &lt;span style="color:#0000ff;"&gt;1&lt;/span&gt; ]; &lt;span style="color:#881350;"&gt;then&lt;/span&gt;&lt;br/&gt;
    PATHDIR=&lt;span style="color:#660088;"&gt;`pwd`&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;else&lt;/span&gt;&lt;br/&gt;
    PATHDIR=&lt;span style="color:#c4620a;"&gt;$1&lt;/span&gt;&lt;br/&gt;&lt;span style="color:#881350;"&gt;fi&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;
/usr/bin/osascript «-EOF&lt;br/&gt;
activate application &lt;span style="color:#760f15;"&gt;“Terminal”&lt;/span&gt;&lt;br/&gt;
tell application &lt;span style="color:#760f15;"&gt;“System Events”&lt;/span&gt;&lt;br/&gt;
    keystroke &lt;span style="color:#760f15;"&gt;“t”&lt;/span&gt; using {&lt;span style="color:#440088;"&gt;command&lt;/span&gt; down}&lt;br/&gt;
end tell&lt;br/&gt;
tell application &lt;span style="color:#760f15;"&gt;“Terminal”&lt;/span&gt;&lt;br/&gt;
    repeat with win &lt;span style="color:#881350;"&gt;in&lt;/span&gt; windows&lt;br/&gt;
        try&lt;br/&gt;
            &lt;span style="color:#881350;"&gt;if&lt;/span&gt; get frontmost of win is &lt;span style="color:#880088;"&gt;true&lt;/span&gt; &lt;span style="color:#881350;"&gt;then&lt;/span&gt;&lt;br/&gt;
                &lt;span style="color:#881350;"&gt;do&lt;/span&gt; script &lt;span style="color:#760f15;"&gt;“cd &lt;/span&gt;&lt;span style="color:#c4620a;"&gt;$PATHDIR&lt;/span&gt;&lt;span style="color:#760f15;"&gt;; clear”&lt;/span&gt; &lt;span style="color:#881350;"&gt;in&lt;/span&gt;&lt;span style="color:#003369;"&gt; &lt;/span&gt;(selected tab of win)&lt;br/&gt;
            end &lt;span style="color:#881350;"&gt;if&lt;/span&gt;&lt;br/&gt;
        end try&lt;br/&gt;
    end repeat&lt;br/&gt;
end tell&lt;br/&gt;
EOF&lt;br/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/tlrobinson/~4/krMje8UUjX8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/tlrobinson/~3/krMje8UUjX8/336826012</link><guid isPermaLink="false">http://blog.tlrobinson.net/post/336826012</guid><pubDate>Wed, 22 Oct 2008 22:47:16 -0700</pubDate><feedburner:origLink>http://blog.tlrobinson.net/post/336826012</feedburner:origLink></item></channel></rss>

