Push notifications of continuous integration to your iPhone

G. Schmidt / Wednesday, July 22, 2009

The iPhone OS 3.0 brought push notifications to most of finnlabs' mobile devices (iPhone is dominating here). Since we are big fans of Continuous Integration, I wanted to see whether or not we could get notifications about our build status to our phones. It turned out to be rather simple. By combining a) a great iPhone application, b) simple APIs, and c) open source work by others, we were able to achieve this goal.

The Ingredients

Prowl is an iPhone application, that allows to forward Growl notifications to your iPhone via Apple’s push notification technology. In fact, your message is passed from Growl to the Prowl-Growl-Plugin to a Prowl server to an Apple server to your phone. Additionally Prowl offers an API for third party applications such that you are able to use the Prowl infrastructure (servers and iPhone client) for your own good, independent from a running OS X machine.

Prowler is a RubyGem, that wraps a simple Ruby API around Prowl’s web service. This enables every ruby application to sent push notifications using any given Prowl API key.

ShortURL is a RubyGem, that wraps an even simpler Ruby API around multiple URL shortening services. Its as simple as that.

CruiseControl.rb is our favorite Continuous Integration server. We are hosting an instance for over a year now here at finnlabs. Every project is hooked up there. Generally we are monitoring the build status using the build server’s web page or CCMenu. Actually, we never set up the email notifications for build changes, since there was no need to do so.

What we did

CruiseControl.rb knows a simple yet powerful plugin architecture, which allows arbitrary ruby code to be executed on certain build events. By using the above mentioned Prowler gem and the the EmailNotifier bundled with CruiseControl.rb itself, we were able to implement a simple CruiseControl.rb plugin called ProwlNotification. It sends notifications each time the build status of a certain project changes.

If configured correctly, the message will include a link to the project page on your CruiseControl.rb server, so that all necessary information is right at hand. If present, ProwlNotification uses the ShortURL gem to shorten the link.

Get it as well

All that was left to do was writing documentation and installation instructions. You may find everything on the GitHub project page. The code is published under an MIT-style license, so you are able to change and tweak it to your needs. Of course, we would love to here, how you like it.

Enjoy.

Hurray: 9th birthday SiN/Finn GmbH!

T. Lindenthal / Sunday, July 19, 2009


Last week, Finn GmbH celebrated its 9th birthday. We have come a long way since then. Founded as a provider of educational content and webservices in the heydays of the dot-com euphoria, we soon offered software development to a distinct group of clients. Solid craftsmanship and fast adaptation was recession-proof. We continued to flourish even when many fellow-companies had to shift several gears down in the following years. Today, finnlabs offers a broad range of services and own products – and is more fun than ever.

This is a good moment to thank our team and clients, our business partners and advisors, our friends and family for their excellent teamwork, support, help, and inspiration. Cheers to everyone!

Bringing HTML 5 features to every browser, today

G. Schmidt / Thursday, July 16, 2009

Just like Bruce Lawson on sitepoint.com says: «Yes, You Can Use HTML 5 Today!» Besides new HTML elements, HTML 5 brings lots of new features to JavaScript and the DOM-API as well. One of these new features is the hashchange event.

The hashchange event

Whenever you follow an internal link on a website, the portion of the URL behind the # in the location bar and the browser’s history is updated. This enables easy browsing within large documents. With AJAX-enabled websites, changing the location hash was also used to store a certain navigation step with the same page, without being directly related to page internal links. This technique brings history support and bookmarkability – two important features of a browser – to these sites. The DOM-API implemented in current browsers simply does not allow for capturing changes of the location hash directly.

HTML 5 will overcome this shortcoming. Here, every time the location hash changes (either by following an internal link, using the Back button, a bookmark, or by changing the hash in the location bar) an event will be triggered that can be listened to by any JavaScript function.

Current state

As of today, only Internet Explorer 8 supports the new event. In all other browser this behavior needs to be simulated. This is generally done by constantly polling the state of the location hash and comparing stored and current values. Managing the polling function and triggering the right actions may become tedious, especially when multiple actions need to be run.

jQuery.observeHashChange plugin

In order to make use of the new functionality in HTML 5 and Internet Explorer 8 while still supporting older browsers, we compiled a jQuery plugin that gives you a cross platform, jQuery-like API. The API always tries to use the best possible function, so when other browsers start to support for the hashchange event, your application will benefit automagically.

This page provides a live example. Besides our new plugin, the site features new HTML 5 elements to structure the content. It already works in all major browsers, today. (Please note, that the layout won’t work in Internet Explorer 6, but this is related to missing CSS features.)

As usual, we have released the plugin on GitHub page.

Modularise HAProxy's configuration files

H. Just / Friday, June 26, 2009

finnlabs uses HAProxy to balance the requests on the application servers powering our clients web applications. We recommend this fantastic piece of software to anybody as it scales almost infinitely in terms of throughput and concurrent connections. It is even that efficiently designed that under extreme loads most of the times not HAProxy becomes the bottleneck but the underlying operating system.

Unfortunately, HAProxy’s configuration is not very flexible. What was missing the most is some kind of “include” mechanism to split up the single large configuration file into smaller modules (at least in my opinion and according to posts of others in the mailing list).

As a workaround I developed a small python script which takes bits of configuration from a well-defined directory structure and assembles the single configuration file. Including a call to this script into the init script of HAProxy mimics an include mechanism. The script can be downloaded from github. A modified init script based on the one which comes with the HAProxy package of Debian (originally written by Arnaud Cornet) can also be found there. You might need to update the path values in the script.

The script expects a certain fixed directory hierarchy. The top-level directory names are fixed. The other names can be chosen arbitrarily. Note that the second level directory names end up as section names in the final configuration file. Choose your names so that they are accepted by HAProxy. An example directory tree for the configuration is given below. If you put that tree below the /etc/haproxy the script will work out of the box and create the /etc/haproxy/haproxy.cfg file.

  • global
    • 00-base
    • 10-log
  • defaults
    • 00-base
    • 10-errorfiles
  • frontends
    • my-first-frontend
      • 00-ports
      • 10-acls
      • 20-backend1
      • 21-backend2
    • my-second-frontend
  • listen
    • sect1
      • 00-base
      • 10-backend1
    • sect2
  • backends
    • my-first-backend
      • 00-base
      • 10-server1
      • 11-server2
    • my-second-backend

DNND.de in the "meedia"

T. Lindenthal / Tuesday, June 02, 2009

DNND caught the attention of Meedia.de - a portal serving German news professionals with in-depth coverage of the industry. With a sympathetic dose of understatement Meedia.de introduces itself as a “source of information for anyone interested in the media sector”.

DNND is a hobby-horse project of the finnlabs founders. It aggregates the top headlines of German and international news providers on one page. The service is special as it picks those headlines that have been selected to be most important by the professional editors of the different sources (and not e.g. select on publication date only). This crowdsourcing approach gives a unique cross-section through the current state of the public discourse.

DNND is online for 10 years by now. Yes, it is a web 1.0 dinosaur.

The full interview (in German) can be found here.

Fixing jQuery autocomplete plugin for Opera browsers

G. Schmidt / Thursday, May 28, 2009

At finnlabs we are using the jQuery library in all current web development projects. JQuery allows for writing the functionality we need in fewer lines of code and thus eases maintainability and minimizes bugs and errors. The great variety of available JQuery plugins offers us the possibility to stand with our JavaScript applications “on the shoulders of giants”.

Autocompletion of text fields is a very common task and thanks to the jQuery autocomplete plugin straight forward to implement for most modern web browsers. It works great in most use cases and has enough hooks and whistles to extend its functionality for individual needs.

Unfortunately all Opera browsers at hand (Version 9.x) show an annoying bug. When the Ajax request returns without results, the suggestion list is removed and the cursor is placed at the beginning of the text input. This is a real burden for power users.

During a quick investigation it turned out, that $.Autocompleter.Selection is causing the trouble. The main purpose of this function is either to select portions of text in the autocompleted input element (when the autoFill option is used) or to place the cursor behind the last character (when an element is selected from the suggestions list). With the help of feature detection the best implementation is selected.

$.Autocompleter.Selection = function(field, start, end) {
    if( field.createTextRange ){
        var selRange = field.createTextRange();
        selRange.collapse(true);
        selRange.moveStart("character", start);
        selRange.moveEnd("character", end);
        selRange.select();
    } else if( field.setSelectionRange ){
        field.setSelectionRange(start, end);
    } else {
        if( field.selectionStart ){
            field.selectionStart = start;
            field.selectionEnd = end;
        }
    }
    field.focus();
};

I’m not an expert concerning feature detection. I always try to avoid browser dependent code and use cross-platform libraries instead. Here is no way around, so I started guessing: createTextRange is Microsoft’s approach, setSelectionRange and selectionStart are both the Mozilla way. Opera seems to support createTextRange, but obviously not in the right way, hence the bug. By simply switching priorities and starting to look for setSelectionRange first everything magically started to work fine. Here is our new version:

$.Autocompleter.Selection = function(field, start, end) {
    if( field.setSelectionRange ){
        field.setSelectionRange(start, end);
    } else if( field.createTextRange ){
        var selRange = field.createTextRange();
        selRange.collapse(true);
        selRange.moveStart("character", start);
        selRange.moveEnd("character", end);
        selRange.select();
    } else if( field.selectionStart ){
        field.selectionStart = start;
        field.selectionEnd = end;
    }
    field.focus();
};

Sometimes it is that simple.

In order to better track the code changes, we just released the fixed code in our GitHub repository. You can find minimized and packed versions of our updates there as well.

Siemens AG: multi-language knowledge management

W. Lindenthal / Thursday, May 14, 2009

A truly global production company, Siemens AG employs 430,000 people in 190 countries. This international presence implies a large number of employees work in languages other than their native tongue. English, thanks to Siemens’ localisation mechanisms and training programs, has become its unifying corporate language. When it comes to communication, finnlabs supports Siemens in the field of e-learning. Our engagement at Siemens signifies the development of a major training initiative: user-centric translation services. We reduce language barriers encountered by trainees, thus increasing quality, user acceptance, and learning effect.

Our collaboration had two major components. First, finnlabs re-designed Siemens’ deployed glossary mechanism. This tool plays a key role in their corporate knowledge management and training programs. It centrally maintains uniform definitions and concepts used in subsidiaries across the globe. One can easily access these terms through a web service such as the Siemens intranet and can embed them in a multitude of training manuals and other educational material. finnlabs combined all aspects of glossary content management into one intuitive web interface. Editors do not need to possess technical skills to roll-out changes, which are deployed in real time. Definitions do not have to be hard-coded into training content, which drastically reduces development and maintenance costs. Multiple roles and a clear access concept allow for content design and maintenance in varying steps.

The second challenge of our project was to reduce language-based friction in the training process. The most direct approach would have been prohibitively expensive and out of reach: to translate all documents into every language used within Siemens. finnlabs’ response provides technology-driven language solutions which enable employees to work confidently with material in English or German, without being native speakers in either tongue. We provide high quality translations of training content in the user’s native language. Beside company and industry-specific vocabulary, we integrate extensive general dictionaries, ensuring users receive support for basic requests. Employees do not have to leave the training environment for assistance.

iPhone app: media management

N. Lindenthal / Tuesday, May 05, 2009

mm1 Consulting & Management is a leading consultancy in the telecommunication industry. It has a long and illustrious history of managing extensive product-development projects for major European operators.

finnlabs joined with mm1 to design and prototype a media management client for Apple’s iPhone. The application syncs pictures and other media content between the iPhone and an online media application, such as a photo-sharing website. The power of the system lies in its intuitive user interface and its economic use of the handheld’s resources. An exceptionally small bandwidth footprint allows rich service while minimizing strain on data carrier networks.

PONS.eu: the best of both worlds

T. Lindenthal / Friday, May 01, 2009

PONS GmbH, Stuttgart, is a leader in both German dictionary publishing and in marketing language-learning products and services. Since 2000, PONS has relied on finnlabs’ technology for all their online dictionaries and web-based language services.

finnlabs’ newest product is the multi-language dictionary platform PONS.eu. We enriched and integrated the renowned quality print content into a high-performance web application, designed to serve millions of queries a day. The system scales with demand, insuring PONS against future IT expenses, and revenues from higher popularity of its services are not eaten up by exploding service costs.

PONS.eu encourages users to contribute their own content. Utilising the potential of the web’s crowd intelligence is a bold step not yet taken by other established publishing houses.

The system’s key technical feature is its combination of the strengths of different programming languages. Components which require high performance, like the sophisticated dictionary search, are written in Java. This gives the system high speed and a low computing footprint. Services with more extensive functions but fewer performance requirements are written in Ruby, capitalising on its low development costs. finnlabs uses JRuby to seamlessly integrate these two different programming languages. PONS.eu has helped establish finnlabs’ reputation for running one of the first high-performance web services based on JRuby world-wide.

The latest edition of the Economisch Statistische Berichten (very broadly speaking the Dutch answer to the Economist) features an article by Thies Lindenthal and Prof. Piet Eichholtz. The authors analyse a possible collapse of housing demand caused by decreasing population numbers in the southern Dutch Parkstad agglomeration. Referring to experiences in Eastern German cities, an integrated demolition program is suggested for peripheral areas suffering from population losses.

The full article can be downloaded here (ESB-login needed).