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.registry as registry
from supybot.i18n import PluginInternationalization
from supybot.i18n import internationalizeDocstring
_ = PluginInternationalization('Listener')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
# a bool that specifies whether the user identified himself as an advanced
@ -45,5 +49,8 @@ Listener = conf.registerPlugin('Listener')
# conf.registerGlobalValue(Listener, '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:

View File

@ -1,5 +1,6 @@
###
# Copyright (c) 2010, quantumlemur
# Copyright (c) 2012, Valentin Lorentz
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -28,17 +29,29 @@
###
import json
import time
import socket
import threading
import traceback
import supybot.log as log
import supybot.conf as conf
import supybot.utils as utils
import supybot.world as world
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.registry as registry
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):
"""Add the help for "@plugin help Listener" here
@ -48,13 +61,33 @@ class Listener(callbacks.Plugin):
def __init__(self, irc):
self.__parent = super(Listener, self)
self.__parent.__init__(irc)
self.buffer = ''
self.channel = '#supybot-bots' # set this
self.network = 'freenode' # ...and this
self.host = 'localhost' # ...and this
self.port = 56789 # ...and this.
self.listenerThread = self.ListeningThread(self.network, self.channel, self.host, self.port)
self.listenerThread.start()
self.listenerThreads = []
try:
conf.supybot.plugins.Listener.relays.addCallback(
self._loadFromConfig)
except registry.NonExistentRegistryEntry:
log.error("Your version of Supybot is not compatible with "
"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):
@ -83,23 +116,74 @@ class Listener(callbacks.Plugin):
if self.buffer:
for IRC in world.ircs:
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.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):
"""takes no arguments
Tries to close the listening socket"""
self.listenerThread.active = False
self.listenerThread.listener.close()
Tries to close all listening sockets"""
for thread in self.listenerThreads:
thread.active = False
thread.listener.close()
self.listenerThreads = []
irc.replySuccess()
stop = wrap(stop)
def die(self):
self.listenerThread.active = False
self.listenerThread.listener.close()
for thread in self.listenerThreads:
thread.active = False
thread.listener.close()
self.listenerThreads = []
time.sleep(2)
Class = Listener