A little Jabber bot with Twisted Words
Tue 30 January 2007 — Bot, Jabber, Twisted Words, Python, XMPP
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.
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 — Maths, Semantic Web, Social, Ruby
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.
- Génération d’une matrice d’adjacence ;
- Calcul des profondeurs respectives des noeuds vis-à-vis d’un noeud choisi ;
- 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 — How to, Javascript, Packer
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 — API, Bikini Test, PHP, REST, Upcoming
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 — Real Life, Job, 2006, Feedback
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.