Oops - Comments, RSS and other things fixed
Ouch, comments and RSS have been broken here for about a month. My specs caught the bugs, but I didn’t run them the last time I deployed. Tests aren’t much good if you’re too lazy to run them. Anyway, all working again – apologies!
Irish Weather app live on the App Store
I was bored three weekends ago and had an idea for a simple Irish weather app. Met Eireann have tons of great data available to the public, but finding the good stuff was a little fiddly. Anyway, after a weekend of work in Photoshop and Xcode, I had a pretty nice app. It was finally approved late last night. It’s free to download, so feel free to give it a spin.
The day a Time Capsule died
This is the first Apple product I’ve owned that’s died since my old Apple ][. The hard drive seems to be fine though. Plugged it into another machine and it works just fine. I guess all that heat killed the logicboard. I guess it had been warning me with a few months though – its DHCP server had become very flakey over the past few weeks.
Oh well, time to dust off my old dependable WRT54GL.
Node.js - Event driven, non-blocking web servers written in JavaScript
I’ve been fiddling with Ryan Dahl’s Node.js event driven I/O framework for the V8 JavaScript VM over the past couple of days. It’s probably the coolest piece of software I’ve come across in ages, and it really builds upon one of JavaScript’s core strengths: event driven programming. If you’ve been looking to brush up on your event driven programming, it’s seriously worth taking the time to play with. As part of his work on Node, Ryan has also released a seriously cool tiny HTTP parser in C (and used by Node). At 128 bytes per connection, it’s perfect for use in any embedded environment which could do with some HTTP love, like the Arduino.
Bluetooth/USB tethering & MMS for O2 Ireland with iPhone OS 3.0
Update #2: These carrier settings will work with Beta 2 also. Also, Safari likes to attach a .zip extension to the ipcc, so either rename the downloaded file minus the extension or use Firefox/curl something else to download the updated carrier settings.
Update: Updated the MMS proxy settings, the previous version was using an old (dead) proxy. To update just re-download the carrier settings and apply an update once more.
After a little dicking around prompted by some stuff I noticed on twitter, I cobbled together this updated carrier bundle for O2 Ireland to enable USB/Bluetooth tethering for iPhone OS 3.0. This also enables the sending/recieving of MMS messages a new photo button will appear in Messages.app to send pictures as MMS messages.
Grab it here.
To install, option (alt) click update in iTunes, and select this updated IPCC.
If something terrible happens, you can grab a backup of the old one to restore here.
Trip report - #fowadublin
I attended FOWA Dublin Friday last, and had a pretty good time. The speakers were the main reason I attended, with DHH & Simon Willison delivering particularly great talks. There were a couple of things that bugged me about the event setup. Not to be a jerk or anything, but there’s a few points I hope the Carsonified guys take a look at and fix in time for next year:
- Poor WiFi – I know the guys have apologised about this already, but it stuck in most people’s craw and I guess it bears repeating. With 400 odd people milling about with iPhones and Macs some decent WiFi would’ve been nice.
- Socialising is kind of hard when you’ve got absolutely no room to move.
- I don’t really care about toilets, but I heard there was only one bathroom for guys and one for girls.
- Lack of freebies. The tickets were pretty pricey (although I’d guess individuals paying for their own tickets were in the minority). Basically the only thing given away was a name-tag & holder. Free coffee for breaks or something would’ve gone down nicely.
- Mike Butcher
I’m sorry I missed the after party, but traveling really saps my will to go drinking.
Using cookies to calculate a user's timezone
A few days ago I discovered a quick & easy way few to use cookies to help your Rails app get a user’s timezone, without prompting. It’s pretty easy to implement:
First up: set a cookie, any cookie:
var date = new Date();
// returns offset from GMT in minutes
var offset = date.getTimezoneOffset();
// set a cookie however you see fit, I like to use jQuery.cookie
$.cookie('timezone', offset);
Then, in application.rb or wherever you like:
def browser_timezone
return nil if cookies[:timezone].blank?
@browser_timezone ||= begin
min = cookies[:timezone].to_i
TimeZone[(min + (-2 * min)).minutes]
end
end
The cookie gives you minutes from GMT, but
ActiveSupport::TimeZone expects seconds from GMT.Anyway, hopefully someone will find my pointing it out useful. It may buckle under pressure (with daylight savings), but guessing and getting it right 50% of the time is better than forcing user interaction. Probably.
An iPhone app is born
We finally saw our first iPhone app land on the appstore a couple of days ago. iPhone app development is pretty wonderful in comparison to some of the other crapheaps out there, but it’s also pretty damn nice by itself too. It was a ton of fun to write, and it was nice to do something like it for a local paper, The Munster Express.
Check it out here
Ruby Christmas
"/|"\
"/wl)e";eval(\
"A | A"\
"A | A"\
\
"InHhL"\
",Z,%w{-"\
",Y&/LH,L*"\
"cCnd,Hh&/d,"\
"YCB/Hh,Y&YHh,"\
"L&xHh,L*v*nHh,*"\
"&ghHh,n&nHh,H*nHh"\
",*q*v*nHh,Hw*qv*Hh}"\
"Iq&n*L,Z,[,n&qK,n&qK,"\
"@TwC,LH/&ng,gLBbL@K,@Th"\
"/**,YC/k*d,Hh/*QdL@K,@FCB"\
"/,cQqq&ng,=/CcL@K,@F&v*,RBb"\
"y,g*mL!@K,@S&x,mQ/LhQqL,dBm=&"\
"ng@K,@S*v*n,dBckL,Q-Hy=&ng@K,@E"\
"&ghH,d&/L,Q-gqCbb&ng@K,@N&n*,/Qng"\
"*L,LH*==&ng@K,@T*n,H/yL,Q-cQHch&ng@"\
"K,@Eq*v*n,&CL,=&=&ng@K,@Tw*qv*,mCnk*y"\
"L,=QHch&ng@,]IDAJJA2)J*Qch,dC,U&UI=/&nH"\
",@\nOn,Hh*,\#{nHhL[&]},dQy,CY,MQHzmQL,my,"\
"H/B*,qCv*,gQv*,HC,m*:\n@I&JdCwnHCD2),dC,UjU"\
"I=/&nH,@,,,\#{q&n*L[j]}\n@I*ndI=/&nHDD&,ZZ,A)"\
"?,@,,"\
",G@,:"\
",@,,,"\
"Gnd,Q"\
"@)I=/"\
"&nH,@,n*w,v*/L&Cn,CY,RBby!\n@I*nd"\
"I".tr(' ID/VHLYGBqCA&|*UQJ=Z@K,',
'+;(r/tsfAulo1i8e|a.p=", '))
Thanks whoever you are.
Google Calendar & iCal - Together at last
Happy news greeted me in my feed reader this morning, since Google calendar now supports iCal.
Moving day
Slicehost have been very good to me over the past year, with no downtime or anything bad to report. But a few weeks ago I began checking out Linode. I could shave 8 bux a month off of my hosting bill and gain a little RAM and an extra 100GB of transfer. I could also have it hosted closer to this side of the Atlantic (Newark, New Jersey to be precise).
I’ve also moved the old blog from typo to Mephisto, since Mephisto is really lightweight and does one of the things all great software should aspire to: doing one thing, and doing it extremely well. Mephisto has been on life support for a while now, but it’s started to receive regular attention and mending pretty regularly over the past 2 or 3 months. I’ve got one or two patches I’ll submit when I get around to it, since it’s nice to support software you use by tending to it.
Farewell MacBook Air, I hardly knew ye.
I’ve decided that there were just too many little things that irked me about my MacBook Air (small screen size was killing me), so it’s time to let it go. I’ve put it up for auction, anticipating that I’ll probably purchase a MacBook Pro again after tomorrow’s Apple media event. If you’re interested, there’s still some time left:
http://cgi.ebay.ie/ws/eBayISAPI.dll?ViewItem&item=150303143685
Content aware image resizing
Content aware image resizing in Photoshop is something that I’ve been looking forward to for a long time, ever since I saw this (see Seam Carving for Content-Aware Image Resizing) article about it a couple of years ago. Looks like it’s finally going to land in CS4.
JavaScript flexes its muscles
It’s an exciting time for JavaScript developers. Over the past few months, we’ve seen all sorts of cool things coming our way. We’ve seen new fast, heavily optimised JavaScript virtual machines such as WebKit’s SquirrelFish, Mozilla’s TraceMonkey and, most recently, Google’s V8. We’ve seen all kinds of cool things done with these new VMs, perhaps the coolest (to my mind) is running dynamic languages such as Ruby in the browser – see http://macournoyer.wordpress.com/2008/09/02/ruby-on-v8/.
We’ve also seen the effective death of the ECMAScript 4 proposal and seen it reborn as ECMAScript Harmony. To top things off, we’ve also seen some very interesting new JavaScript frameworks designed specifically with complex client-side web applications such as SproutCore and, just today, Cappccino & Objective-J. The web development world is evolving too quickly for the current model of standards adoption remain sustainable, and it’s nice to see that developers like those behind Cappuccino get it.
Reinventing the wheel, just to see what all the fuss is about.
I’ve been amassing a small army of broken arduinos over the past two months, but now I have something to show for it – the bones of a working (but altogether bulky) GPS tracker. The code I used seems kind of nasty to me, mostly because the bit-banging used for serial communication to try to ensure no data is missed in transition. The Arduino IDE is okay I guess (for a Java app), but if you like Ruby you may want to check out RAD. Looks like RAD only works with version 10 of the arduino SDK right now though.
In terms of kit hooked up, we’ve got an EM-406A (GPS Module) & an Arduino Mini along with a USB to serial header. I need to buy a EEPROM for storage, or possibly some kind of microSD reader. Borrowing some code from here we can parse NMEA to take a look at where you are with Google Maps.
#define bit4800Delay 200 //1 bit per 0.2 ms
#define halfBit4800Delay 100byte rx = 8; //Connect to EM-406A’s TX
byte tx = 9; //Connect to EM-406A’s RX
char dataformat7 = “$GPGGA”; //GGA
char messageline80 = "";
int i = 0;
char latitude10;
char longitude11;void setup() {
pinMode(rx,INPUT);
pinMode(tx,OUTPUT);
digitalWrite(tx,HIGH); // Needs to be pulled high before the EM-406A will return data
digitalWrite(13,HIGH); // Debugging LED
Serial.begin(9600); // Echo EM-406A output through serial
}char SWread()
if (digitalRead(rx) == LOW) { delayMicroseconds(halfBit4800Delay); for (int offset = 0; offset < 8; offset++) { delayMicroseconds(bit4800Delay); val |= digitalRead(rx) << offset; } delayMicroseconds(bit4800Delay); // Bitbanging if( val > 128 ) return val-128; else return val; }
{
byte val = 0;
//Wait for start bit (0)
while(digitalRead(rx) == HIGH);}
void char2string() {
while(messageline[i] != 13 & i<80) { i++; messageline[i] = SWread(); } messageline[i+1] = ‘\0’; }
i = 0;
messageline0 = SWread();
if (messageline0 == ‘$’) {
i++;
messageline[i] = SWread();}
void loop() {
char2string();
if (strncmp(messageline, dataformat, 6) == 0 & i>4) {
Serial.println(messageline);
}
}
