Listener: Use the Supybot registry instead of hardcoded values & allow multiple listeners.

master
Valentin Lorentz 2012-08-31 13:54:45 +02:00
parent fb65290f3f
commit 7e40a4bddb
2 changed files with 104 additions and 13 deletions

View File

@ -31,6 +31,10 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization
from supybot.i18n import internationalizeDocstring
_ = PluginInternationalization('Listener')
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is
# a bool that specifies whether the user identified himself as an advanced # a bool that specifies whether the user identified himself as an advanced
@ -45,5 +49,8 @@ Listener = conf.registerPlugin('Listener')
# conf.registerGlobalValue(Listener, 'someConfigVariableName', # conf.registerGlobalValue(Listener, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName.""")) # registry.Boolean(False, """Help for someConfigVariableName."""))
conf.registerGlobalValue(Listener, 'relays',
registry.String('[]', _("""JSON-formatted relays. Do not edit this
configuration variable unless you know what you are doing.""")))
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

View File

@ -1,5 +1,6 @@
### ###
# Copyright (c) 2010, quantumlemur # Copyright (c) 2010, quantumlemur
# Copyright (c) 2012, Valentin Lorentz
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -28,17 +29,29 @@
### ###
import json
import time import time
import socket import socket
import threading import threading
import traceback
import supybot.log as log
import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
import supybot.world as world import supybot.world as world
from supybot.commands import * from supybot.commands import *
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization
from supybot.i18n import internationalizeDocstring
_ = PluginInternationalization('Listener')
def serialize_relay(relay):
format_ = _('from %(host)s:%(port)s to %(channel)s@%(network)s')
return format_ % relay
class Listener(callbacks.Plugin): class Listener(callbacks.Plugin):
"""Add the help for "@plugin help Listener" here """Add the help for "@plugin help Listener" here
@ -48,13 +61,33 @@ class Listener(callbacks.Plugin):
def __init__(self, irc): def __init__(self, irc):
self.__parent = super(Listener, self) self.__parent = super(Listener, self)
self.__parent.__init__(irc) self.__parent.__init__(irc)
self.buffer = '' self.listenerThreads = []
self.channel = '#supybot-bots' # set this try:
self.network = 'freenode' # ...and this conf.supybot.plugins.Listener.relays.addCallback(
self.host = 'localhost' # ...and this self._loadFromConfig)
self.port = 56789 # ...and this. except registry.NonExistentRegistryEntry:
self.listenerThread = self.ListeningThread(self.network, self.channel, self.host, self.port) log.error("Your version of Supybot is not compatible with "
self.listenerThread.start() "configuration hooks. So, Listener won't be able "
"to reload the configuration if you use the Config "
"plugin.")
self._loadFromConfig()
def _loadFromConfig(self, name=None):
relays = json.loads(self.registryValue('relays'))
for thread in self.listenerThreads:
thread.active = False
thread.listener.close()
time.sleep(2)
self.listenerThreads = []
for relay in relays:
try:
log.debug('Starting listener thread: %s' %
serialize_relay(relay))
thread = self.ListeningThread(**relay)
thread.start()
self.listenerThreads.append(thread)
except TypeError:
irc.error('Cannot load relay: %s' % serialize_relay(relay))
class ListeningThread(threading.Thread): class ListeningThread(threading.Thread):
@ -83,23 +116,74 @@ class Listener(callbacks.Plugin):
if self.buffer: if self.buffer:
for IRC in world.ircs: for IRC in world.ircs:
if IRC.network == self.network: if IRC.network == self.network:
IRC.queueMsg(ircmsgs.privmsg(self.channel, self.buffer)) try:
IRC.queueMsg(ircmsgs.privmsg(self.channel, self.buffer))
except Exception as e:
traceback.print_exc(e)
self.buffer = '' self.buffer = ''
self.listener.close() self.listener.close()
def add(self, irc, msg, args, channel, network, host, port):
"""[<channel>] [<network>] <host> <port>
Start listening on <host>:<port> and relays messages to <channel> @
<network>.
<channel> and <network> default to the current ones."""
relays = json.loads(self.registryValue('relays'))
relay = {'channel': channel, 'network': network.network,
'host': host, 'port': port}
if relay in relays:
irc.error(_('This relay already exists.'), Raise=True)
relays.append(relay)
self.setRegistryValue('relays', value=json.dumps(relays))
self._loadFromConfig()
irc.replySuccess()
add = wrap(add, ['channel', 'networkIrc', 'somethingWithoutSpaces',
('int', 'port', lambda x: (x<65536))])
def remove(self, irc, msg, args, channel, network, host, port):
"""[<channel>] [<network>] <host> <port>
Start listening on <host>:<port> and relays messages to <channel> @
<network>.
<channel> and <network> default to the current ones."""
relays = json.loads(self.registryValue('relays'))
relay = {'channel': channel, 'network': network.network,
'host': host, 'port': port}
try:
relays.remove(relay)
except ValueError:
irc.error(_('This relay does not exist.'), Raise=True)
self.setRegistryValue('relays', value=json.dumps(relays))
self._loadFromConfig()
irc.replySuccess()
remove = wrap(remove, ['channel', 'networkIrc', 'somethingWithoutSpaces',
('int', 'port', lambda x: (x<65536))])
def list(self, irc, msg, args):
"""takes no arguments
Return a list of all relays."""
relays = json.loads(self.registryValue('relays'))
irc.replies([serialize_relay(x) for x in relays])
list = wrap(list)
def stop(self, irc, msg, args): def stop(self, irc, msg, args):
"""takes no arguments """takes no arguments
Tries to close the listening socket""" Tries to close all listening sockets"""
self.listenerThread.active = False for thread in self.listenerThreads:
self.listenerThread.listener.close() thread.active = False
thread.listener.close()
self.listenerThreads = []
irc.replySuccess() irc.replySuccess()
stop = wrap(stop) stop = wrap(stop)
def die(self): def die(self):
self.listenerThread.active = False for thread in self.listenerThreads:
self.listenerThread.listener.close() thread.active = False
thread.listener.close()
self.listenerThreads = []
time.sleep(2) time.sleep(2)
Class = Listener Class = Listener