TransBot
Suite à l’article sur Twisted, framework réseau, une autre application des Bots XMPP : un client MUC permettant de traduire les messages.
L’origine de ce Bot était de pourvoir discuter par Chat XMPP avec mes cousines d’espagne sans être limité par le barrière de la langue.
Apertium
Il existe de nombreux outils de traduction, mais Apertium, développé initialement par l’Université d’Alicante, me semblait le plus adapté à une traduction Français / Espagnol, et qui plus est il est sous license GPL ;)
P.I. ce logiciel s’installe très facilement sous Debian/Ubuntu via un classique apt-get install apertium-fr-es
.
P.S. le dépot d’Ubuntu n’est pas à jour, il faut passer par un PPA :
$ wget http://apertium.projectjj.com/apt/install-nightly.sh
$ sudo bash ./install-nightly.sh
$ sudo aptitude update # the script above did this, but…
$ sudo aptitude install apertium-en-es apertium-fr-es apertium
$ echo “Eso es un test” | apertium es-en
This is a test
MUC Bot XMPP
Nous allons créer notre classe MUCTranslateBot
comme sous classe de MUCClient
, et non comme un sous-protocole de MUCClientProtocol
, de manière à pouvoir surcharger la méthode receivedGroupChat
.
En effet, MUCClient
implémente receivedGroupChat
qui fait la distinction entre les messages mettant à jour le sujet de la salle de discussion, les messages d’historique et les messages ’lives’. Dans notre cas on ne prendra en compte que les messages ’lives’.
# transbot.py
from twisted.python import log
from twisted.words.protocols.jabber.jid import JID
from wokkel.client import XMPPClient
from wokkel.muc import MUCClient
from subprocess import check_output
class MUCTranslateBot(MUCClient):
"""I join a room and respond to translation requests."""
def __init__(self, roomJID, nick):
MUCClient.__init__(self)
self.roomJID = roomJID
self.nick = nick
def connectionInitialized(self):
"""Once authorized, join the room.
If the join action causes a new room to be created, the room will be
locked until configured. Here we will just accept the default
configuration by submitting an empty form using configure, which
usually results in a public non-persistent room."""
def joinedRoom(room):
if room.locked:
# Just accept the default configuration.
return self.configure(room.roomJID, {})
MUCClient.connectionInitialized(self)
d = self.join(self.roomJID, self.nick)
d.addCallback(joinedRoom)
d.addCallback(lambda _: log.msg("Joined room"))
d.addErrback(log.err, "Join failed")
def receivedGroupChat(self, room, user, message):
"""Called when a groupchat message was received.
Check if the message was addressed to my nick. Respond by sending
translated message to the room addressed to the sender."""
if message.body.startswith(u"fr-es:"):
nick, text = message.body.split(':', 1)
text = text.strip().lower()
# Call apertium to translate messages
output = check_output("echo '%s' | apertium fr-es" % text, shell=True)
output = unicode(output, "utf-8") # convert output to unicode
self.groupChat(self.roomJID, u"es: %s" % output)
elif message.body.startswith(u"es-fr:"):
nick, text = message.body.split(':', 1)
text = text.strip().lower()
# Call apertium to translate messages
output = check_output("echo '%s' | apertium es-fr" % text, shell=True)
output = unicode(output, "utf-8") # convert output to unicode
self.groupChat(self.roomJID, u"fr: %s" % output)
Notre Bot est maintenant complet, il ne nous manque plus que le fichier de configuration pour le lanceur twistd :
Application
# transbot.tac
from twisted.application import service
from twisted.words.protocols.jabber.jid import JID
from wokkel.client import XMPPClient
from transbot import MUCTranslateBot
application = service.Application("TransBot")
xmppclient = XMPPClient(JID("user@jabber.fr/transbot"), "pass")
xmppclient.logTraffic = True
xmppclient.setServiceParent(application)
transbot = MUCTranslateBot(JID("trans@chat.jabberfr.org"), u"transbot")
transbot.setHandlerParent(xmppclient)
Il ne reste plus qu’a lancer notre Bot via : twisted -y transbot.tac
– il se connectera et/ou créera la salle de discussion trans@chat.jabberfr.org
– et attendra des messages du type :
-
fr-es:
Bonjour tout le monde ! Comment allez-vous ? - pour répondre :
transbot: es:
saludo todo el mondo ! cómo íos ?