I recently switched from the HTC Desire to the iPhone 4s and I’m pretty happy so far. The things that usually use on my phone and that I have to look for on the Apple app store are:

  • a podcasting client
  • an app to record GPS files while running
  • an app for turn-by-turn navigation

The podcasting client was easy, I’ve already used instacast on my iPad, it syncs with iCloud and works perfectly for what I need.
This post deals with the second app, the running app. When I was on Android, I usually used runkeeper. It worked fine and the only downside was that I had to go to the website to get the GPX file (and they tried to hide it pretty well). On iOS, the app seemed a bit… jumpy when it comes to filtering the GPS signal:
runkeeper jumpiness
This wasn’t really what I was looking for.
I also tried a few other ones, but most of them where targeted towards getting you on some website and wanting you to buy some sort of premium subscription.
I looked for a paid app that isn’t free but offers good value, this is where I noticed Runmeter:
runkeeper mainscreen runkeeper map runkeeper calendar

The company that develops it has a nice comparison online. While this has to be taken with a grain of salt, I think they did an ok job.
Things I like:

  • It has support for adding runs to the calendar after you’re done. It’s kinda neat to see your calendar and know what you’ve done next to all the other stuff.
  • It is able to attach a gpx to an email and export it that way. It is also able to send customized reports with direct links. I’ll probably use this to automate the import into my custom tailored runalog (that is in dire need of a bit of code polish):
    runkeeper jumpiness
  • It is able to customize the voice feedback. You can pretty much combine whatever information you want to hear.
  • It doesn’t force me to go to any website. The only thing you have to sign up for is sending automated emails after every run. You can also use the iPhone to send those, but iOS limits apps to just popping up a prefilled “compose” window and not actually sending them. I don’t have a problem with using the developers webservice.
  • It has a whole lot of social yadda yadda integrated. I don’t use it, but I like the fact that I could.

So far I am happy with the app, it’s actively being developed and the price of 4.99$ is ok for something that I use every day.
–> App store link

Here are the slides of a NoSQL presentation I did as a “lunch and learn” at acquia.
The presentation introduces the different categories of NoSQL data-stores and discusses some of their possible use-cases.
The slides are a bit on the text heavy side and really don’t have a good design. I think I will stop trying to use google docs for that kind of stuff:

A PDF copy of the slides is available here.

When trying to run a test-unit test with the included XML testrunner on 1.8.7, I ended up with a NameError about a missing “TestResultFailureSupport”:

1
2
> ruby test.rb --runner=xml
.rvm/gems/ruby-1.8.7-p334/gems/test-unit-2.3.2/lib/test/unit/testresult.rb:28: uninitialized constant Test::Unit::TestResult::TestResultFailureSupport (NameError)

To solve this, you have to make sure that the file actually loads the test-unit 2.x GEM as opposed to using the included 1.x version from stdlib. You can do this by simply adding this line to your ruby file:

1
gem "test-unit"

It’s another one of those blogposts… :)
I was a bit fed up with having to keep a whole software stack (mysql, apache, varnish, …) on my VPS up to date while just serving static content (comments via disqus).
When Werner Vogel’s blopgpost “No Server Required - Jekyll & Amazon S3” popped up in my feed reader, I decided to spend a few hours fiddling with a quick and dirty migration attempt.
Thanks to the wonders of open source, migrating my blog from drupal to octopress was relatively easy. I had to change some minor things in the migration script and I was ready to go. I hope to parametrize my changes correctly and submit a D7 compatible version of the script to the octopress github repo on one of the upcoming weekends.
The next steps will be:

  • move the blog to Amazon S3
  • thin out the softwarestack on my VPS a bit
  • change the blog template to something custom

Fun times ahead :)

The disqus module allows the usage of drupal with the disqus commenting system.
Since I recently migrated, I’d love to be able to:
a) keep all of my links the same
and
b) have all the old comments show up on the new site.
Problem a) can be solved by simply using the pathauto module and some minor tweaking wherever needed.
Problem b) needed some hacking for me.

I always used the alias (blog.marc-seeger.de/year/month/day/slug) as an identifier on disqus. The durpal module, by default, uses the drupal node ID (blog.marc-seeger.de/node/123) as the identifier.
It’s easy enough to make some small changes though. All of this is in the disqus.module file. Here is the original passage that sets the disqus URL:

alias_orig.php
1
2
3
4
5
        // Build the absolute URL without the alias for the disqus_url flag.
        $node->disqus['url'] = url("node/$node->nid", array(
          'alias' => TRUE,
          'absolute' => TRUE,
        ));

Just change the ‘alias’ parameter to false to get your aliased path as the disqus URL:

alias_mod.php
1
          'alias' => FALSE,

This tells the url() function to NOT assume that the alias is already resolved.
The API for the url function describes it as “Whether the given path is a URL alias already.” The second thing you have to change is the disqus identifier. Also in the disqus.module search for this:

identifier_orig.php
1
2
    // Provide the identifier.
        $node->disqus['identifier'] = 'node/' . $node->nid;

and replace it by:

identifier_mod.php
1
2
3
4
5
        // Provide the identifier.  
        $node->disqus['identifier'] = url("node/$node->nid", array(
          'alias' => FALSE,
          'absolute' => TRUE,
        ));

Worked for me :)

When trying to watch a TV show on hulu (u.s.) or iplayer (u.k.) from inside Germany, one is usually greeted with messages like these:

iPlayer:

iplayer geolocation error

Hulu:

hulu geolocation error

These services usually use your IP address to determine what country you’re from. An obvious solution would be to just run the whole traffic over an HTTP proxy that is standing inside of the country in question. The problem is that while browsers tend to honor HTTP proxy settings, the flash player will try a direct socket connection first. This could be circumvented by blocking ports, but that is one of the more annoying solutions to the problem.

Something interesting can be seen by looking at how the iPlayer does the geo locating. It will check the IP and, if successful, pass out the URL for the actual streaming video. This URL can be accessed from anywhere, the only problem is to somehow get at it.

While VPN solutions work, they usually will tunnel ALL of your traffic over the comparatively slow VPN connection, will require manual enabling/disabling, won’t work with e.g. the apple tv out of the box and are in general a pain to set up. If you want to go this way, I recommend taking a look at privateinternetaccess.com. I used to just grab cheap VPS systems from lowendbox.com, but seeing as privateinternetacces provides me with endpoints in 9+ countries (US for Hulu, NL for NFL Gamepass, UK for iPlayer, Switzerland for Zattoo, …) for 40$ a year, I’d rather just save myself the hassle.

As mentioned, there are however good reasons why one might not want to have all traffic being routed over a VPN connection. I recently came across a pretty interesting service that has a different approach to this problem. The service is Unblock US and they provide a DNS based solution to the whole ‘geolocation-check’ topic. After you signed up (free 1 week trail without payment details) you’ll have to use their servers as DNS servers.

What they will do is redirect all DNS requests to geo-location checks to their own IPs where e.g. a squid server will forward the connection with an IP address that matches the country in question (e.g. the US for Hulu and the UK for iPlayer). The advantages of this approach are:

  • Only the necessary traffic will run over the slow proxy. Most of the time, the real video will come directly to you via your regular internet connection

  • You can just put the DNS servers into your router and all of your devices (iPad, AppleTV, Laptops, … ) will be able to automagically use the geo-restricted services

  • While the service provider might redirect any website to their servers, they still can’t fake an SSL certificate, so anything important should still be safe (you hopefully ARE using SSL/TLS!)

  • In contrast to a VPN solution, this allows you to access services from more than just one country (e.g. Netflix from the US, iPlayer from the UK, TruTV from Germany, TF1 from France)

The price for the service isn’t too bad either. When prepaying for a year, it will come down a little bit less than 3 Euro/month. Monthly payments will be approximately 3.50 Euro/month.

A downside of this approach is, that they have to ‘whitelist’ services and figure out which URLs/Domains are responsible for the GeoIP checks. With a VPN, you can use ANY service within that country without further actions.

While I haven’t signed up with them so far, I’m seriously considering it once I have some free time on my hands to actually watch all the tv and movies.

First of all: This is a bad idea in general since you shouldn’t use class variables in ruby.
But just in case you ever need to use them and would like to access them using a getter method, this is how it can work:

attr_class.rb
1
2
3
4
5
6
7
8
9
class Derp
  @@numero_uno = "Something about cake"
  @@numero_dos = "Number one was a lie"
  #this creates the methods when the class is loaded  
   self.class_variables.each{ |sym| class_eval("def self.#{sym.gsub('@@','')}; return #{sym}; end;") }
end

puts Derp.numero_uno
puts Derp.numero_dos

This is a bit of magic and even has an eval(), but it works…

I recently got my hands on the Western Digital MyBook Live ( Amazon DE, Amazon US ). It is a 2 TB external harddrive that has only 2 connectors:
- A power supply
- A gigabit ethernet port

Initially, I wanted to use it as a no-hassle solution for OSX Time Machine backups. This worked perfectly and I can easily push 5-6 MB/s over Wifi to the drive. After being happy with this, I decided to see if there is anything else interesting going on with the drive.

Here are some findings: - The MyBook Live admin console is done in PHP using the full blown cakePHP framework:
cake php on the mybook
- The MyBook Live has a hidden page to enable SSH at “/UI/ssh”:
enabling ssh on the mybook
- It has an 800MHz CPU with 256 MB RAM:

1
2
3
4
5
6
7
8
9
10
# cat /proc/cpuinfo  
processor : 0  
cpu       : APM82181  
clock     : 800.000008MHz  
revision  : 28.129 (pvr 12c4 1c81)  
bogomips  : 1600.00  
timebase  : 800000008  
platform  : PowerPC 44x Platform  
model     : amcc,apollo3g  
Memory        : 256 MB
  • The internal harddrive is using ext4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cat /etc/mtab  
/dev/md1 / ext3 rw,noatime 0 0
tmpfs /lib/init/rw tmpfs rw,nosuid,mode=0755,size=50M 0 0
proc /proc proc rw,noexec,nosuid,nodev 0 0
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
procbususb /proc/bus/usb usbfs rw 0 0
udev /dev tmpfs rw,mode=0755 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,size=50M 0 0
devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=620 0 0
tmpfs /tmp tmpfs rw,size=50M 0 0
/var/log /var/log.hdd none rw,bind 0 0
ramlog-tmpfs /var/log tmpfs rw,size=20M 0 0
/dev/sda4 /DataVolume ext4 rw,noatime,nodelalloc 0 0
/DataVolume/cache /CacheVolume none rw,bind 0 0
/DataVolume/shares /shares none rw,bind 0 0
/DataVolume/shares /nfs none rw,bind 0 0
none /sys/kernel/security securityfs rw 0 0
rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw 0 0
nfsd /proc/fs/nfsd nfsd rw 0 0
  • It is using lots of open source software:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# ls -l /etc/init.d/
total 456
-rw-r--r-- 1 root root  1510 Mar  4  2010 README  
-rwxr-xr-x 1 root root  6532 Sep 20 22:34 apache2  
-rwxr-xr-x 1 root root 18698 Mar  4  2010 autofs  
-rwxr-xr-x 1 root root  2359 Jul 31  2010 avahi-daemon  
-rwxr-xr-x 1 root root  2155 Mar  4  2010 bootlogd  
-rwxr-xr-x 1 root root  1988 Mar  4  2010 bootmisc.sh  
-rwxr-xr-x 1 root root  3004 Mar  4  2010 checkfs.sh  
-rwxr-xr-x 1 root root  9831 Mar  4  2010 checkroot.sh  
-rwxr-xr-x 1 root root  2602 Jun 16  2010 cron  
-rwxr-xr-x 1 root root  4636 Mar  4  2010 dbus  
-rwxr-xr-x 1 root root   833 Jul 14  2010 emi-patch-check.sh  
-rwxr-xr-x 1 root root  6593 Mar  4  2010 exim4  
-rwxr-xr-x 1 root root   959 Jun 18  2010 factoryRestoreSettings.sh  
-rwxr-xr-x 1 root root  1397 Sep 13  2010 halt  
-rwxr-xr-x 1 root root 10725 Mar  4  2010 hdparm  
-rwxr-xr-x 1 root root  1287 Mar  4  2010 hostname.sh  
-rwxr-xr-x 1 root root  5061 Jul  9  2010 hwclock.sh  
-rwxr-xr-x 1 root root  5079 Jul  9  2010 hwclockfirst.sh  
-rwxr-xr-x 1 root root  3117 May 14  2010 ifplugd  
-rwxr-xr-x 1 root root  2518 Mar  4  2010 ifupdown  
-rwxr-xr-x 1 root root  1046 Mar  4  2010 ifupdown-clean  
-rwxr-xr-x 1 root root  2814 Aug  2  2010 itunes  
-rwxr-xr-x 1 root root  1484 Mar  4  2010 killprocs  
-rwxr-xr-x 1 root root   851 Mar 15  2010 lltd  
-rwxr-xr-x 1 root root  1051 Mar  4  2010 lvm2  
-rwxr-xr-x 1 root root  1845 Jul 31  2010 mDNSResponder  
-rwxr-xr-x 1 root root  1916 Mar  4  2010 mdadm  
-rwxr-xr-x 1 root root  6226 Mar  4  2010 mdadm-raid  
-rwxr-xr-x 1 root root  1726 Jan 14 18:25 mionet  
-rwxr-xr-x 1 root root  1793 Mar  4  2010 module-init-tools  
-rwxr-xr-x 1 root root  1546 Jul  9  2010 monitorio  
-rwxr-xr-x 1 root root  2625 Sep 20 22:34 mountDataVolume.sh  
-rwxr-xr-x 1 root root   620 Mar  4  2010 mountall-bootclean.sh  
-rwxr-xr-x 1 root root  1956 Mar  4  2010 mountall.sh  
-rwxr-xr-x 1 root root  2194 Mar  4  2010 mountdevsubfs.sh  
-rwxr-xr-x 1 root root  2476 Mar  4  2010 mountkernfs.sh  
-rwxr-xr-x 1 root root   618 Mar  4  2010 mountnfs-bootclean.sh  
-rwxr-xr-x 1 root root  2330 Mar  4  2010 mountnfs.sh  
-rwxr-xr-x 1 root root  1321 Mar  4  2010 mountoverflowtmp  
-rwxr-xr-x 1 root root  3668 Mar  4  2010 mtab.sh  
-rwxr-xr-x 1 root root  5755 Mar  4  2010 mysql  
-rwxr-xr-x 1 root root  2515 Mar  4  2010 mysql-ndb  
-rwxr-xr-x 1 root root  1905 Mar  4  2010 mysql-ndb-mgm  
-rwxr-xr-x 1 root root  3180 Aug 11  2010 netatalk  
-rwxr-xr-x 1 root root  1844 Mar  4  2010 networking  
-rwxr-xr-x 1 root root  5964 Mar  4  2010 nfs-common  
-rwxr-xr-x 1 root root  4563 Mar 19  2010 nfs-kernel-server  
-rwxr-xr-x 1 root root  1308 Aug  2  2010 ntpdate  
-rwxr-xr-x 1 root root  2066 Mar  4  2010 portmap  
-rwxr-xr-x 1 root root  1247 Mar  4  2010 procps  
-rwxr-xr-x 1 root root 29492 May 27  2010 ramlog  
-rwxr-xr-x 1 root root 10036 Mar  4  2010 rc  
-rwxr-xr-x 1 root root   788 Mar  4  2010 rc.local  
-rwxr-xr-x 1 root root   117 Mar  4  2010 rcS  
-rwxr-xr-x 1 root root   639 Mar  4  2010 reboot  
-rwxr-xr-x 1 root root  1710 Jun 11  2010 reset_button_mon  
-rwxr-xr-x 1 root root   941 Mar  4  2010 rmnologin  
-rwxr-xr-x 1 root root  5108 Mar  4  2010 rsync  
-rwxr-xr-x 1 root root  2850 Mar  4  2010 rsyslog  
-rwxr-xr-x 1 root root  2533 Oct 15 02:25 samba  
-rwxr-xr-x 1 root root   765 May 11  2010 saveclock.sh  
-rwxr-xr-x 1 root root   918 May  2  2009 screen-cleanup  
-rwxr-xr-x 1 root root  2283 Mar  4  2010 sendsigs  
-rwxr-xr-x 1 root root   590 Mar  4  2010 single  
-rw-r--r-- 1 root root  4167 Mar  4  2010 skeleton  
-rwxr-xr-x 1 root root  3364 Mar  4  2010 smartmontools  
-rwxr-xr-x 1 root root  3845 Aug  2  2010 ssh  
-rwxr-xr-x 1 root root   525 Mar  4  2010 stop-bootlogd  
-rwxr-xr-x 1 root root  1096 Mar  4  2010 stop-bootlogd-single  
-rwxr-xr-x 1 root root   551 Mar 18  2010 sudo  
-rwxr-xr-x 1 root root  4176 Jan 14 22:57 twonky  
-rwxr-xr-x 1 root root  7473 May 13  2010 udev  
-rwxr-xr-x 1 root root  1001 May 13  2010 udev-mtab  
-rwxr-xr-x 1 root root  3175 Mar  4  2010 umountfs  
-rwxr-xr-x 1 root root  2140 Mar  4  2010 umountnfs.sh  
-rwxr-xr-x 1 root root  1456 Mar  4  2010 umountroot  
-rwxr-xr-x 1 root root  2006 May 27  2010 upnp_nas  
-rwxr-xr-x 1 root root  1815 Mar  4  2010 urandom  
-rwxr-xr-x 1 root root   903 May 28  2010 vftd  
-rwxr-xr-x 1 root root  2516 Aug  2  2010 vsftpd  
-rwxr-xr-x 1 root root  1777 Mar  4  2010 x11-common  
-rwxr-xr-x 1 root root  1923 Mar  4  2010 xmail
  • A somewhat recent SVN kernel:
1
2
# uname -a  
Linux MyBookLive 2.6.32.11-svn21605 #1 Fri Oct 15 17:13:23 PDT 2010 ppc GNU/Linux
  • Debian Lenny (I might have added contrib and non-free to this):
1
2
3
4
5
6
7
# cat /etc/apt/sources.list | grep lenny  
deb http://ftp.us.debian.org/debian/ lenny main contrib non-free  
deb-src http://ftp.us.debian.org/debian/ lenny main contrib non-free  
deb http://mirrors.usc.edu/pub/linux/distributions/debian/ lenny main contrib non-free  
deb-src http://mirrors.usc.edu/pub/linux/distributions/debian/ lenny main  
deb http://security.debian.org lenny/updates main contrib non-free  
deb-src http://security.debian.org/ lenny/updates main contrib non-free
  • They even deliver a Java VM with their weird mionet service:
1
2
3
4
# /usr/mionet/bin/cvm -version  
Product: Sun Java Media Client 1.3-b111 WesternDigital-b003 (built on 10/Jun/2010 00:33 IST)  
Profile: Foundation Profile (Security Optional Package) 1.1.2 (Specification 1.1.2)  
JVM:     1.1.2 1.3-b111 WesternDigital-b003 (mixed mode)

Since we’re pretty good on available RAM, there is a bunch of fun stuff we can do (cough)