HAL> Affirmative, Dave, I read you.
Par hr le vendredi 11 janvier 2008, 17:39 - code - Lien permanent
Ah la vacuité d'une session IRC sur un canal dirigé par un automate. Quoi de plus extraordinaire que pouvoir connaitre la météo de Felletin dans la Creuse ou d'avoir une blague carambar à la demande. En ce moment je fais beaucoup de python, donc je me suis penché sur le problème pour un ami. Je vais essayer de vous exposer les clés de l'utilisation d'irclib pour construire un automate irc simple.
L'automate est présenté ci-après, ses fonctions sont simplement la connexion à un serveur irc local sur le port 6667 et l'entrée dans le canal #test. L'automate s'attend à lire des commandes préfixées de '!' dans le canal. La commande !cycle demande à l'automate de partir et revenir sur le canal, la commande !die provoque la déconnexion du serveur puis l'arrêt de l'automate. Le script de l'automate ci-après se trouve en téléchargement ici et peut être lancé par la commande python mybot.py.
import sys
try:
from ircbot import SingleServerIRCBot
import irclib
except ImportError, e:
print e
sys.exit(1)
class pybot(SingleServerIRCBot):
def __init__(self, server, nick, realname, chan):
SingleServerIRCBot.__init__(self, server, nick, realname)
self.chan = chan
self.nick = nick
## Event callbacks
def on_welcome(self, c, e):
if self.chan:
c.join(self.chan)
def on_join(self, c, e):
who = e.source().split('!', 1)
if who[0] == self.nick:
c.privmsg(e.target(), 'Hello world!')
def on_pubmsg(self, c, e):
msg = e.arguments()[0].strip()
if msg.startswith('!'):
cmd = msg[1:].split(' ', 1)[0]
self.trigger(c, e, cmd)
## Command triggers
def trigger(self, c, e, cmd):
try:
getattr(self, 'cmd_%s' % cmd)(c, e)
except AttributeError:
pass
def cmd_cycle(self, c, e):
chan = e.target()
c.part(chan, 'cycle')
c.join(chan)
def cmd_die(self, c, e):
SingleServerIRCBot.die(self, 'Argh')
## Here comes the real script
if __name__ == '__main__':
server = [('localhost', 6667)]
nick = 'monbot'
realname = 'monbot'
channel = '#test'
bot = pybot(server, nick, realname, channel)
try:
bot.start()
except KeyboardInterrupt:
bot.connection.disconnect("Ctrl-C m'a tuer")
bot.connection.close()
La librairie irclib est basée sur la gestion d'évènements, des méthodes vont être lancées sur apparition d'un évènement au sens IRC. Les méthodes de l'objet pybot commençant par 'on_' sont les méthodes de gestion d'évènements, par exemple lorsqu'un message est envoyé sur un canal (PUBMSG) la méthode on_pubsmg() est appelée. La création de l'automate se base sur la surcharge des méthodes de gestion d'évènements. Ces méthodes ont toutes la même définition d'appel :
def on_foo(self, c, e):
[...]
La variable c est un objet ServerConnection, cet objet permet de manipuler tout ce qui concerne le serveur irc d'où provient l'évènement. On peut par exemple rejoindre un canal (c.join()) ou envoyer un message à un canal ou une personne (commande PRIVMSG via c.privmsg()). La variable e est un objet Event, elle permet d'obtenir toutes les informations sur l'évènement qui a provoqué l'appel de la méthode. L'origine de l'évènement (e.source()), la destination de cet évènement (e.target()) ou encore les arguments de cet évènement (e.arguments()). Toutes les informations sur ces 2 méthodes se trouvent dans le module irclib (pydoc irclib).
A partir de la connaissance de ces éléments de base, la construction d'un automate devient assez simple. Si l'automate doit effectuer des tâches régulières, les méthodes execute_at() et execute_delayed() (héritage de l'objet IRC parent de SingleServerIRCBot) peuvent être utilisées. Plus d'information sur irclib devrait se trouver sur mon wiki.
Il est également possible d'utiliser twisted.words pour effectuer la même chose mais ça me semble une librairie un peu imposante pour un simple automate.
Il faut noter qu'on peut faire également le même genre de chose en Perl.
Commentaires
Salut
Pas de gcu aux solutions linux 2008?
Pourquoi?
Je serais sur un stand, probablement OOo les 3 jours.
A+
Pascal
hail to pynt !