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:

1
2
3
4
5
6
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:

1
2
3
4
5
6
7
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 App Store 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

Thanks “whoever you are” :http://pastie.org/344030.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
                     "/|"\
"/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=", '))

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’sSquirrelFish,
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
here.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define bit4800Delay 200 //1 bit per 0.2 ms
#define halfBit4800Delay 100

byte rx = 8; //Connect to EM-406A's TX
byte tx = 9; //Connect to EM-406A's RX
char dataformat[7] = "$GPGGA"; //GGA
char messageline[80] = "";
int i = 0;
char latitude[10];
char longitude[11];

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()
{

byte val = 0;
//Wait for start bit (0)
while(digitalRead(rx) HIGH);

if (digitalRead(rx) LOW) {
delayMicroseconds(halfBit4800Delay);

for (int offset = 0; offset < 8; offset**) {
delayMicroseconds;
val |= digitalRead << offset;
}

delayMicroseconds;

// Bitbanging
if
return val-128;
else
return val;
}
}

void char2string {
i = 0;
messageline[0] = SWread;
if {
i**;
messageline[i] = SWread();

while(messageline[i] != 13 & i<80) {
i++;
messageline[i] = SWread();
}

messageline[i+1] = '0';
}
}

void loop() {
char2string();
if (strncmp(messageline, dataformat, 6) == 0 & i>4) {
Serial.println(messageline);
}
}

iRot - iPhone development is fun

Over the weekend I decided to try my hand at a little iPhone
development. My Objective-C skill is non-existant, and my C skill is
incredibly rusty - but I pressed on. First up was installation of the
toolchain required to compile native applications. This one was tough,
very tough. After much swearing and shouting, I finally managed to get
it to install. The iPhone dev team’s official instructions were of help
right up until

1
2
sed
's/^FLAGS_FOR_TARGET=$/FLAGS_FOR_TARGET=${FLAGS_FOR_TARGET-}/g'

This is where things seemed to go horribly wrong for me and others.
After scouring google for solutions for what seemed like hours, I
finally happened up on
this
little golden nugget. With the toolchain finally installed I cracked
open my copy of Stephen Kochan’s Programming in
Objective-C

along with iPhone Open Application
Development

  • a book by NES.app’s developer which I really can’t recommend at the
    moment.

I decided to write a useless little ROT13 app which you can grab by
adding http://www.jasonmadigan.com/repo.xml to your installer.app’s
repository list. I’ll release the source tomorrow after a quick cleanup.

An end to a frickin' retarded restore path

Finally. Restoring an iPhone is no longer quite so painful. No more
jumping through hoops downgrading to 1.1.1 and slowly clawing your way
back up to 1.1.3 with all manner of retarded soft updates. Thanks to
Zibree’s
ZiPhone, you
no longer need to beg and plead with your iPhone to play along with you
for two hours to get your iPhone back in working order. Unlocking,
activating & jailbreaking any iPhone is now incredibly simple and fast.

Somebody really had to do this - when 1.1.4 lands (and it will soon),
restoring an iPhone would have previously meant no less than 4 jailbreak
hoops to jump through.

Software Unlock for OOTB 1.1.2 & 1.1.3 iPhones

Mister George Hotz has come through for us once again, with a software
based
unlock

for out of the box 1.1.2 & 1.1.3 iPhones. Now would be a good time to
buy one. It uses a delightful IPSF based method but this one doesn’t
zero out your seczones. So should Apple lose their minds in the future
and include a bootloader update in a future software release you won’t
end up with a complete brick.

Hot on it’s heals was a brief update regarding retarded dev-team/elite
team babby drama. It seems Zibri got tired of the two dev teams’
shenanigans once more and decided to jump the gun and
release the
method used by an upcoming semi-hardware unlock (an exploit piggybacking
on a Turbo SIM, once run there’s no need for the Turbo SIM anymore), the
details of which have been known by the dev-team for several weeks now.

Interesting times. Of course this means I’m going to be bombarded with a
stream of requests for unlocking - all of which I’m going to politely
decline. The iPhone is great and all, but eventually you come to realise
that, with every new firmware release, the time it’ll take you to
restore should something terrible happen is going to increase
considerably. I don’t know about you guys, but as soon as an official
release is confirmed for here with 3G, I’m jumping ship. It’s just too
tiring.

1.1.3 - IPSF Keep's On Truckin'

Like I thought, IphoneSimFree’s unlock continues to work with recent
iPhone updates. Taking the baseband out of lockdown requires a little
minicom pockery until we see a patched lockdownd - I’ll look into
patching it this weekend.

Lightweight, fast Rails stack - Thin & nginx

Since purchasing a
slice
of heaven
a few days ago, I’ve setup a very lightweight Rails stack
consisting of
Thin
& nginx for my
Rails needs. Since I went for a slice with just 256MB of RAM, memory
consumption becomes a pretty serious issue. nginx has been around for
quite a while now, and has recently started to become more and more
popular in Rails deployments due to the fact that’s incredibly
lightweight, very fast and stable - perfect not only for VPS jerks like
me, but for anyone who really doesn’t feel it’s necessary to run Apache
for static content/cluster proxying/load balancing. Thin is something I
came across very recently and I decided to try is as a replacement for
mongrel since I’d heard some great things about it, even if it is still
alpha. It’s performance in comparison to mongrel (even with a tacked on
event machine) looks very impressive on paper.

Setting up clustering with it is a snap, just spawn the processes and
pipe them into nginx. Here’s a startup script borrowed from
Stephen
Celis
:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace :thin do
namespace :cluster do desc 'Start thin cluster'
task :start => :environment do
`cd #{RAILS_ROOT}`
port_range = RAILS_ENV == 'development' ? 3 : 8
(ENV['SIZE'] ? ENV['SIZE'].to_i : 4).times do |i|
Thread.new do
port = ENV['PORT'] ? ENV['PORT'].to_i + i : ("#{port_range}%03d" i)
str = "thin start -d -p#{port} -Ptmp/pids/thin-#{port}.pid"
str += " -e#{RAILS_ENV}"
puts str
puts "Starting server on port #{port}..."
`#{str}`
end
end
end
desc 'Stop all thin clusters'
task :stop => :environment do
`cd #{RAILS_ROOT}`
Dir.new("#{RAILS_ROOT}/tmp/pids").each do |file|
Thread.new do
if file.starts_with?("thin-")
str = "thin stop -Ptmp/pids/#{file}"
puts "Stopping server on port #{file[/\d+/]}..."
`#{str}`
end
end
end
end
end
end

Then spawn however many processes you want using something like:

1
rake thin:cluster:start RAILS_ENV=production SIZE=2 PORT=3000

To stop them, use:

1
rake thin:cluster:stop

With that all nicely setup, you can use an nginx config similar to mine to get things in order:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
upstream dapperjerk {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}

server {
listen 80;
server_name www.dapperjerk.com;
rewrite \^/(.\*) http://dapperjerk.com permanent;
}

server {
listen 80;
server_name dapperjerk.com;

access_log /home/jason/public_html/blog/log/access.log;
error_log /home/jason/public_html/blog/log/error.log;

root /home/jason/public_html/blog/public/;
index index.html;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy\_redirect false;

if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}

if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}

if (!-f $request_filename) {
proxy_pass http://dapperjerk;
break;
}
}

}

And that’s really all there is too it. I’m not a masochist so I’ve never
bothered to fully read Apache’s documentation, but I don’t think I’m
going out on a limb here by saying that it seems to be a lot easier to
manage nginx. I haven’t really put thin through its paces yet, but we’ll
see in the coming weeks as I cobble together a custom blog app to run
this place.