Motorcycle Adventures and Free Software
Henri Bergius
Biker, free software consultant, neogeographer

See also my JavaScript blog, The Universal Runtime

There is a total of 861 posts.

Weblog

Open Mobile Linux, this Saturday in FOSDEM

Posted on 2012-02-02 08:55:37 UTC in 60° 9.792 N 24° 55.662 E Helsinki, FI to . 0 comments.

As mentioned in the earlier call for presentations, we're running a track on Open Mobile Linux in FOSDEM this Saturday. Room AW1.120 at the ULB campus in Brussels. From the CfP:

Our primary goal is to facilitate meetups, collaboration and awareness between different projects and communities within Open Mobile Linux and provide a place to present directions, ideas and your projects themselves.

By Open Mobile Linux we mean any open source projects revolving around typical non-desktop/server Linux, such as handsets, tablets, netbooks or other creative uses. Examples of such projects could be Qt5, Mer, MeeGo, Android, webOS, Plasma Active, Tizen, Boot to Gecko, SHR and other related efforts.

There are several exciting things happening in this space, including the recently announced Spark tablet, open sourcing of webOS's Enyo framework and continuing interest in the Maemo platform. Saturday's program includes:

If there are any last-minute announcements or happenings that people want to discuss, we may be a ble to squeeze in a talk or two. Contact Carsten about this.

Also, if you want to chat other things (like PHPCR or CreateJS), I'll be around the whole weekend including the beer event. Drop me an SMS.

Looking forward to seeing as many of you there as possible!

Sponsored links

save money using, phone card

Midgard2 PHPCR provider hits 1.0

Posted on 2011-12-23 10:03:14 UTC in 60° 9.792 N 24° 55.662 E Helsinki, FI to . 0 comments.

I'm happy to announce that we were able to release the first stable version of the Midgard2 PHPCR provider yesterday.

Simply put, PHPCR is the future of Midgard's PHP API. Instead of having our own repository APIs, we follow the well-documented and tested PHP Content Repository specification. This allows much better compatibility with other projects, and for example the possibility to choose whether to store contents in Midgard2 or Apache Jackrabbit on per-deployment basis. This obviously doesn't mean that the current Midgard2 API is going away, but just that there is something better and more compatible available on top of that.

PHPCR provides a nice set of capabilities that are either similar to, or surpass the traditional Midgard features:

  • Your content model is constructed out of a tree of Nodes that can contain other Nodes or Properties
  • Properties can be of many different types, including the typical strings and floats, but also binaries (similar to our blobs) and dates
  • Properties can be multivalued (think of multiple images in same property, or a person having multiple emails)
  • Queries can be either constructed with Query Object Model or SQL2
  • Queries support tree constraints (ISDESCENDANTNODE, ISCHILDNODE) and joins
  • Content can be exported and imported via a standard XML format
  • There is a comprehensive Node Type system that allows you to define your content model. The full definitions can be read and introspected via PHP
  • Nodes also support mixins, allowing you to add per-object metadata
  • There are also the unstructured nodes (nt:unstructured) for cases where you don't want to have constraints on what to store and how

On top of PHPCR, there is also a Doctrine ODM that the Midgard2 provider also supports. That gives you more capabilities, like:

Some code examples: https://github.com/bergie/phpcr-midgard2/tree/master/examples

You can see Midgard's test status for both SQLite and MySQL storage back-ends in our Continuous Integration environment: phpcr-midgard2.png

Once you have Midgard2 and our PHP extension available, installation is easy. Add a composer.json file into the root folder of your project:

{
"require": { "midgard/phpcr": ">=1.0" }
}

Install with Composer:

$ wget http://getcomposer.org/composer.phar
$ php composer.phar install

Copy MgdSchemas:

$ sudo cp vendor/midgard/phpcr/data/share/schema/* /usr/share/midgard2/schema/
$ sudo cp vendor/midgard/phpcr/data/share/views/* /usr/share/midgard2/views/

...and then just start using the repository in your application. PHPCR can obviously be used side-by-side with traditional Midgard2 or other PHP code.

What will happen next:

  • Support for PHP 5.4 and Postgres (needs work on Midgard2 level)
  • Performance optimization
  • Features work, including versioning
  • More tools for PHPCR. Think of Asgard that would allow you to work with any repositories!
  • PHPCR support built-in for MidCOM and MVC?

For those interested in learning more about PHPCR, there will also be a Paris meetup in mid-January.

Using CoffeeScript for GNOME development

Posted on 2011-12-16 16:04:16 UTC in 47° 48.570 N 13° 3.300 E Salzburg, AT to . 0 comments.

In Suski's blog I saw a question on whether developing GNOME apps would be possible in CoffeeScript. The answer is yes. I wrote a quick example back in Desktop Summit:

# GObject Introspection APIs are available from imports.gi.Modulename
Gtk = imports.gi.Gtk

# For GNOME 3.2+ this should be Gtk.init null, 0
Gtk.init 0, null

win = new Gtk.Window
type: Gtk.WindowType.TOPLEVEL
win.set_border_width 10
win.connect "destroy", (widget) ->
Gtk.main_quit()

button = new Gtk.Button
label: "Hello, world"
button.connect "clicked", ->
button.set_label "Bar"
win.add button

button.show()
win.show()

Gtk.main()

Gjs doesn't run CoffeeScript directly, so you need to convert this before running:

$ coffee -c window.coffee 
$ gjs window.js

You should see something similar to:

gjs-coffee-example.png

Call for presentations: Open Mobile Linux at FOSDEM 2012

Posted on 2011-12-14 09:46:57 UTC in 47° 48.570 N 13° 3.300 E Salzburg, AT to . 0 comments.

At FOSDEM 2012 we will have a devroom related to Open Mobile Linux. Our primary goal is to facilitate meetups, collaboration and awareness between different projects and communities within Open Mobile Linux and provide a place to present directions, ideas and your projects themselves.

By Open Mobile Linux we mean any open source projects revolving around typical non-desktop/server Linux, such as handsets, tablets, netbooks or other creative uses. Examples of such projects could be Qt5, Mer, MeeGo, Android, webOS, Plasma Active, Tizen, Boot to Gecko, SHR and other related efforts.

We have the room AW1.120 with 74 seats, a video projector (VGA), wireless internet on Saturday 4th February for a total of 8 hours.

The format we will be utilizing is lightning talks of length 15 minutes with 10 minutes of questions, 5 minute changeover to next speaker. Our goal is about 15 talks during the day.

The motivation is that after each talk, you and your project will be visible to the rest of the Open Mobile Linux community and further deeper discussions into your topic with your peers can continue outside the devroom.

Please send a short biography and an abstract for your talk to carsten.munk@gmail.com by Dec 31st 2011, and we'll get back to you at latest January 7th.

We're also grateful for volunteers helping to run the devroom. Contact Carsten if you're interested.

Composer solves the PHP code-sharing problem

Posted on 2011-11-02 00:01:06 UTC in 60° 10.188 N 24° 56.292 E Helsinki, FI to . 7 comments.

In PHP we've had a lousy culture of code-sharing. Because depending on code from others as been tricky, every major PHP application or framework has practically had to reimplement the whole world. Only some tools, like PHPUnit, have managed to break over this barrier and become de-facto standards across project boundaries. But for the rest: just write it yourself.

But now Composer, and its repository counterpart Packagist, promise to change all that. And obviously new conventions like PHP's namespacing support and the PSR-0 standard autoloader help.

Composer is heavily inspired by NPM which has built a strong culture of code-sharing and easy deployment in the Node.js community.

Easy for users

With Composer, managing dependencies in your project is very easy. Simply create a composer.json file where you state your dependencies, and let the package management system worry about the rest.

Packages that are registered with packagist.org are obviously easiest to depend on, but you can also state packages coming from custom repositories (like your company's internal version control system), or PHP extensions that you need.

Here is for example the composer.json from the Midgard PHPCR provider:

{
    "name": "midgard/phpcr",
    "type": "library",
    "require": {
        "php": ">=5.3.0",
        "ext-midgard2": ">=10.05.5",
        "phpcr/phpcr": ">=2.1.0-beta1"
    }
}

With this file, Composer knows that our PHPCR provider runs only on PHP 5.3 or newer (as it uses namespaces), and that it needs the Midgard PHP extension and the PHPCR interface classes to be available.

Now installing the project is easy:

$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install

How about autoloading? Traditionally PHP required you to manually include or require all files you wanted to use in your code, with the possibility to write an autoloader to handle it automatically when you call an undefined class. But managing these autoloaders is also a chore.

Composer helps here too, by automatically generating an autoloader that will be able to load your own code, and the code from all your dependencies. So you can get rid of your own autoloaders and include statements, and just include the Composer-generated autoloader in your code:

require 'vendor/.composer/autoload.php';

After this all the classes you've stated your application needing will be available.

Easy for developers

While ease-of-installation is important, it isn't enough to build an ecosystem. The other thing that has to be easy is publishing code. Basically: if you've written a piece of functionality in PHP that you could see yourself using in another project, it should be effortless to publish it as a library.

This is where approaches like PEAR mostly failed, by making it too cumbersome to define your packages, to build them, and to upload them to the repository.

With Composer this is very easy. You again define a composer.json for your package, and push that to your project's Git repository. Then just register the Git repository URL with packagist.org.

After this Packagist will spider your repository and make it available as a package.

Publishing new versions is very easy: simply keep your composer.json up-to-date, and tag your releases in Git.

Where are we now?

It is still early days for Composer, and the project is being worked on at a hectic pace. However, it is already good enough for managing dependencies to modern, PSR-0 compatible libraries.

What I would like to see happen next is support for custom package roles and autoloaders. This would allow us to handle more specific cases, like for example installation of Midgard MVC components and their non-namespaced autoloading needs. After that we should be able to get rid of our custom installer code and just join the Composer crowd.

But if your code is already fully namespaced, this is a great time to get started with Composer.

DNode: Make PHP and Node.js talk to each other

Posted on 2011-10-31 11:50:50 UTC in 60° 10.188 N 24° 56.292 E Helsinki, FI to . 0 comments.

If you've been following my blog, you might have noticed that lately I've started doing quite a lot of Node.js development alongside PHP. Based on conversations I've had in various conferences, I'm by far not alone in this situation - using Node.js for real-time functionality, and PHP (or Django, or Rails) for the more traditional CRUD stuff.

Both environments have their strong points. Node.js is very fast and flexible, but PHP has a lot more mature tools and libraries available. So in a lot of projects it is hard to choose between the two. But now you might not have to.

Enter DNode

DNode is a remote method invocation protocol originally written for Node.js, as the name probably tells. But as the protocol itself is quite simple, just sending newline-terminated JSON packets over TCP connections, implementations have started popping up in other languages. You can talk DNode in Ruby, Perl, Python, Java, and now PHP.

I started working on the PHP DNode implementation in the Symfony CMF hackday in Cologne a week ago, and got it into a running stage on a train ride from there to Paris. The implementation isn't yet complete, but works already quite well.

With DNode you can expose Node.js functions to be available on PHP, and PHP class methods to be available on Node.

Like most Node.js functionality, DNode works asynchronously. So instead of waiting for return values you supply a callback function that will be called when the method completes.

PHP as client

Here is a simple DNode service for Node.js:

var dnode = require('dnode');
var server = dnode({
    zing: function (n, cb) { cb(n * 100) }
});
server.listen(7070);

This creates a DNode service running in TCP port 7070 that provides one method: zing that multiplies the value given to it by 100 and sends the result to the callback provided.

Calling this with PHP is easy:

// Connect to DNode server running in port 7070 and call 
// Zing with argument 33
$dnode = new DNode\DNode();
$dnode->connect(7070, function($remote, $connection) {
    // Remote is a proxy object that provides us all methods
    // from the server
    $remote->zing(33, function($n) use ($connection) {
        echo "n = {$n}\n";
        // Once we have the result we can close the connection
        $connection->end();
    });
});

Now just start the server:

$ node simple/server.js

And run the client. As you can see from the PHP code above, once we get the result the client will end the connection automatically:

$ php examples/simple/client.php 
n = 3300

Because only simple TCP connections and JSON packets are used, this is quite fast. Here are time results for the client on my MacBook Air:

real    0m0.064s
user    0m0.050s
sys     0m0.010s

PHP as a server

PHP can also act as a DNode server. You instantiate the DNode class and pass it the object you want to expose via DNode. All public methods of the object will be made available to the DNode clients:

// This is the class we're exposing to DNode
class Zinger
{
    // Public methods are made available to the network
    public function zing($n, $cb)
    {
        // Dnode is async, so we return via callback
        $cb($n * 100);
    }
}

// Create a DNode server
$server = new DNode\DNode(new Zinger());
$server->listen(7070);

This DNode service will obviously be visible for both Node.js and PHP clients.

Bidirectional communications

A DNode client can also expose methods to the server. In this example the server provides functionality for converting temperatures from Celsius to Fahrenheit, but actually gets the current Celsius temperature by asking it from a client.

Server:

// This is the class we're exposing to DNode
class Converter
{
    // Poll the client's own temperature() in celsius
    // and convert that value to fahrenheit in the supplied 
    // callback
    public function clientTempF($cb)
    {
        // The other side of DNode connection is exposed via
        // $this->remote proxy object
        $this->remote->temperature(function($degC) use ($cb) {
            $degF = round($degC * 9 / 5 + 32);
            $cb($degF);
        });
    }
}

// Create a DNode server that listens to port 6060
$server = new DNode\DNode(new Converter());
$server->listen(6060);

Client:

// This is the class we're exposing to DNode
class Temp
{
    // Compute the client's temperature and stuff that value
    // into the callback
    public function temperature($cb)
    {
        $degC = rand(-20, 50);
        echo "{$degC}° C\n";
        $cb($degC);
    }
}

$dnode = new DNode\DNode(new Temp());
$dnode->connect(6060, function($remote, $connection) {
    // Ask server for temperature in Fahrenheit
    $remote->clientTempF(function($degF) use ($connection) {
        echo "{$degF}° F\n";
        // Close the connection
        $connection->end();
    });
});

Then just start the server:

$ php examples/bidirectional/server.php

And run the client:

$ php examples/bidirectional/client.php 
28° C
82° F

The same will obviously work with a Node.js client:

$ node bidirectional/client.js 
23° C
73° F

Installing DNode

dnode-php can be installed using the Composer tool. You can either add dnode/dnode to your package dependencies, or if you want to install dnode-php as standalone, go to the main directory of its repository and run:

$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install

You can then use the composer-generated autoloader to access the DNode classes:

require 'vendor/.composer/autoload.php';

Some DNode examples can be found from the examples folder. They are compatible with the similarly-named examples from Node.js DNode.

Contributing

php-dnode is developed under the MIT license in GitHub. If you're interested in it, please watch the repository and send issues or pull requests.

Where is the future for openness in mobile?

Posted on 2011-10-03 17:53:42 UTC in 60° 0.000 N 24° 0.000 E 28km S of Lojo, FI to . 1 comments.

These are tough times for fans of open mobile environments. Android is less and less open, Symbian was closed again, HP stopped making webOS devices, and now Intel abandoned MeeGo to work with Samsung and operators instead. So, what is the community to do?

One option is to follow the lead of the big companies, hoping that Tizen works, or that Google again sees the benefit of working with others in the open.

The other is to take the matters in our own hands. There is precedent for this. Much of early Linux activity came from the efforts of the community, not on the initiative of corporate interests. And there have been OpenMoko and Mer, the latter an attempt to make a fully open version of Nokia's Maemo environment, suspended when MeeGo promised to bring the same benefits.

Well, now Mer is back.

mer-400.jpg

The goals for Mer align pretty well with what the community would need:

  • To be openly developed and openly governed as a meritocracy
  • That primary customers of the platform are device vendors - not end-users.
  • To provide a device manufacturer oriented structure, processes and tools: make life easy for them
  • To have a device oriented architecture
  • To be inclusive of technologies (such as MeeGo/Tizen/Qt/EFL/HTML5)
  • To innovate in the mobile OS space

There have also been some other invitations to new potential homes for the community, ranging from openSUSE to Debian.

It will be interesting to see how this works out. But whatever we as a community do, we should ensure we look at more than just licensing.

Business analytics with CouchDB and NoFlo

Posted on 2011-09-21 17:52:53 UTC in 47° 0.000 N 13° 0.000 E 48km SE of Saalfelden am Steinernen Meer, AT to . 0 comments.

The purpose of business analytics is to find data from the company's information systems that can be used to support decision making. What customers buy most? What do they do before a buying decision? What are the signs that a customer may be leaving?

For the last month we've been working in Salzburg to build such a system, the Intelligent Project Controlling Tool needed for running large collaborative research projects like IKS. Since the design we went with can be reused for other business analytics needs, I wanted to write a bit about it.

But first, here is how our system looks like:

Proggis displaying IKS project plan

Where does the data come from?

There are many ways to gather business data. Often the information systems already contain the data needed. But it may also be hidden in a jungle of spreadsheets. Or maybe some data is simply not available, and has to be filled in manually.

Handling all these cases in one system is a tricky question. To solve it, we went with a two-layered strategy:

  • All data used for analytics is stored as Linked Data in a CouchDB system
  • NoFlo workflows are used for gathering data from the diverse sources and convert it to the format needed

In IKS's case, much of the data was available in a series of spreadsheets. With these, we built the necessary workflows for first converting the spreadsheets into XML with Apache Tika, and then extracting the information from them in a sensible subset of JSON-LD.

Because IKS is a collaborative project, information needs to be gathered from a diverse group of partner organizations. Some of them have systems that provide the needed APIs (like Basecamp, which we use), and we can just periodically import the data. But with many we decided on a simple data interchange approach: spreadsheets handled over email.

In this approach, user files a data request into the system. This gets picked up by NoFlo, which sends an email with the appropriate spreadsheet template to the partner. Then it starts waiting for a reply. When a reply arrives, it extracts the data from the attached spreadsheet and imports it to the system.

Our NoFlo processes are mostly initiated by the CouchDB change notification API. We keep them running persistently using forever Node, so whenever some operation needs to be run it happens nearly immediately.

Ensuring data consistency

With any automation, and especially with the email-based data interchange, things can go wrong. Because of this we tag all data that we receive with its origin, whether it was some automated operation or an imported spreadsheet. These origins are called execution documents. Users can browse all completed workflow executions and see what data came in from them. These can then be either accepted or rejected.

This way if some partner accidentally sends faulty data, or something else breaks, the incorrect information received can be easily removed. CouchDB's versioning capabilities help here.

Analyzing the data

CouchDB is built on top of the concept of map/reduce. Here you can modify and combine the data in lots of different ways using simple JavaScript functions. In our case we elected to write all our CouchDB code in CoffeeScript for simplicity. For example, here is the reduce function in CoffeeScript that counts totals of time planned, time used, and time left per task or partner in a project:

(keys, values, rereduce) ->
    roundNumber = (rnum, rlength) ->
        Math.round(parseFloat(rnum) * Math.pow(10, rlength)) / Math.pow(10, rlength)
    data =
        planned: 0.0
        spent: 0.0
        left: 0.0

    if rereduce
        for reducedData in values
            data.planned += reducedData.planned
            data.spent += reducedData.spent
        data.left = data.planned - data.spent
        return data

    for doc in values
        if doc['@type'] is 'effortallocation'
            data.planned += roundNumber doc.value, 1
        if doc['@type'] is 'effort'
            data.spent += roundNumber doc.value, 1
    data.left = roundNumber data.planned - data.spent, 1
    return data

If you figure out a new way to look at the data you have, simply write the needed map and reduce functions and save them into the database. CouchDB will then run them against existing data and produce numbers.

Data visualizations

Numbers are good, but to really see the information buried in them you need some visualizations. For this we decided to follow the CouchApp idea where the user interface code is stored in the database together with the data itself. This way no application servers are needed, and you can take the whole system with you just by replicating the database. Think of the possibility of doing some analysis on your company while flying to a meeting!

The visuals are in our case provided by JavaScript InfoVis Toolkit, a nice, MIT-licensed interactive graph library.

CouchDB views handle the number crunching, then CouchDB list functions process the numbers into the format needed for visualization. This leaves only a minimal amount of work for the client side.

For consistency our application has been built with CoffeeApp, so all the database and user interface code is in CoffeeScript.

In a nutshell

Any business analytics system dealing with moderate amounts of data can be built following this approach.

Simple architecture for a business analytics system

This way you have a business analytics environment that is easy to extend with more data when it becomes available. New analysis can be done by writing reasonably simple map/reduce functions, and CouchDB's replication capabilities allow you to take the system and data with you.

Using JSON-LD for the data storage makes a lot of sense, as this way the relations between different pieces of information are easy to handle. And using URIs for data identifiers means you can easily mash up information coming from different sources together.

The two-layered approach of using NoFlo for data imports, and CouchDB for analysis also allows for clean separation of concerns. In our case, I did the workflow part of things, and Szaby built the visualizations.

VIE 2.0 is starting to emerge

Posted on 2011-09-21 15:01:28 UTC in 47° 0.000 N 13° 0.000 E 48km SE of Saalfelden am Steinernen Meer, AT to . 0 comments.

VIE is a JavaScript library that makes RDFa-annotated entities on web pages editable. We started the work towards the next major version of it, codenamed Zart (for Mozart) in a Salzburg IKS hackathon couple of weeks ago.

VIE

Yesterday I merged the Zart codebase into the VIE repository. This blog post describes some of the improvements it brings.

VIE now has an instance

For VIE 1.x users the first visible change (and probably the only necessary API change) is that now VIE needs to be instantiated before being used. Singletons are evil, and so we are not a singleton any longer.

So, for existing VIE code, you need to:

var vie = new VIE();
// and then any traditional VIE calls, like:
var entities = vie.RDFaEntities.getInstances('div.article');
console.log("There are " + entities.length + " RDFa entities in your articles");

The VIE 1.0 API can be disabled by passing a setting when instantiating VIE:

var vie = new VIE({classic: false});

Services and VIE

The other big change in VIE is that now the API has been built in a service-oriented manner. This means that for example reading and writing RDFa is just a service you can enable and disable at will.

The benefit here is that we can easily add support for other formats and capabilities without having to touch VIE internals. Thanks to the schema.org situation, Microdata is getting more use, and so at some point we'll probably add a service for it.

Registering and accessing services is easy:

// Instantiate VIE
var vie = new VIE();

// Pass the service instance and a name you want to use for it
vie.use(new vie.RdfaService, 'rdfa');

// Call a method from the service using the name
// this one would give us the RDF subject of the
// element matched by the jQuery selector
vie.service('rdfa').getElementSubject('div.article');

An immediate benefit here is that we can have two RDFa parsing implementations. If you have problems with our own custom jQuery-based RDFa parser, then you can use the more strict rdfQuery powered implementation instead:

vie.use(new RdfaRdfQueryService, 'rdfa');

Using deferreds

For the new main VIE API we created a sort of a Domain-Specific Language for handling semantic entities. A core part of it is that now all operations utilize jQuery's Deferred objects. With them you can attach different callbacks to the results of your operation, and they will fire either when the operation completes, or immediately if the operation has already been run.

This gives a lot of flexibility in using the API, and allows us to provide same API for services that deal with the DOM, and services that talk to external APIs like Stanbol.

For example, parsing RDFa from a given DOM element (provided with a jQuery selector) happens like this:

vie.load({
        element: 'div.article'
    }).
    from('rdfa').
    execute().
    done(function(entities) {
        console.log(entities);
    });

The chain here is: operation (in this case, load), from service (rdfa), execute operation, then when done, do callback.

With the RDFa service we register Backbone Views for the elements our entities came from, so just like with VIE 1.x, they will update automatically when you change the contents of your entities. But manual writing is also available in case you need it. Here is how it works:

vie.save({
        element: 'div.article',
        entity: someBackboneModel
    }).
    to('rdfa').
    execute().
    done(function() {
        console.log("Saved!");
    });

In addition to done, which fires if the operation succeeds, you have fail for failed operations, and then which fires regardless of success or failure.

Accessing external services

The new VIE is not just about RDFa. In addition to working with the entities you have on a page, you can also access external repositories of semantic information, like DBpedia.

For example, to find out everything that Wikipedia knows about Salzburg, you could run:

vie.use(new vie.DBPediaService, 'dbpedia');
vie.load({
        entity: '<http://dbpedia.org/resource/Salzburg>'
    }).
    using('dbpedia').
    execute().
    done(function(entity) {
        console.log("This is what we know of Salzburg");
        console.log(entity);
    });

In browser usage these calls to external services are subject to cross-domain AJAX limitations. A way to work around those is to set up a proxy, and tell the DBpedia service to use that. To do this, pass the proxy URL to the service when instantiating:

vie.use(new vie.DBPediaService({proxyUrl: 'http://localhost:8080'});

With this, all the factual information from Wikipedia will be at your disposal. The size of every city, the height of every mountain. Birthdates and places of birth for famous people. Your web app can do quite a bit with this information.

Finding entities from text

Apache Stanbol is a semantic engine that can extract all kinds of entities from text documents. It can be used for auto-tagging and other things.

Here is how you can use it with VIE:

vie.use(new vie.StanbolService, 'stanbol');
vie.analyze({
        element: 'div.article'
    }).
    using('stanbol').
    execute().
    done(function(entities) {
        console.log("We got the following enhancements for article content");
        console.log(entities);
    });

Stanbol can tell you what a piece of content talks about. People mentioned, places, concepts. It will also give you the language of the text.

Moving forward

The new version of VIE is still under heavy development. Most of the thngs work, but some details may still change. It is a good idea to start taking a look at it now, but before a beta release at least, VIE 1.0 is the recommended tool to use.

If you already use VIE 1.0 for making your content editable, VIE 2.x will give you a lot of additional power. Enhancements, data queries, namespace handling, and much more.

Thanks to Szaby and Sebastian for helping to make this happen!

GObject Introspection is coming to Node.js

Posted on 2011-09-12 00:27:13 UTC in 60° 9.834 N 24° 55.734 E Helsinki, FI to . 1 comments.

GObject Introspection (GIR) is a way to create automatic bindings to GNOME libraries for various different programming languages. I've written before about the benefits of bringing GIR to PHP, and now it seems something similar is happening on Node.js.

node-gir has been written by Tim Caswell, with help from Sebastian Wick and Piotr Pokora.

I've been following the progress for a while, and today, during a flight from Helsinki to Salzburg, I was finally able to open a Midgard repository connection with it. The API still is a bit weird, and lacks support for the asynchronous nature of Node, but those will hopefully change soon. Quick example:

var Midgard, gir, config, mgd;
gir = require("../gir");
gir.init();
Midgard = gir.load("Midgard");
Midgard.init();

// Use a local SQLite database file
config = new Midgard.Config();
config.__set_property__("dbdir", __dirname);
config.__set_property__("dbtype", "SQLite");
config.__set_property__("database", "midgard");

// Open connection to the database
mgd = new Midgard.Connection();
if (!mgd.__call__("open_config", config)) {
    console.error("Failed to open connection");
    process.exit();
}

node-gir is being developed on GitHub if you want to lend a hand or try it out. To build it, run npm install and you should be able to run the code examples.

Having GIR support for Node would make it a full-fledged GNOME environment, and mean that there would be proper GObject Introspection in all three major JavaScript runtimes - SpiderMonkey, JavaScriptCore and V8. And this way GNOME JavaScript developers could also utilize the wealth of existing Node.js modules.