I love the idea of the Quantified Self movement. I love collecting data, trying to see connections and monitoring my self improvement process. I’ve been collecting GPX traces while running for quite a while, so it isn’t all that unexpected that the fitbit was a gadget that was right up my alley. It allows you to record the amount of steps you take like every other pedometer, but thanks to a few more sensors, it also can tell you how many floors you’ve climbed, how many kilometers ou traveled and even how often you worke up while sleeping.
It syncs wirelessly, the battery lasts a long time and it is small enough that it isn’t an annoyance to carry arround all day.
The only downside is the webservice itself. It’s not that I dislike their site itself, quite to the contrary. The annoying part is that I’d have to subscribe to their premium plan to get a hold of my raw data. I’m not actually looking to use any of the other premium features, so just paying 50$/yr because they hold my data hostage was kind of a pain.

The nice part however is, that they provide an API that allows you to programmatically grab at least an overview of activity and sleep stats. It misses the actual timeframes (“you walked 1000 steps between 3 and 3,15”, “you woke up at 3, 3:45 and 5”) but it provides you with an ok summary (steps per day, fell asleep at time x, …).

I was a bit afraid that I’d have to screen scrape their site to get to my data, but not only didn’t I have to do that, I also didn’t have to deal with the oauth stuff myself either.

Zachery Moneypenny (“whazzmaster”) had already created a client library for their API and provided a bit of sample code.
Using that library I was able to whip up a quick incremental backup script that saves the activities and sleep data as something machine readable.
This is an example of what the activity data looks like:

$ cat 2012_09_10_activities.yaml 
---
activities: []
goals:
  activeScore: 1000
  caloriesOut: 3092
  distance: 8.05
  floors: 10
  steps: 10000
summary:
  activeScore: 762
  activityCalories: 1362
  caloriesOut: 2885
  distances:
  - activity: total
    distance: 6.43
  - activity: tracker
    distance: 6.43
  - activity: loggedActivities
    distance: 0
  - activity: veryActive
    distance: 2.25
  - activity: moderatelyActive
    distance: 3.36
  - activity: lightlyActive
    distance: 0.81
  - activity: sedentaryActive
    distance: 0
  elevation: 9.14
  fairlyActiveMinutes: 102
  floors: 3
  lightlyActiveMinutes: 139
  marginalCalories: 913
  sedentaryMinutes: 651
  steps: 8114
  veryActiveMinutes: 33

And the sleep data:

$ cat 2012_09_10_sleep.yaml 
---
sleep:
- awakeningsCount: 8
  duration: 30900000
  efficiency: 97
  isMainSleep: true
  logId: 16236289
  minutesAfterWakeup: 1
  minutesAsleep: 471
  minutesAwake: 16
  minutesToFallAsleep: 27
  startTime: '2012-09-10T00:56:00.000'
  timeInBed: 515
summary:
  totalMinutesAsleep: 471
  totalSleepRecords: 1
  totalTimeInBed: 515

You can find the script in my github repo. It’s not properly packaged and the Readme could use some polish, but this is more of a ‘scratching my own itch’ thingy that I thought might just save somebody 15 minutes.

I ran into a strange ‘bug’ that was a little bit more annoying to debug.
Apparently OpenSSL 1.x that is getting installed by brew doesn’t seem to be 100% compatible with Ruby, at least when you install it using RVM.

I ran into a reproducible problem when trying to connect to a salesforce sandbox account. This could be distilled down to this snipped:

1
2
3
4
5
6
7
8
require 'net/http'
require 'openssl'

h = Net::HTTP.new('test.salesforce.com', 443).tap do |http|
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
h.post('/test' ,'')

Which resulted in this sad exception after 30 seconds or so:

Errno::ECONNRESET: Connection reset by peer - SSL_connect
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:744:in `start'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1284:in `request'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1096:in `post'

It turns out that RVM can also install openssl, and it decides to go for version 0.9.8:

$ rvm pkg install openssl
Fetching openssl-0.9.8t.tar.gz to /Users/mseeger/.rvm/archives
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3690k  100 3690k    0     0   394k      0  0:00:09  0:00:09 --:--:--  456k
Extracting openssl-0.9.8t.tar.gz to /Users/mseeger/.rvm/src
Configuring openssl in /Users/mseeger/.rvm/src/openssl-0.9.8t.
Compiling openssl in /Users/mseeger/.rvm/src/openssl-0.9.8t.
Installing openssl to /Users/mseeger/.rvm/usr
$ 

After that I just reinstalled Ruby and pointed it at the openssl version just to make extra sure:

rvm reinstall 1.9.3-p194 --with-openssl-dir=~/.rvm/usr

After that, the snipped ends up with a 404 as expected.

I’ve recently been dabbling with setting up a little homeserver. It runs XBMC, afpd (for TimeMachine) and a good amount of other little scripts and apps that mike my life more automated.
One of the things I would like to have is the ability to access US only services like Hulu from within XBMC.
From the XBMC side, that isn’t all that hard of a task. There are plugins for hulu (video) and the online portfolio of various cable stations (video) available from bluecop’s repository. They certainly aren’t giving the user an experience that is up to par with something like the interface of an Apple TV, but it usually works without too much of a hassle.
One of the problems when setting up this combination is the geo-locked nature of hulu and the other providers. When visiting the Hulu website from my usual German IP address, I am greeted with the usual “NO VIDEO FOR YOU!” message:

contentprovider fail

To get arround this, I’ve used VPNs or specialized services in the past. While both of them work pretty decently, I’d rather not force ALL of my traffic over the VPN or pay for a service that I can’t use for much more than Hulu.
One solution would be to go down the VPN route and configure network access based on the user or group using iptables’s owner-match extension, but I honestly don’t like working with iptables and the extension isn’t necessarily available on all systems.
Thanks to @makefoo, I looked a bit more into available “socksification” tools. These tools basically hook TCP/IP kernel methods and redirect them over a SOCKS proxy on a per application level using LD_PRELOAD as far as I understood. This means that you can use them on a per-application level and the only thing you need to point them at is a SOCKS proxy. A SOCKS proxy like the one that SSH is able to provide with the -D flag. So the only real setup I have to do is establishing an SSH connection before I launch the app using something like:

ssh -ND 8765 -i /path/to/certificate [email protected] 

Given that you set up a ‘user’ account on your server (.bin/false or /bin/nologin are your friends) and have public key authentication enabled, this will open a local socks proxy on port 8765 and is able to dynamically forward all requests ports through that connection. There are several tools that can do the actual redirection of the network requests. I personally have had good luck with ProxyChains. Other alternatives are TSocks or Dante.

Another big advantage is that this doesn’t need anything running on the remote server besides SSH. I suggest looking at current LowEndBox offers for a cheap VPS. I currently use the “Atlanta OpenVZ VPS - OVZ128” from Quickpacket which comes down to 15 USD a year. I had to ask them for another IP once because the first one wasn’t for some reason detected as being from the US, but besides that it worked great.

If you’re looking for solutions to proxy your Bittorrent traffic, I suggest using Deluge Torrent which supports SOCKS without the need for forced socksification. And at least for Germany, Oderland is a nice swedish VPS provider that has a VPS starting at 2-3 Euros/month.

Thanks to this, I can now do all of my backups straight over my regular connetion and specific programs will use the SSH encryted connection. With my AMD E-450 CPU, I can push 100 mbit/s transfer speed to the internet without a problem.

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 :)