January 2007

A little Jabber bot with Twisted Words

Tue 30 January 2007, , , ,

Jabber is my favorite IM protocol for years and not only because of this Open Source license but for its open minded approach. You can choose which server will provide you your service. I could be your company, a server in your country or Google because GTalk is build on top of Jabber (they just added Jingle for the sound supports). (BTW I’m waiting for Telepathy for my (stable) GNU/Linux box.)

That matter isn’t about Jabber or not here, but about a tool that lots of people are intrigued about, Bots. I’m not talking about Spambot but a chatting bot. Mine is very easy and it does quite nothing. Like a hello world, it’s interesting because you can see what is the power underlying a concept or a technology.

First of all, you need a jabber account (not a Google one, see bellow). Now let’s start by importing everything that is required for this from the Twisted Words libraries.

from twisted.words.protocols.jabber import client, jid
from twisted.xish import domish, xmlstream
from twisted.internet import reactor

Now, create the client. JID stands for Jabber ID.

me = jid.JID("greutly@swissjabber.ch/TwistedWords")
factory = client.basicClientFactory(me, "password")

The client works with callbacks, it’s event driven here. The one that is required is relative to the authentication.

def authd(xmlstream):
  # need to send presence so clients know we're
  # actually online.
  presence = domish.Element(('jabber:client', 'presence'))
  presence.addElement('status').addContent('Online')
  
  xmlstream.send(presence)
  
  # add a callback for the messages
  xmlstream.addObserver('/message', gotMessage)

The callback called gotMessage will receive the incoming messages and display them directly.

def gotMessage(message):
  # sorry for the __str__(), makes unicode happy
  print u"from: %s" % message["from"]
  for e in message.elements():
    if e.name == "body":
      print unicode(e.__str__())
      break

Now set the authentication callback to the factory.

factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, authd)

And go!

reactor.connectTCP("swissjabber.ch", 5222, factory)
reactor.run()

The previous example doesn’t work with GMail account because they require TLS (that isn’t support for my version of Twisted Words). It seems that in the trac their is a support for TLS but I didn’t search much more longer in this direction.

The little script that is above. There is another one that will answer you when you talked to him. It reverses the words in the sentence you gave it before answering you.

Gaim screenshot

Have fun! Twist’n’shout!

Jabber étant mon outil d’IM privilégié depuis quelques années, je me suis aujourd’hui amusé à franchir le pas des gens réels, pour approcher le monde du bot. Certains d’entre vous connaissent certainement Twitter qui permet de publier directement via Jabber. Simple rapide et efficace (par toujours réactif, mais généralement rien ne se perd).

Donc voici, un petit bot à tester vous-même, avec votre compte jabber, évitez si possible GTalk car ce dernier utilise TLS et je ne me suis pas amusé avec ça pour l’instant. Selon mes recherches dans le Trac du projet les éléments y nécessaires devraient être présents.

Une fois de plus, un article technique où la partie croustillante se trouve en anglais. Je suis à votre écoute si question il y a : greut@swissjabber.ch.

Could social web be a graph?

Wed 24 January 2007, , ,

While I’m playing with LinkedIn there are some questions that comes to me.

  • How to play with all these relations?
  • Is it hard to know at which level is this person from me?
  • Or if he/she is in my network at any level?
  • Is this kind of Semantic Web? Or be expressed this way? (obviously yes, be easily, I can’t tell)

I remembered the math lessons from two or three years ago, I love mathematics more than ever now. Hard to pratice during lunch time. Friendship is a graph, instead of RDF not directed. And friendship could represented as a Simple Graph. So I tried to do a graph Graphviz that is cool for displaying them and Ruby because I need to more (and more) about it and the way you can hack things with it.

For the math part, I started with the Adjacency Matrix that is a pretty simple 0 or 1 n✕n matrix.

Next step is to generate a .dot file to GraphViz. This is easy.

A rich information should be at which level from the given node are the others? What I need is a function that gives me the levels of the nodes from the current one. It require only a few minutes of braining, and more to code it (especially with my poor experience, but I’m working on it, with Ruby).

And the result could be, this nice picture. Use this script this way (remove the tube part to see the .dot file):

./graph.rb 26 .93 | dot -Tgif -o graph.gif

Parameters are 26 nodes and 93% chance of unknowing another node.

My conclusion is that even with only few connections by node, the depth of the friend’s friend is very low and that it’s hard to obtain deep levels. I think that people in a modest town can reach everybody in it with only 3 or 4 levels.

Alors que je joue avec LinkedIn tout un tas de questions me viennent à l’esprit, spécialement en matière de web social et de réseau (ce dernier ne fait que du réseautage et depuis peu du social avec partimonie).

  • Comment font-ils pour jongler avec toutes ces relations ?
  • Est-ce complexe de savoir à quel niveau se trouve telle ou telle personne de moi ? Voire connaître si elle fait partie de mon réseau ou non ?
  • Ceci peut-il être fait en passant par le Web Sémantique ? Si oui, comment de manière légère, SPARQL (via FOAF) me semblant lourd, l’est-il ?

Cogitant avec tout ça, j’ai ressorti les vieilles mathématiques du tiroir, j’apprécie beaucoup les maths mais c’est difficile d’en faire régulièrement une fois sorti d’un cadre scolaire je trouve. Spécialement, si on ne veut pas être considéré comme une espèce d’autiste (l’autisme étant bien évidemment complétement différent dans 99.9% des case)

Le modèle de base de relations entre personnes est le graphe, dit graphe simple car sans boucle ni multiple liens. Ce graphe peut être représenté par sa matrice d’adjacence qui se compose de 0 et de 1, un 1 indiquant un lien entre les deux noeuds.

Une fois ce modèle identifié, mon idée a été de pouvoir générer des graphes et les visualiser simplement. L’outil de visualisation a coulé de source : Graphviz qui est aussi simple que flexible. Ensuite, j’ai choisi le langage Ruby pour générer le format lu par ce dernier, nommé DOT. Ruby car, j’ai du travail de dégrossissage avec ce langage là pour commencer à en faire un bon usage.

Le système fonctionne ne trois étapes.

  1. Génération d’une matrice d’adjacence ;
  2. Calcul des profondeurs respectives des noeuds vis-à-vis d’un noeud choisi ;
  3. Génération d’un fichier au format DOT.

Un résultat est visible ici. Il a été généré via ce script avec le jeu de commandes suivant qui va générer un graphe de 26 noeuds qui ont chacun 93% de chance de ne pas avoir de relation avec un autre noeud donné.

./graph.rb 26 .93 | dot -Tgif -o graph.gif

En conclusion de cette petite expérimentation je dirais qu’il n’est pas si compliqué de jouer avec ses relations (tout en restant à des niveaux raisonnables) et que de mettre au point un modèle entité-relation représentant ces principes là ne me semblent pas hors de portée. Autre point intéressant (et plutôt sociologique pur que geek pur) étant qu’il faut malgré tout peu de relations pour que la profondeur soit faible, qu’un noeud puisse atteindre tous les autres rapidement. Je pense que dans une ville de dimension modeste, une personne doit pouvoir en 3 ou 4 niveau atteindre tout le monde.

Plus personnellement, je n’ai jamais aimé en rencontrant quelqu’un et me disant que c’était une personne complètement nouvelle de me rendre compte qu’on a un bon bout de nos d’amis, connaissances qui sont communs. Avoir joué au scientifique fou, va peut-être me rendre plus ouvert pour ces aspects là.

How to write compressible JavaScript

Sun 21 January 2007, ,

If you ever tried to use the Packer of Dean Edwards, you probably constating that your script don’t work anymore. It happens to me and I found what did I do wrong.

This cool tool that compress and obfuscate your Javascript code do, at first, an inlining operation. NB: I use the PHP5 script. If Javascript is very cool about syntax, it isn’t anymore when code is inlined. In the following example I will put the mandatory semicolons (;) for uncompressed script in bold. These semicolons are required in inlined code.

var a=0;
var b=2;

if(a > b) {
	var text = "a is bigger than b";
	console.warn(text)
}

for(var i=0; i<b;i++)
	console.log(i + "/" + b);

function C(value) {
	var c = value
}

C.prototype.compare = function(value) {
	if(this.c == value)
		return 0;
	else if(this.c > value)
		return 1;
	else
		return -1
};

Every ; can be removed if you don’t want to compress your JS file.

By the way an intersting project called Fork Javascript that aims to get the best of Prototype and YUI.

Ayant récemment dû corriger certains des scripts Javascript que j’ai écrit pour qu’il soit aisément comprimable par le merveilleux outil développé par Dean Edwards nommé Packer, voici une rapide explication de comment s’y prendre.

Le packer en question va tout d’abord mettre le code JavaScript sur une ligne, supprimer les commentaires avant de le compresser. Hélas pour que l’interpréteur puisse lire du code en ligne il faut qu’il soit convenable écrit, donc avec des point-virgules (;) là où c’est nécessaire.

Le code ci-contre est truffé de points-virgule mis en gras (;). Ceux-ci ne sont pas nécessaire dans cette forme là et peuvent être aisément supprimés sans affecter l’évaluation du script mais son requis si le dit script est voué à être compressé.

Les buts de la compression sont : le gain de bande passante (des points de vue du client et du serveur) et l’offuscation (cacher un minimum comment est fait le code, bien que...).

Working with the Upcoming API

Sun 14 January 2007, , , ,

I managed to put some extra functionalities to the admin area of the Bikini Test. Now they can directly published their events to Upcoming.org (that belongs to Y!).

There is two (not sexy) screenshots of it, it’s a little bit of Ajax and some glue code.

An sample code of how this works (I’ve wrote some classes in PHP4 for this purpose). You can read before the Token-based Authentication of the Upcoming API.

<?php # -*- coding: utf8 -*-
// http://upcoming.org/services/api/keygen.php
$api_key = '##########';
// http://upcoming.org/services/auth/?api_key=<API_KEY>
$frob = '###.....###';

include(dirname(__FILE__).'/upcoming.lib.php');
$upcoming =& new Upcoming($api_key, $frob);
$upcoming->authGetToken();
?>
<h1>Agenda</h1>
<dl>
<?php
// Bikini Test
$venue =& new Venue();
$venue->id = 37518;
// an adapted event.search
$events = $upcoming->eventSearchByVenue($venue);
foreach($events as $event) {
?>
  <dt>
    <a href="<?= $event->url ?>">
      <?= $event->name; ?>
    </a>
  </dt>
  <dd>
    <?= $event->description; ?>
  </dd>
<?php
}
?>
</dl>

This will show the events of the Bikini Test Venue. It’s really easy and powerful. The library isn’t complete enough to decently authorize me to publish it here and now. If you are interested by it, contact me.

The API was painful and sometimes buggy but I think that in a couple of month it gonna be strong enough to avoid the strange behaviours I’ve met. So, “Is Upcoming ready for you?” The answer is no if you have business in mind, not yet, but yes if it’s for the fun.

J’ai offert à la sompteuse interface d’administration du Bikini Test la possibilité de publier des évènements sur Upcoming, directement.

Comme vous pouvez le voir dans le code d’exemple ci-dessous (à gauche), il est assez simple de jouer avec ça. Le système communique grâce à l’API du service qui permet de faire des recherches, de gèrer ses évènements, etc. C’est une API se basant sur l’architecture REST via HTTP, donc qui ne demande pas de connaissances de XML-RPC ou SOAP (par exemple). Les réponses sont fournies dans un format XML, se lisant avec un parseur ou, comme je l’ai fait rapidement, des expressions régulières.

Attention c’est service qui ne doit pas être utilisé dans un but lucratif et il souffre encore, d’une certaine jeunesse. J’ai été confronté a des problème avec la gestion des tags qui semble leur en poser également. N’hésitez pas à me contacter si vous êtes désireux de jouer avec cette librairie, elle est hélas un peu trop rudimentaire pour que j’ose décemment la publier ici.

Past, present and future

Thu 04 January 2007, , ,

We are in 2007 and I wanna just do a little feedback about the full-of-things year 2006. Very personal maybe boring, just like this blog.

First of all, I get my Bachelor in Science of Computer Science (formerly Diplôme HES) at la HE-ARC of Le Locle (Switzerland). The last project I worked on was a neurosurgerical software for brain disease in wxPython/VTK (for the EPFL).

Then, in the end of february, I leaved La Chaux-de-Fonds for a five months social work at La Branche (near Lausanne). I worked with mentally disabled people during their day-job. A very growing experience. This work was required in a alternative to the obligatory swiss army that isn’t anymore compatible with my philosophy.

During this period I started this blog, and started to look for my first true job. Is this a pure hazard?

I moved to Zürich, Moûtier, Lausanne and Dublin to show my face. It’s pretty hard to have a person in front of that is searching what you are and for doing what you want to. Bullshit is not the way to find a job I think, but sometimes it seems that it can work.

In August a Monday, I posted a comment in a blog, his boss called me the same day and I got an interview the day after and a “temporary” job on Thursday. My actual job, sounds crazy or too easy but, here I am today.

I mention temporary because of another pending job offer that finally didn’t append. I had my driving license to finish and, maybe, living a first experience in a city not too far from where I come isn’t a bad idea. My first expectaction was to leave Switzerland, now it’s the second. I want to do this before getting too old and less flexible to can.

When Dublin collapsed, I definitively moved to Lausanne, sharing a flat with this old dude Batiste and a friend of him’s girlfriend.

I worked on various projects involving PHP/MySQL with lots of Ajax to start, the crappy ActionScript 2.0 afterwards and for the end of the Year some XHTML/CSS integration, design fix with some DHTML things (mainly unobtrusive) with jQuery.

Now at the beginning of this new year, I want to push my knowledge and my curiosity further and share them with people. The thing that makes me sad is that I didn’t meet, here in Lausanne, people that are open enough to that, an underground network or a secret society exists maybe.

I think that 2007 will be another year with lots of activities in my working life, personnal one and social one.

Nous voici en 2007, j’ai le désir de lancer un petit coup d’oeil dans le rétroviseur et un autre sur la ligne d’horizon en bon départ.

Fin janvier, j’ai terminé mon diplôme d’ingénieur HES à la HE-ARC du Locle, avec soulagement, la vie d’étudiant commençant à me lâsser. Le travail de diplôme a porté sur un logiciel de simulation d’opération de neurochirurgie destiné à l’EPFL.

Ceci terminé, j’ai entamé les 5 mois qu’il me restaient à faire dans le cadre du service civil au sein de l’association La Branche. De participer au travail quotidien de personnes handicapées mentales a été une expérience humainement très enrichissante.

Pendant cette période, j’ai commencé ce blog et mes recherches d’emploi, aucun rapport. N’en croyez rien, c’est un complot rondement mené et pensé.

Mes recherches m’ont conduit à Zürich un vendredi printanier, à Lausanne et Moûtier début juillet, puis Dublin. Des expériences très intéressantes d’entretiens d’embauche.Un seule poignée de main et vous savez déjà si vous en serez ou pas, tous différents, tous semblables les entretiens. Une entreprise qui vous interroge techniquement vaut certainement la peine d’être considéré, le reste c’est du bullshittage pur. Manager, pensez-y !

En août, un commentaire dans un blog local, suivi d’un coup fil, puis un entretien et pof! un job. Fou, magnifique, étrange. Oubliez JobUp, Monster ou CFI, le réseau fait la différence aujourd’hui. Il faut montrer sa gueule, être visible.

Ensuite, des projets orienté plus ou moins Web 2.0, plus ou moins funky, plus ou moins plaisant mais qui m’ont permis de faire un intéressant tour d’horizon. Ce n’est pas pour autant que je pense pouvoir me positionner, mais peut-être juste ne pas me positionner.

Sinon, un permis de conduire qui est au jour d’aujourd’hui si onéreux que je m’en félicite toujours et ai parfois de la peine à en être conscient, moi qui ai déjà tant de peine à monter dans un bus juste par plaisir de marcher, le nez au vent.

Actuellement, je vis à Lausanne, y travaille, y est installé simplement, l’esprit frivole.

L’année qui est maintenant amorcée, va m’être de se que je sens, également pleine de rebondissements, d’évènements. Je n’ai pas oublié où je veux aller, pas oublié de continuer de me demander régulièrement où je veux aller. Même si où n’est pas la question mais où pour quoi faire amorce déjà un début de réponse. Pour l’instant, je n’ai pas trouvé de lieu, de gens qui me permettraient d’échanger ce que mon avide curiosité technique me fait découvrir, tester dès que le temps me le permet.