<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Marc's Blog]]></title>
  <link href="http://blog.marc-seeger.de/atom.xml" rel="self"/>
  <link href="http://blog.marc-seeger.de/"/>
  <updated>2012-01-31T09:56:52+01:00</updated>
  <id>http://blog.marc-seeger.de/</id>
  <author>
    <name><![CDATA[Marc Seeger]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Running Apps on the iPhone]]></title>
    <link href="http://blog.marc-seeger.de/2011/10/21/running-apps-on-the-iphone/"/>
    <updated>2011-10-21T22:31:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/10/21/running-apps-on-the-iphone</id>
    <content type="html"><![CDATA[<p>I recently switched from the <a href="http://en.wikipedia.org/wiki/HTC_Desire">HTC Desire</a> to the <a href="http://en.wikipedia.org/wiki/IPhone_4S">iPhone 4s</a> and I&#8217;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:</p>

<ul>
<li>a podcasting client</li>
<li>an app to record GPS files while running</li>
<li>an app for turn-by-turn navigation</li>
</ul>


<p>The podcasting client was easy, I&#8217;ve already used <a href="http://itunes.apple.com/us/app/instacast/id420368235?mt=8">instacast</a> on my iPad, it syncs with iCloud and works perfectly for what I need.<br/>
This post deals with the second app, the running app.
When I was on Android, I usually used <a href="http://www.runkeeper.com">runkeeper</a>. 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:<br/>
<img src="http://blog.marc-seeger.de/assets/2011/10/21/runkeeper.png" alt="runkeeper jumpiness" /><br/>
This wasn&#8217;t really what I was looking for.<br/>
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.<br/>
I looked for a paid app that isn&#8217;t free but offers good value, this is where I noticed <a href="http://click.linksynergy.com/fs-bin/click?id=EkBoRjf29pk&amp;offerid=146261.326498704&amp;type=2&amp;subid=0">Runmeter</a>:<br/>
<img src="http://blog.marc-seeger.de/assets/2011/10/21/runmeter_main.png" alt="runkeeper mainscreen" /> <img src="http://blog.marc-seeger.de/assets/2011/10/21/runmeter_map.png" alt="runkeeper map" /> <img src="http://blog.marc-seeger.de/assets/2011/10/21/runmeter_cal.png" alt="runkeeper calendar" /></p>

<p>The company that develops it has a nice <a href="http://www.abvio.com/running-guide/">comparison</a> online. While this has to be taken with a grain of salt, I think they did an ok job.<br/>
Things I like:</p>

<ul>
<li>It has support for adding runs to the calendar after you&#8217;re done. It&#8217;s kinda neat to see your calendar and know what you&#8217;ve done next to all the other stuff.</li>
<li>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&#8217;ll probably use this to automate the import into my custom tailored <a href="https://github.com/rb2k/run-a-log">runalog</a> (that is in dire need of a bit of code polish):<br/>
<img src="http://blog.marc-seeger.de/assets/2011/10/21/runmeter_mail.png" alt="runkeeper jumpiness" /></li>
<li>It is able to customize the voice feedback. You can pretty much combine whatever information you want to hear.</li>
<li>It doesn&#8217;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 &#8220;compose&#8221; window and not actually sending them. I don&#8217;t have a problem with using the developers webservice.</li>
<li>It has a whole lot of social yadda yadda integrated. I don&#8217;t use it, but I like the fact that I could.</li>
</ul>


<p>So far I am happy with the app, it&#8217;s actively being developed and the price of 4.99$ is ok for something that I use every day.<br/>
&#8211;> <a href="http://click.linksynergy.com/fs-bin/click?id=EkBoRjf29pk&amp;offerid=146261.326498704&amp;type=2&amp;subid=0">App store link</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NoSQL Lunch and Learn]]></title>
    <link href="http://blog.marc-seeger.de/2011/10/11/nosql-lunch-and-learn/"/>
    <updated>2011-10-11T23:51:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/10/11/nosql-lunch-and-learn</id>
    <content type="html"><![CDATA[<p>Here are the slides of a NoSQL presentation I did as a &#8220;lunch and learn&#8221; at <a href="http://www.acquia.com/careers">acquia</a>. Not 100% happy about the slides, a bit text heavy:</p>

<div style="width:425px" id="__ss_9650040"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/marc.seeger/nosql-databases-9650040" title="NoSQL databases" target="_blank">NoSQL databases</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9650040?rel=0" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></div>


<p>PDF available <a href="http://blog.marc-seeger.de/assets/papers/2011_10-lunch_and_learn_nosql_databases.pdf">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mashups: Shake N' Bake]]></title>
    <link href="http://blog.marc-seeger.de/2011/09/30/mashups-shake-n-bake/"/>
    <updated>2011-09-30T13:44:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/09/30/mashups-shake-n-bake</id>
    <content type="html"><![CDATA[<p>Collected enough good stuff again :)</p>

<iframe src="http://8tracks.com/mixes/403296/player_v3_universal" width="512" height="288"></iframe>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using the Test-unit XML Runner]]></title>
    <link href="http://blog.marc-seeger.de/2011/09/09/using-the-test-unit-xml-runner/"/>
    <updated>2011-09-09T13:55:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/09/09/using-the-test-unit-xml-runner</id>
    <content type="html"><![CDATA[<p>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 &#8220;TestResultFailureSupport&#8221;:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">&gt;</span> <span class="n">ruby</span> <span class="nb">test</span><span class="o">.</span><span class="n">rb</span> <span class="o">--</span><span class="n">runner</span><span class="o">=</span><span class="n">xml</span>
</span><span class='line'><span class="o">.</span><span class="n">rvm</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="n">ruby</span><span class="o">-</span><span class="mi">1</span><span class="o">.</span><span class="mi">8</span><span class="o">.</span><span class="mi">7</span><span class="o">-</span><span class="n">p334</span><span class="o">/</span><span class="n">gems</span><span class="o">/</span><span class="nb">test</span><span class="o">-</span><span class="n">unit</span><span class="o">-</span><span class="mi">2</span><span class="o">.</span><span class="mi">3</span><span class="o">.</span><span class="mi">2</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="nb">test</span><span class="o">/</span><span class="n">unit</span><span class="o">/</span><span class="n">testresult</span><span class="o">.</span><span class="n">rb</span><span class="p">:</span><span class="mi">28</span><span class="p">:</span> <span class="n">uninitialized</span> <span class="n">constant</span> <span class="no">Test</span><span class="o">::</span><span class="no">Unit</span><span class="o">::</span><span class="no">TestResult</span><span class="o">::</span><span class="no">TestResultFailureSupport</span> <span class="p">(</span><span class="no">NameError</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>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:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">gem</span> <span class="s2">&quot;test-unit&quot;</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Migration to Octopress]]></title>
    <link href="http://blog.marc-seeger.de/2011/08/24/migration-to-octopress/"/>
    <updated>2011-08-24T15:27:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/08/24/migration-to-octopress</id>
    <content type="html"><![CDATA[<p>It&#8217;s another one of those blogposts&#8230; :)<br/>
I was a bit fed up with having to keep a whole software stack (mysql, apache, varnish, &#8230;) on my VPS up to date while just serving static content (comments via disqus).<br/>
When Werner Vogel&#8217;s blopgpost &#8221;<a href="http://www.allthingsdistributed.com/2011/08/Jekyll-amazon-s3.html">No Server Required - Jekyll &amp; Amazon S3</a>&#8221; popped up in my feed reader, I decided to spend a few hours fiddling with a quick and dirty migration attempt.<br/>
Thanks to the wonders of open source, migrating my blog from <a href="http://www.drupal.org">drupal</a> to <a href="https://github.com/imathis/octopress">octopress</a> 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.<br/>
The next steps will be:</p>

<ul>
<li>move the blog to Amazon S3</li>
<li>thin out the softwarestack on my VPS a bit</li>
<li>change the blog template to something custom</li>
</ul>


<p>Fun times ahead :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[disqus migration to drupal]]></title>
    <link href="http://blog.marc-seeger.de/2011/04/09/disqus-migration-to-drupal/"/>
    <updated>2011-04-09T00:00:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/04/09/disqus-migration-to-drupal</id>
    <content type="html"><![CDATA[<p>The <a href="http://drupal.org/project/disqus">disqus module</a> allows the usage of drupal with the disqus commenting system.<br/>
Since I recently migrated, I&#8217;d love to be able to:<br/>
a) keep all of my links the same<br/>
and<br/>
b) have all the old comments show up on the new site.<br/>
Problem a) can be solved by simply using the <a href="http://drupal.org/project/pathauto">pathauto</a> module and some minor tweaking wherever needed.<br/>
Problem b) needed some hacking for me.</p>

<p>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.<br/>
It&#8217;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:</p>

<figure class='code'><figcaption><span>alias_orig.php </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">        // Build the absolute URL without the alias for the disqus_url flag.</span>
</span><span class='line'><span class="x">        $node-&gt;disqus[&#39;url&#39;] = url(&quot;node/$node-&gt;nid&quot;, array(</span>
</span><span class='line'><span class="x">          &#39;alias&#39; =&gt; TRUE,</span>
</span><span class='line'><span class="x">          &#39;absolute&#39; =&gt; TRUE, </span>
</span><span class='line'><span class="x">        ));</span>
</span></code></pre></td></tr></table></div></figure>


<p>Just change the &#8216;alias&#8217; parameter to false to get your aliased path as the disqus URL:</p>

<figure class='code'><figcaption><span>alias_mod.php </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">          &#39;alias&#39; =&gt; FALSE,</span>
</span></code></pre></td></tr></table></div></figure>


<p>This tells the url() function to NOT assume that the alias is already resolved.<br/>
The <a href="http://api.drupal.org/api/drupal/includes--common.inc/function/url">API for the url function</a>  describes it as &#8220;Whether the given path is a URL alias already.&#8221;
The second thing you have to change is the disqus identifier. Also in the disqus.module search for this:</p>

<figure class='code'><figcaption><span>identifier_orig.php </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">    // Provide the identifier.</span>
</span><span class='line'><span class="x">        $node-&gt;disqus[&#39;identifier&#39;] = &#39;node/&#39; . $node-&gt;nid;</span>
</span></code></pre></td></tr></table></div></figure>


<p>and replace it by:</p>

<figure class='code'><figcaption><span>identifier_mod.php </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">        // Provide the identifier.  </span>
</span><span class='line'><span class="x">        $node-&gt;disqus[&#39;identifier&#39;] = url(&quot;node/$node-&gt;nid&quot;, array(</span>
</span><span class='line'><span class="x">          &#39;alias&#39; =&gt; FALSE,</span>
</span><span class='line'><span class="x">          &#39;absolute&#39; =&gt; TRUE,</span>
</span><span class='line'><span class="x">        ));</span>
</span></code></pre></td></tr></table></div></figure>


<p>Worked for me :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[hulu and iplayer outside the US without a VPN]]></title>
    <link href="http://blog.marc-seeger.de/2011/04/07/hulu-and-iplayer-outside-the-us-without-a-vpn/"/>
    <updated>2011-04-07T00:00:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/04/07/hulu-and-iplayer-outside-the-us-without-a-vpn</id>
    <content type="html"><![CDATA[<p>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:</p>

<p>iPlayer:</p>

<p><a href="http://unblock-us.com/663.html"><img src="http://blog.marc-seeger.de/assets/2011/04/07/bbc_iplayer_geofail.png" alt="iplayer geolocation error"/></a></p>

<p>Hulu:</p>

<p><a href="http://unblock-us.com/663.html"><img src="http://blog.marc-seeger.de/assets/2011/04/07/hulu_geofail.png" alt="hulu geolocation error"/></a></p>

<p>These services usually use your IP address to determine what country you&#8217;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.</p>

<p>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.</p>

<p>While VPN solutions work, they usually will tunnel ALL of your traffic over the comparatively slow VPN connection, will require manual enabling/disabling, won&#8217;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 a look over to <a href="http://www.lowendbox.com">lowendbox.com</a> for matching VPS systems or at one of the many commercial VPN providers which are usually more expensive than setting it up yourself.</p>

<p>I recently came across a pretty interesting service that has a different approach to this problem. The service is <a href="http://unblock-us.com/663.html">Unblock US</a> and they provide a DNS based solution to the whole &#8216;geolocation-check&#8217; topic. After you signed up (free 1 week trail without payment details) you&#8217;ll have to use their servers as DNS servers.</p>

<p>What they will do is redirect all DNS requests to geo-location checks to their own IPs where e.g. a <a href="http://www.squid-cache.org/">squid server</a> 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:</p>

<ul>
<li><p>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</p></li>
<li><p>You can just put the DNS servers into your router and all of your devices (iPad, AppleTV, Laptops, &#8230; ) will be able to automagically use the geo-restricted services</p></li>
<li><p>While the service provider might redirect any website to their servers, they still can&#8217;t fake an SSL certificate, so anything important should still be safe (you hopefully ARE using SSL/TLS!)</p></li>
<li><p>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)</p></li>
</ul>


<p>The price for the service isn&#8217;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.</p>

<p>A downside of this approach is, that they have to &#8216;whitelist&#8217; 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.</p>

<p>While I haven&#8217;t signed up with them so far, I&#8217;m seriously considering it once I have some free time on my hands to actually watch all the tv and movies.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[attr_reader for class variables in Ruby]]></title>
    <link href="http://blog.marc-seeger.de/2011/04/06/attr_reader-for-class-variables-in-ruby/"/>
    <updated>2011-04-06T00:00:00+02:00</updated>
    <id>http://blog.marc-seeger.de/2011/04/06/attr_reader-for-class-variables-in-ruby</id>
    <content type="html"><![CDATA[<p>First of all: This is a bad idea in general since you <a href="http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html">shouldn&#8217;t use class variables</a> in ruby.<br/>
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:</p>

<figure class='code'><figcaption><span>attr_class.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">Derp</span>
</span><span class='line'>  <span class="vc">@@numero_uno</span> <span class="o">=</span> <span class="s2">&quot;Something about cake&quot;</span>
</span><span class='line'>  <span class="vc">@@numero_dos</span> <span class="o">=</span> <span class="s2">&quot;Number one was a lie&quot;</span>
</span><span class='line'>  <span class="c1">#this creates the methods when the class is loaded  </span>
</span><span class='line'>   <span class="nb">self</span><span class="o">.</span><span class="n">class_variables</span><span class="o">.</span><span class="n">each</span><span class="p">{</span> <span class="o">|</span><span class="n">sym</span><span class="o">|</span> <span class="nb">class_eval</span><span class="p">(</span><span class="s2">&quot;def self.</span><span class="si">#{</span><span class="n">sym</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="s1">&#39;@@&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">)</span><span class="si">}</span><span class="s2">; return </span><span class="si">#{</span><span class="n">sym</span><span class="si">}</span><span class="s2">; end;&quot;</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="nb">puts</span> <span class="no">Derp</span><span class="o">.</span><span class="n">numero_uno</span>
</span><span class='line'><span class="nb">puts</span> <span class="no">Derp</span><span class="o">.</span><span class="n">numero_dos</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is a bit of magic and even has an eval(), but it works&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mashup Mix March 2011]]></title>
    <link href="http://blog.marc-seeger.de/2011/03/24/mashup-mix-march-2011/"/>
    <updated>2011-03-24T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/03/24/mashup-mix-march-2011</id>
    <content type="html"><![CDATA[<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="300" height="250"><param name="movie" value="http://8tracks.com/mixes/267304/player_v3"><param name="allowscriptaccess" value="always"><embed src="http://8tracks.com/mixes/267304/player_v3" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="300" height="250" allowscriptaccess="always" ></embed></object>


<p>It took a while but here is a new mix on 8tracks. <br/>
Have fun :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Western Digital MyBook Live]]></title>
    <link href="http://blog.marc-seeger.de/2011/03/20/the-western-digital-mybook-live/"/>
    <updated>2011-03-20T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/03/20/the-western-digital-mybook-live</id>
    <content type="html"><![CDATA[<p>I recently got my hands on the Western Digital MyBook Live ( <a href="https://www.amazon.de/dp/B00499DMRQ/ref=as_li_ss_til?tag=marblo-21&amp;camp=2906&amp;creative=19474&amp;linkCode=as4&amp;creativeASIN=B00499DMRQ&amp;adid=069R0M7A7S1Y876TS7WF&amp;">Amazon DE</a>, <a href="https://www.amazon.com/dp/B00439GMJ2/ref=as_li_ss_til?tag=masbl0b0-20&amp;camp=213381&amp;creative=390973&amp;linkCode=as4&amp;creativeASIN=B00439GMJ2&amp;adid=0PV3Z1QBKZSPJ0ZX6TZS&amp;">Amazon US</a> ). It is a 2 TB external harddrive that has only 2 connectors:<br/>
- A power supply<br/>
- A gigabit ethernet port</p>

<p>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.</p>

<p>Here are some findings:
- The MyBook Live admin console is done in PHP using the full blown cakePHP framework:<br/>
<img src="http://blog.marc-seeger.de/assets/2011/03/20/mybook-cakephp.png" alt="cake php on the mybook"  width="480px" height="240px"/><br/>
- The MyBook Live has a hidden page to enable SSH at &#8220;/UI/ssh&#8221;:<br/>
<img src="http://blog.marc-seeger.de/assets/2011/03/20/mybook-ssh-access.png" alt="enabling ssh on the mybook" width="480px" height="240px"/><br/>
- It has an 800MHz CPU with 256 MB RAM:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># cat /proc/cpuinfo  
</span><span class='line'>processor : 0  
</span><span class='line'>cpu       : APM82181  
</span><span class='line'>clock     : 800.000008MHz  
</span><span class='line'>revision  : 28.129 (pvr 12c4 1c81)  
</span><span class='line'>bogomips  : 1600.00  
</span><span class='line'>timebase  : 800000008  
</span><span class='line'>platform  : PowerPC 44x Platform  
</span><span class='line'>model     : amcc,apollo3g  
</span><span class='line'>Memory        : 256 MB</span></code></pre></td></tr></table></div></figure>


<ul>
<li>The internal harddrive is using ext4:</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># cat /etc/mtab  
</span><span class='line'>/dev/md1 / ext3 rw,noatime 0 0
</span><span class='line'>tmpfs /lib/init/rw tmpfs rw,nosuid,mode=0755,size=50M 0 0
</span><span class='line'>proc /proc proc rw,noexec,nosuid,nodev 0 0
</span><span class='line'>sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
</span><span class='line'>procbususb /proc/bus/usb usbfs rw 0 0
</span><span class='line'>udev /dev tmpfs rw,mode=0755 0 0
</span><span class='line'>tmpfs /dev/shm tmpfs rw,nosuid,nodev,size=50M 0 0
</span><span class='line'>devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=620 0 0
</span><span class='line'>tmpfs /tmp tmpfs rw,size=50M 0 0
</span><span class='line'>/var/log /var/log.hdd none rw,bind 0 0
</span><span class='line'>ramlog-tmpfs /var/log tmpfs rw,size=20M 0 0
</span><span class='line'>/dev/sda4 /DataVolume ext4 rw,noatime,nodelalloc 0 0
</span><span class='line'>/DataVolume/cache /CacheVolume none rw,bind 0 0
</span><span class='line'>/DataVolume/shares /shares none rw,bind 0 0
</span><span class='line'>/DataVolume/shares /nfs none rw,bind 0 0
</span><span class='line'>none /sys/kernel/security securityfs rw 0 0
</span><span class='line'>rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw 0 0
</span><span class='line'>nfsd /proc/fs/nfsd nfsd rw 0 0</span></code></pre></td></tr></table></div></figure>


<ul>
<li>It is using lots of open source software:</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># ls -l /etc/init.d/
</span><span class='line'>total 456
</span><span class='line'>-rw-r--r-- 1 root root  1510 Mar  4  2010 README  
</span><span class='line'>-rwxr-xr-x 1 root root  6532 Sep 20 22:34 apache2  
</span><span class='line'>-rwxr-xr-x 1 root root 18698 Mar  4  2010 autofs  
</span><span class='line'>-rwxr-xr-x 1 root root  2359 Jul 31  2010 avahi-daemon  
</span><span class='line'>-rwxr-xr-x 1 root root  2155 Mar  4  2010 bootlogd  
</span><span class='line'>-rwxr-xr-x 1 root root  1988 Mar  4  2010 bootmisc.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  3004 Mar  4  2010 checkfs.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  9831 Mar  4  2010 checkroot.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  2602 Jun 16  2010 cron  
</span><span class='line'>-rwxr-xr-x 1 root root  4636 Mar  4  2010 dbus  
</span><span class='line'>-rwxr-xr-x 1 root root   833 Jul 14  2010 emi-patch-check.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  6593 Mar  4  2010 exim4  
</span><span class='line'>-rwxr-xr-x 1 root root   959 Jun 18  2010 factoryRestoreSettings.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  1397 Sep 13  2010 halt  
</span><span class='line'>-rwxr-xr-x 1 root root 10725 Mar  4  2010 hdparm  
</span><span class='line'>-rwxr-xr-x 1 root root  1287 Mar  4  2010 hostname.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  5061 Jul  9  2010 hwclock.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  5079 Jul  9  2010 hwclockfirst.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  3117 May 14  2010 ifplugd  
</span><span class='line'>-rwxr-xr-x 1 root root  2518 Mar  4  2010 ifupdown  
</span><span class='line'>-rwxr-xr-x 1 root root  1046 Mar  4  2010 ifupdown-clean  
</span><span class='line'>-rwxr-xr-x 1 root root  2814 Aug  2  2010 itunes  
</span><span class='line'>-rwxr-xr-x 1 root root  1484 Mar  4  2010 killprocs  
</span><span class='line'>-rwxr-xr-x 1 root root   851 Mar 15  2010 lltd  
</span><span class='line'>-rwxr-xr-x 1 root root  1051 Mar  4  2010 lvm2  
</span><span class='line'>-rwxr-xr-x 1 root root  1845 Jul 31  2010 mDNSResponder  
</span><span class='line'>-rwxr-xr-x 1 root root  1916 Mar  4  2010 mdadm  
</span><span class='line'>-rwxr-xr-x 1 root root  6226 Mar  4  2010 mdadm-raid  
</span><span class='line'>-rwxr-xr-x 1 root root  1726 Jan 14 18:25 mionet  
</span><span class='line'>-rwxr-xr-x 1 root root  1793 Mar  4  2010 module-init-tools  
</span><span class='line'>-rwxr-xr-x 1 root root  1546 Jul  9  2010 monitorio  
</span><span class='line'>-rwxr-xr-x 1 root root  2625 Sep 20 22:34 mountDataVolume.sh  
</span><span class='line'>-rwxr-xr-x 1 root root   620 Mar  4  2010 mountall-bootclean.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  1956 Mar  4  2010 mountall.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  2194 Mar  4  2010 mountdevsubfs.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  2476 Mar  4  2010 mountkernfs.sh  
</span><span class='line'>-rwxr-xr-x 1 root root   618 Mar  4  2010 mountnfs-bootclean.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  2330 Mar  4  2010 mountnfs.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  1321 Mar  4  2010 mountoverflowtmp  
</span><span class='line'>-rwxr-xr-x 1 root root  3668 Mar  4  2010 mtab.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  5755 Mar  4  2010 mysql  
</span><span class='line'>-rwxr-xr-x 1 root root  2515 Mar  4  2010 mysql-ndb  
</span><span class='line'>-rwxr-xr-x 1 root root  1905 Mar  4  2010 mysql-ndb-mgm  
</span><span class='line'>-rwxr-xr-x 1 root root  3180 Aug 11  2010 netatalk  
</span><span class='line'>-rwxr-xr-x 1 root root  1844 Mar  4  2010 networking  
</span><span class='line'>-rwxr-xr-x 1 root root  5964 Mar  4  2010 nfs-common  
</span><span class='line'>-rwxr-xr-x 1 root root  4563 Mar 19  2010 nfs-kernel-server  
</span><span class='line'>-rwxr-xr-x 1 root root  1308 Aug  2  2010 ntpdate  
</span><span class='line'>-rwxr-xr-x 1 root root  2066 Mar  4  2010 portmap  
</span><span class='line'>-rwxr-xr-x 1 root root  1247 Mar  4  2010 procps  
</span><span class='line'>-rwxr-xr-x 1 root root 29492 May 27  2010 ramlog  
</span><span class='line'>-rwxr-xr-x 1 root root 10036 Mar  4  2010 rc  
</span><span class='line'>-rwxr-xr-x 1 root root   788 Mar  4  2010 rc.local  
</span><span class='line'>-rwxr-xr-x 1 root root   117 Mar  4  2010 rcS  
</span><span class='line'>-rwxr-xr-x 1 root root   639 Mar  4  2010 reboot  
</span><span class='line'>-rwxr-xr-x 1 root root  1710 Jun 11  2010 reset_button_mon  
</span><span class='line'>-rwxr-xr-x 1 root root   941 Mar  4  2010 rmnologin  
</span><span class='line'>-rwxr-xr-x 1 root root  5108 Mar  4  2010 rsync  
</span><span class='line'>-rwxr-xr-x 1 root root  2850 Mar  4  2010 rsyslog  
</span><span class='line'>-rwxr-xr-x 1 root root  2533 Oct 15 02:25 samba  
</span><span class='line'>-rwxr-xr-x 1 root root   765 May 11  2010 saveclock.sh  
</span><span class='line'>-rwxr-xr-x 1 root root   918 May  2  2009 screen-cleanup  
</span><span class='line'>-rwxr-xr-x 1 root root  2283 Mar  4  2010 sendsigs  
</span><span class='line'>-rwxr-xr-x 1 root root   590 Mar  4  2010 single  
</span><span class='line'>-rw-r--r-- 1 root root  4167 Mar  4  2010 skeleton  
</span><span class='line'>-rwxr-xr-x 1 root root  3364 Mar  4  2010 smartmontools  
</span><span class='line'>-rwxr-xr-x 1 root root  3845 Aug  2  2010 ssh  
</span><span class='line'>-rwxr-xr-x 1 root root   525 Mar  4  2010 stop-bootlogd  
</span><span class='line'>-rwxr-xr-x 1 root root  1096 Mar  4  2010 stop-bootlogd-single  
</span><span class='line'>-rwxr-xr-x 1 root root   551 Mar 18  2010 sudo  
</span><span class='line'>-rwxr-xr-x 1 root root  4176 Jan 14 22:57 twonky  
</span><span class='line'>-rwxr-xr-x 1 root root  7473 May 13  2010 udev  
</span><span class='line'>-rwxr-xr-x 1 root root  1001 May 13  2010 udev-mtab  
</span><span class='line'>-rwxr-xr-x 1 root root  3175 Mar  4  2010 umountfs  
</span><span class='line'>-rwxr-xr-x 1 root root  2140 Mar  4  2010 umountnfs.sh  
</span><span class='line'>-rwxr-xr-x 1 root root  1456 Mar  4  2010 umountroot  
</span><span class='line'>-rwxr-xr-x 1 root root  2006 May 27  2010 upnp_nas  
</span><span class='line'>-rwxr-xr-x 1 root root  1815 Mar  4  2010 urandom  
</span><span class='line'>-rwxr-xr-x 1 root root   903 May 28  2010 vftd  
</span><span class='line'>-rwxr-xr-x 1 root root  2516 Aug  2  2010 vsftpd  
</span><span class='line'>-rwxr-xr-x 1 root root  1777 Mar  4  2010 x11-common  
</span><span class='line'>-rwxr-xr-x 1 root root  1923 Mar  4  2010 xmail</span></code></pre></td></tr></table></div></figure>


<ul>
<li>A somewhat recent SVN kernel:</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># uname -a  
</span><span class='line'>Linux MyBookLive 2.6.32.11-svn21605 #1 Fri Oct 15 17:13:23 PDT 2010 ppc GNU/Linux</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Debian Lenny (I might have added contrib and non-free to this):</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># cat /etc/apt/sources.list | grep lenny  
</span><span class='line'>deb http://ftp.us.debian.org/debian/ lenny main contrib non-free  
</span><span class='line'>deb-src http://ftp.us.debian.org/debian/ lenny main contrib non-free  
</span><span class='line'>deb http://mirrors.usc.edu/pub/linux/distributions/debian/ lenny main contrib non-free  
</span><span class='line'>deb-src http://mirrors.usc.edu/pub/linux/distributions/debian/ lenny main  
</span><span class='line'>deb http://security.debian.org lenny/updates main contrib non-free  
</span><span class='line'>deb-src http://security.debian.org/ lenny/updates main contrib non-free</span></code></pre></td></tr></table></div></figure>


<ul>
<li>They even deliver a Java VM with their weird mionet service:</li>
</ul>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># /usr/mionet/bin/cvm -version  
</span><span class='line'>Product: Sun Java Media Client 1.3-b111 WesternDigital-b003 (built on 10/Jun/2010 00:33 IST)  
</span><span class='line'>Profile: Foundation Profile (Security Optional Package) 1.1.2 (Specification 1.1.2)  
</span><span class='line'>JVM:     1.1.2 1.3-b111 WesternDigital-b003 (mixed mode)</span></code></pre></td></tr></table></div></figure>


<p>Since we&#8217;re pretty good on available RAM, there is a bunch of fun stuff we can do (<em><a href="http://sickbeard.com/">c</a><a href="http://couchpotatoapp.com/">o</a><a href="http://sabnzbd.org/">u</a><a href="http://www.transmissionbt.com/">g</a>h</em>)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting up a PPTP server on BuyVM]]></title>
    <link href="http://blog.marc-seeger.de/2011/03/18/setting-up-a-pptp-server-on-buyvm/"/>
    <updated>2011-03-18T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/03/18/setting-up-a-pptp-server-on-buyvm</id>
    <content type="html"><![CDATA[<p>I got myself a <a href="buyvm.net">BuyVM</a> VPS some time ago. For 15 USD a year you get 128 MB RAM (256 MB Burst), 15 GB HDD space and 500 GB / month.<br/>
Since they enabled GRE and have the proper modules in place, you can easily set up a PPTP server. I used the Ubuntu 10.10 images for this:</p>

<ol>
<li>apt-get install pptpd</li>
<li>open /etc/pptpd.conf and enter the following</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>localip 192.168.10.1  
</span><span class='line'>remoteip 192.168.10.101-200</span></code></pre></td></tr></table></div></figure>


<ol>
<li>echo 1 > /proc/sys/net/ipv4/ip_forward</li>
<li>edit /etc/ppp/chap-secrets and add a user (username [tab] pptpd [tab] password [tab] *)</li>
<li>set up the iptables rules and replace OUTBOUND_IP_ADDRESS with your server&#8217;s IP</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>iptables -A INPUT -p tcp --dport 1723 -j ACCEPT  
</span><span class='line'>iptables -A INPUT -p 47 -j ACCEPT  
</span><span class='line'>iptables -A FORWARD -i ppp+ -o venet0 -j ACCEPT  
</span><span class='line'>iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source OUTBOUND_IP_ADDRESS</span></code></pre></td></tr></table></div></figure>


<ol>
<li>edit /etc/ppp/pptpd-options and enter these options:</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>name pptpd  
</span><span class='line'>refuse-pap  
</span><span class='line'>refuse-chap  
</span><span class='line'>refuse-mschap  
</span><span class='line'>require-mschap-v2  
</span><span class='line'>require-mppe-128  
</span><span class='line'>proxyarp  
</span><span class='line'>lock  
</span><span class='line'>nobsdcomp  
</span><span class='line'>novj  
</span><span class='line'>novjccomp  
</span><span class='line'>nologfd  
</span><span class='line'>ms-dns 8.8.8.8  
</span><span class='line'>ms-dns 8.8.4.4</span></code></pre></td></tr></table></div></figure>


<p>If you want to make these permanent, edit /etc/sysctl.conf and make sure that &#8220;net.ipv4.ip_forward=1&#8221; doesn&#8217;t have a hash (#) in front of it.<br/>
After this, copy the iptables rules from above to /etc/rc.local so they are executed on boot.  <br/>
This should give you an IP from the US that you can connect to with your tech gadgets :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RoboMop]]></title>
    <link href="http://blog.marc-seeger.de/2011/03/13/robomop/"/>
    <updated>2011-03-13T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/03/13/robomop</id>
    <content type="html"><![CDATA[<p>I bought myself a RoboMop from <a href="https://www.amazon.de/dp/B001G4IG6O/ref=as_li_ss_til?tag=marblo-21&amp;camp=2906&amp;creative=19474&amp;linkCode=as4&amp;creativeASIN=B001G4IG6O&amp;adid=19P7HB00D24XP0SMJCFS&amp;">Amazon DE</a>/<a href="http://www.amazon.com/gp/product/B004HIOUS4/ref=as_li_ss_tl?ie=UTF8&amp;tag=masbl0b0-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=B004HIOUS4">Amazon US</a> and so far, I&#8217;m pretty happy. I just let it run for 90 minutes and it collects a fair amount of dust and hairs. It uses kind of a random walk algorithm to cover as much ground as possible. (60 sq. m per hour according to the packaging).<br/>
Since it&#8217;s the softbase version, it even gets into some of the harder to reach corners of my apartment. The only thing I&#8217;m not 100% sure about is, how often I should replace the electrostatic pads. For now, I just dust them off on the balcony and put them back on the mop.<br/>
Here&#8217;s a video of the little ball in action:</p>

<iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/QU4Wb1x-tFs" frameborder="0" allowfullscreen></iframe>


<p></p>

<p>You can get the electostatic replacement pads on <a href="https://www.amazon.de/dp/B00261M0UE/ref=as_li_ss_til?tag=marblo-21&amp;camp=2906&amp;creative=19474&amp;linkCode=as4&amp;creativeASIN=B00261M0UE&amp;adid=16V6R9GZH1BFNQZMG3X0&amp;">Amazon Germany</a> (13.99 Euros for 20 pads) and on <a href="http://www.amazon.com/gp/product/B004SC4TH6/ref=as_li_ss_tl?ie=UTF8&amp;tag=masbl0b0-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=B004SC4TH6">Amazon US</a> for 7 USD for 20. On Amazon.com, there is also an offer with <a href="https://www.amazon.com/dp/B000GFWSCM/ref=as_li_ss_til?tag=masbl0b0-20&amp;camp=213381&amp;creative=390973&amp;linkCode=as4&amp;creativeASIN=B000GFWSCM&amp;adid=1Z1CNYHEY20KVE1KGZY5&amp;">24 for 7.50 USD</a>, but I&#8217;m not quite sure if they fit 100% (robomaid <-> robomop).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Encrypted diskimages in OSX]]></title>
    <link href="http://blog.marc-seeger.de/2011/02/06/encrypted-diskimages-in-osx/"/>
    <updated>2011-02-06T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/02/06/encrypted-diskimages-in-osx</id>
    <content type="html"><![CDATA[<p>If you&#8217;re ever in the situation that you want to have sensitive/work data on your mac encrypted but also readily available to work with, you&#8217;ll probably want to use an encrypted disk image to store your files.
The main problem with the disc image is, that mounting it on boot isn&#8217;t the easiest thing to do.
Since there aren&#8217;t that many guides on it, I though I&#8217;d write one myself.
Without further ado, here is how you create an encrypted volume and automount it on boot:</p>




<ol>
<li>Open &#8220;Disc Utility&#8221; and click the new image icon: <br/><img alt="new image" src="http://blog.marc-seeger.de/assets/2011/02/06/00_new_image.png"/></li>
<li>Create a sparse bundle and be sure to enable encryption: <br/><img alt="new image" src="http://blog.marc-seeger.de/assets/2011/02/06/01_sparsebundle.png"/></li>
<li>Enter a password for it:<br/><img alt="new image" src="http://blog.marc-seeger.de/assets/2011/02/06/02_password.png"/></li>
<li>
After this, your image should be created and mounted. Go to the terminal and find out its disk device:<br/>  
<div class="CodeRay">
  <div class="code"><pre>    <span class="er">$</span> mount  
    [...]  
    <span class="rx"><span class="dl">/</span><span class="k">dev</span><span class="dl">/</span></span>disk1s2 on <span class="rx"><span class="dl">/</span><span class="k">Volumes</span><span class="dl">/</span></span><span class="co">My</span> personal stuff (hfs, local, nodev, nosuid, journaled, noowners, mounted by mseeger)  
</pre></div>
</div>
After you found out the device, check the image&#8217;s UUID:  
<div class="CodeRay">
  <div class="code"><pre>    <span class="er">$</span> diskutil info <span class="rx"><span class="dl">/</span><span class="k">dev</span><span class="dl">/</span></span>disk1s2 | grep <span class="co">UUID</span>  
    <span class="co">Volume</span> <span class="ke">UUID</span>:              <span class="i">8</span><span class="co">F37F1F3</span>-<span class="i">71</span><span class="co">EB</span>-<span class="i">35</span><span class="co">AA</span>-<span class="co">BED9</span>-<span class="i">237</span><span class="co">DCD2A0842</span>  
</pre></div>
</div>
  
There we go, our image&#8217;s UUID is 8F37F1F3-71EB-35AA-BED9-237DCD2A0842
</li>
<li>Create a folder you want to mount it to later</li>
<li>Open the system&#8217;s fstab files by typing &#8220;sudo vifs&#8221; into the terminal</li>
<li>Insert the following line, replace UUID and path with your values:  
<div class="CodeRay">
  <div class="code"><pre>    <span class="co">UUID</span>=<span class="i">8</span><span class="co">F37F1F3</span>-<span class="i">71</span><span class="co">EB</span>-<span class="i">35</span><span class="co">AA</span>-<span class="co">BED9</span>-<span class="i">237</span><span class="co">DCD2A0842</span> <span class="rx"><span class="dl">/</span><span class="k">Users</span><span class="dl">/</span><span class="mod">msee</span></span>ger/stuff hfs rw <span class="i">1</span> <span class="i">0</span>
</pre></div>
</div>
    
p.s. vifs will put you in VI, so just press &#8216;i&#8217; to get into insertion mode and [escape], :wq, [enter] to save the file
</li>
<li>Drag the sparse image into your user&#8217;s &#8220;login items&#8221; (System Preferences) and it will be automatically mounted on boot. Since the image&#8217;s key will be placed into the keychain that you unlock when you login, the image will be ready to use at the designated folder :)</li>
</ol>




<p>That&#8217;s it, have fun :)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Binaergewitter NoSQL]]></title>
    <link href="http://blog.marc-seeger.de/2011/01/14/binaergewitter-nosql/"/>
    <updated>2011-01-14T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2011/01/14/binaergewitter-nosql</id>
    <content type="html"><![CDATA[<p>I recently was part of the first episode of the (German language) podcast &#8220;Binaergewitter&#8221; (roughly: Binary thunderstorm).<br/>
The first episode had &#8220;NoSQL&#8221; as a topic and the four of us talked for 2 1/2 hours about everything in the NoSQL space. We hopefully gave a pretty decent overview over the subject. People seem to like it so far :)<br/>
If you always wanted to know what column stores, datastructure stores, document stores, key value stores and graph databases are and German is your cup of tea, you should give it a go.<br/>
Here&#8217;s the <a href="http://blog.radiotux.de/2011/01/09/binaergewitter-1-nosql/">link</a>.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Adding flattr to serious]]></title>
    <link href="http://blog.marc-seeger.de/2010/12/19/adding-flattr-to-serious/"/>
    <updated>2010-12-19T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/12/19/adding-flattr-to-serious</id>
    <content type="html"><![CDATA[<p>After giving it a bit of thought, I decided to reactivate my <a href="http://www.flattr.com/">flattr</a> account. Since the flattr API improved a lot since flattr&#8217;s early beta days, I thought it would be nice to integrate the auto submission feature with <a href="http://github.com/colszowka/serious">Serious</a>, my current (ruby based) blogging engine of choice.<br/>
This blog post will discuss the paramaters that can be used to automatically add the buttons.</p>




<p>The first thing to do will be inserting the javascript part of the integration into our /views/layout.erb file. This file contains (among other things) the header that is part of every page. This code doesn&#8217;t need any customization and can just be copied into the head section of the HTML</p>




<div class="CodeRay">
  <div class="code"><pre>&lt;script type=&quot;text/javascript&quot;&gt;
/* &lt;![CDATA[ */
    (function() {
        var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];

        s.type = 'text/javascript';
        s.async = true;
        s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';

        t.parentNode.insertBefore(s, t);
    })();
/* ]]&gt; */
&lt;/script&gt;
</pre></div>
</div>




<p>The HTML part of the API has to be added to the &#8220;/views/_article.erb&#8221; template that is responsible for diaplaying the actual content of each blogpost.<br/>
In this case, just replace the &#8220;data-flattr-uid&#8221; value with your fattr username.</p>




<div class="CodeRay">
  <div class="code"><pre><span class="ta">&lt;a</span> <span class="an">class</span>=<span class="s"><span class="dl">&quot;</span><span class="k">FlattrButton</span><span class="dl">&quot;</span></span> <span class="an">style</span>=<span class="s"><span class="dl">&quot;</span><span class="k">display:none;</span><span class="dl">&quot;</span></span> <span class="an">title</span>=<span class="s"><span class="dl">&quot;</span><span class="k">&lt;%= article.title %</span></span><span class="er">&gt;</span>&quot; data-flattr-uid=&quot;rb2k&quot; data-flattr-category=&quot;text&quot; href=&quot;<span class="c">&lt;%= Serious.url + article.url %&gt;</span>&quot;<span class="er">&gt;</span><span class="c">&lt;%= article.title %&gt;</span><span class="ta">&lt;/a&gt;</span>
</pre></div>
</div>




<p>This should be it, happy flattr&#8217;ing</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My thesis - building blocks of a scalable webcrawler]]></title>
    <link href="http://blog.marc-seeger.de/2010/12/09/my-thesis-building-blocks-of-a-scalable-webcrawler/"/>
    <updated>2010-12-09T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/12/09/my-thesis-building-blocks-of-a-scalable-webcrawler</id>
    <content type="html"><![CDATA[<p>In my last semester as a student, I had the chance of working for an awesome company (<a href="http://acquia.com/">Acquia</a>) on a very interesting project. It all started with a <a href="http://buytaert.net/drupal-site-crawler-project">post</a> over at Dries Buytaert&#8217;s blog. He is the CTO and co-founder of Acquia (and Mollom), inventor of Drupal, open-source celebrity and also knows a thing or two about FPGA-aware garbage collection :).<br/>
I had a great time with a lot of brilliant people and learned tons and tons about datastructures, scalability, nosql, ruby and asynchronous I/O.<br/>
This thesis documents my experiences trying to handle over 100 million sets of data while keeping them searchable. All of that happens while collecting and analyzing about 100 new domains per second.
It covers topics from the different Ruby VMs (JRuby, Rubinius, YARV, MRI) to different storage-backend (Riak, Cassandra, MongoDB, Redis, CouchDB, Tokyo Cabinet, MySQL, Postgres, &#8230;) and the data-structures that they use in the background.<br/>
Long story short, here we go: [<a href="http://blog.marc-seeger.de/assets/papers/thesis_seeger-building_blocks_of_a_scalable_webcrawler.pdf">PDF</a>]</p>




<div align="center">
<div style="width:477px" id="__ss_6088058"></strong><object id="__sse6088058" width="477" height="510"><param name="movie" value="http://static.slidesharecdn.com/swf/doc_player.swf?doc=thesisseeger-buildingblocksofascalablewebcrawler-101209041009-phpapp01&rel=0&stripped_title=building-blocks-of-a-scalable-webcrawler&userName=marc.seeger" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse6088058" src="http://static.slidesharecdn.com/swf/doc_player.swf?doc=thesisseeger-buildingblocksofascalablewebcrawler-101209041009-phpapp01&rel=0&stripped_title=building-blocks-of-a-scalable-webcrawler&userName=marc.seeger" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="477" height="510"></embed></object></div>
</div>




<p>p.s. acquia is <a href="http://acquia.com/careers">hiring</a> ;)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Added caching to my blog]]></title>
    <link href="http://blog.marc-seeger.de/2010/12/09/added-caching-to-my-blog/"/>
    <updated>2010-12-09T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/12/09/added-caching-to-my-blog</id>
    <content type="html"><![CDATA[<p>I decided to beef up my current infrastructure a bit by adding a proper caching layer to my blog.<br/>
<a href="http://github.com/colszowka/serious">Serious</a>, my current blogging engine of choice, already generates proper HTTP Cache-Control headers as can be seen in its sinatra <a href="https://github.com/colszowka/serious/blob/master/lib/serious.rb">routing file</a>:</p>




<div class="CodeRay">
  <div class="code"><pre>  before <span class="r">do</span>
    headers[<span class="s"><span class="dl">'</span><span class="k">Cache-Control</span><span class="dl">'</span></span>] = <span class="s"><span class="dl">&quot;</span><span class="k">public, max-age=</span><span class="il"><span class="idl">#{</span><span class="co">Serious</span>.cache_timeout<span class="idl">}</span></span><span class="dl">&quot;</span></span>
  <span class="r">end</span>
</pre></div>
</div>




<p>Since I like to keep my application logic out of the webserver, I decided to use <a href="http://tomayko.com/">Ryan Tomayko</a>&#8217;s <a href="http://rtomayko.github.com/rack-cache/">rack-cache</a> middleware.<br/>
While using the nginx-internal caching feature might be the faster solution, I like the feeling that I can actually read the sourcecode easily if I ever happen to encounter bugs.</p>




<p>When looking at the headers of my blog, you can now see a new attribute called &#8220;X-Rack-Cache&#8221;.<br/>
When hitting a page that wasn&#8217;t in the cache, it looks like this:</p>




<div class="CodeRay">
  <div class="code"><pre>Age: 0  
X-Rack-Cache: miss, store
</pre></div>
</div>




<p>and if you happen to hit something cached, you&#8217;ll see this:</p>




<div class="CodeRay">
  <div class="code"><pre>Age: 217  
X-Rack-Cache: fresh  
</pre></div>
</div>




<p>The &#8220;Age&#8221; header will tell you how many seconds ago the HTML had been generated. I currently set the maximum cache vaildity time to 300 seconds. If you happen to hit something in the cache that is OLDER than 300 seconds, you should see this:</p>




<div class="CodeRay">
  <div class="code"><pre>Age: 0  
X-Rack-Cache: stale, invalid, store
</pre></div>
</div>




<p>Trying to see if the added caching actually made a difference was pretty satisfying:</p>




<p><strong>Before</strong></p>




<div class="CodeRay">
  <div class="code"><pre>$ ab -kc 10 -t 30 http://blog.marc-seeger.de/
Server Software:        nginx/0.8.52
Concurrency Level:      10
Time taken for tests:   30.058 seconds
Complete requests:      420
Failed requests:        0
Write errors:           0
Keep-Alive requests:    420
Requests per second:    13.97 [#/sec] (mean)
Time per request:       715.662 [ms] (mean)
Time per request:       71.566 [ms] (mean, across all concurrent requests)
Transfer rate:          150.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.4      0      16
Processing:    89  704 873.3    530    9556
Waiting:       72  654 870.6    498    9539
Total:         89  705 873.5    530    9556

Percentage of the requests served within a certain time (ms)
  50%    530
  66%    572
  75%    613
  80%    671
  90%   1055
  95%   1448
  98%   2804
  99%   5267
 100%   9556 (longest request)
</pre></div>
</div>




<p><strong>After</strong></p>




<div class="CodeRay">
  <div class="code"><pre>
$ ab -kc 10 -t 30 http://blog.marc-seeger.de/

Server Software:        nginx/0.8.52
Concurrency Level:      10
Time taken for tests:   30.007 seconds
Complete requests:      7165
Failed requests:        0
Write errors:           0
Keep-Alive requests:    7099
Requests per second:    238.78 [#/sec] (mean)
Time per request:       41.880 [ms] (mean)
Time per request:       4.188 [ms] (mean, across all concurrent requests)
Transfer rate:          2203.54 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.6      0      18
Processing:    18   42  69.4     34    2433
Waiting:       17   39  64.9     32    2401
Total:         18   42  69.8     34    2433

Percentage of the requests served within a certain time (ms)
  50%     34
  66%     37
  75%     40
  80%     43
  90%     61
  95%     74
  98%     86
  99%    121
 100%   2433 (longest request)
</pre></div>
</div>




<p>Not too shabby :)</p>




<p>p.s. when configuring rack-cache, the &#8220;allow_reload&#8221; <a href="http://rtomayko.github.com/rack-cache/configuration">option</a> should be set to false unless you want to allow everybody to forcefully ignore your cache.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Prime numbers in Ruby]]></title>
    <link href="http://blog.marc-seeger.de/2010/12/05/prime-numbers-in-ruby/"/>
    <updated>2010-12-05T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/12/05/prime-numbers-in-ruby</id>
    <content type="html"><![CDATA[<p>Just a little experiment to see how fast I could generate prime numbers in Ruby.<br/>
The <a href="http://shackspace.de/">shackspace</a> public mailing list had a fun little thread where people would implement an algorithm to find primes in the first 2500000 numbers.
While I knew that Ruby wouldn&#8217;t score well on the performance side of things, I thought I could at least give it a try and see how Ruby 1.9.2, Rubinius and JRuby would perform in the end.</p>




<p>Here is the code, a simple sieve of eratosthenes:</p>




<div class="CodeRay">
  <div class="code"><pre><span class="r">def</span> <span class="fu">prime_sieve_upto</span>(n)
  all_nums = (<span class="i">0</span>..n).to_a
  all_nums[<span class="i">0</span>] = all_nums[<span class="i">1</span>] = <span class="pc">nil</span>
  all_nums.each <span class="r">do</span> |p|
    <span class="c">#jump over nils</span>
    <span class="r">next</span> <span class="r">unless</span> p
    <span class="c">#stop if we're too high already</span>
    <span class="r">break</span> <span class="r">if</span> p * p &gt; n
    <span class="c">#kill all multiples of this number</span>
    (p*p).step(n, p){ |m| all_nums[m] = <span class="pc">nil</span> }
  <span class="r">end</span>
  <span class="c">#remove unwanted nils</span>
  all_nums.compact
<span class="r">end</span>

starting = <span class="co">Time</span>.now
amount = <span class="i">2500000</span>
primes = prime_sieve_upto(amount)
puts <span class="s"><span class="dl">&quot;</span><span class="k">Found </span><span class="il"><span class="idl">#{</span>primes.size<span class="idl">}</span></span><span class="k"> in the numbers from 0 to </span><span class="il"><span class="idl">#{</span>amount<span class="idl">}</span></span><span class="k"> in </span><span class="il"><span class="idl">#{</span><span class="co">Time</span>.now - starting<span class="idl">}</span></span><span class="k">s</span><span class="dl">&quot;</span></span>
</pre></div>
</div>




<p>On my Macbook Pro (2.6 GHz Core2Duo), the different VMs perform as follows:</p>




<p>ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]:<br/>
$ ruby prime_fast.rb<br/>
Found 183072 in the numbers from 0 to 2500000 in 3.543216s</p>




<p>rubinius 1.1.1 (1.8.7 release 2010-11-16 JI) [x86_64-apple-darwin10.4.0]<br/>
$ rbx prime_fast.rb<br/>
Found 183072 in the numbers from 0 to 2500000 in 1.333367s</p>




<p>UPDATE:<br/>
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.4.0]<br/>
$ rbx prime_fast.rb<br/>
Found 183072 in the numbers from 0 to 2500000 in 1.277507s</p>




<p>JRuby 1.5.6:<br/>
$ java -Xmx1024m -jar Downloads/jruby-complete-1.5.6.jar prime_fast.rb<br/>
Found 183072 in the numbers from 0 to 2500000 in 1.804s</p>




<p>Nice to see rubinius up there :)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Shared Groups in Prosody]]></title>
    <link href="http://blog.marc-seeger.de/2010/11/24/shared-groups-in-prosody/"/>
    <updated>2010-11-24T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/11/24/shared-groups-in-prosody</id>
    <content type="html"><![CDATA[<p>My favourite Jabber Server (<a href="http://www.prosody.im">Prosody</a>) has a plugin to automatically inject groups into a persons roaster.<br/>
I use this at my university to create groups for every semester (MIB1, CSM3, &#8230;) and fill them with the students using a ruby script that dumps LDAP.<br/>
My initial problem was that the injected contacts didn&#8217;t have a name but just their JID. The <a href="http://prosody.im/doc/modules/mod_groups">mod_groups documentation</a> doesn&#8217;t mention anything related to names, but the <a href="https://github.com/bjc/prosody/blob/master/plugins/mod_groups.lua">sourcecode</a> of the module has this interesting line:</p>




<div class="code">
<pre>local entryjid, name = line<span class="sy">:match</span>(<span class="s"><span class="dl">&quot;</span><span class="k">([^=]*)=?(.*)</span><span class="dl">&quot;</span></span>);</pre>
</div>




<p>This assigns a value to the two variables according to the matches that the regular expression returns.<br/>
So to have the names injected, the groups.txt file has to have the JID and the name seperated by an equals sign. So this is what the format looks like:</p>




<div class="code"><pre>
username@jabberserver.com=John Doe  
anothername@jabberserver.com=Jane Doe  
</pre></div>




<p>This way, you can inject jids AND names :)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Printing from commandline in OSX]]></title>
    <link href="http://blog.marc-seeger.de/2010/11/24/printing-from-commandline-in-osx/"/>
    <updated>2010-11-24T00:00:00+01:00</updated>
    <id>http://blog.marc-seeger.de/2010/11/24/printing-from-commandline-in-osx</id>
    <content type="html"><![CDATA[<p>I just had to print out >10 pictures and didn&#8217;t actually want to open each one of them and print it individually.<br/>
An easy solution in OSX for this is to use the &#8220;lp&#8221; utility which will be able to print out a lot of formats (e.g. pictures or pdf files).<br/>
If you don&#8217;t want to use the default printer, just look up what the one you want is called by using:</p>




<div class="CodeRay">
  <div class="code"><pre><span class="er">$</span> lpstat -a
</pre></div>
</div>




<p>and then printing the files using (in my case: a bunch of jpeg files):</p>




<div class="CodeRay">
  <div class="code"><pre>lp -d <span class="s"><span class="dl">&quot;</span><span class="k">my_printer_name</span><span class="dl">&quot;</span></span> *.jpg
</pre></div>
</div>




<p>If you just want to use the default printer, you can leave away the -d option.</p>

]]></content>
  </entry>
  
</feed>

