add an XML-RPC interface to the irc bot

this allows plugins to register methods that can be called over XML-RPC

the old bot used this interface behind apache for a web service, but i
think in this version it will only be for django -> ircbot, and django
will have a rest API for other things
This commit is contained in:
Brian S. Stephan 2015-06-13 13:06:10 -05:00
parent 65a03ced03
commit 56b495e8fb
2 changed files with 53 additions and 0 deletions

View File

@ -131,6 +131,11 @@ IRCBOT_SSL = False
IRCBOT_IPV6 = False
# XML-RPC settings
IRCBOT_XMLRPC_HOST = 'localhost'
IRCBOT_XMLRPC_PORT = 13132
# IRC module stuff
# weather

View File

@ -7,9 +7,11 @@ import collections
import copy
import logging
import re
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import socket
import ssl
import sys
import thread
from django.conf import settings
@ -25,6 +27,15 @@ from ircbot.models import Alias, IrcChannel, IrcPlugin
log = logging.getLogger('ircbot.bot')
class IrcBotXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
"""Override the basic request handler to change the logging."""
def log_message(self, format, *args):
"""Use a logger rather than stderr."""
log.debug("XML-RPC - %s - %s", self.client_address[0], format%args)
class PrioritizedRegexHandler(collections.namedtuple('Base', ('priority', 'regex', 'callback'))):
def __lt__(self, other):
"when sorting prioritized handlers, only use the priority"
@ -325,6 +336,16 @@ class IRCBot(irc.client.SimpleIRCClient):
self.connection.reactor.add_global_regex_handler('privmsg', r'^!unload\s+([\S]+)$',
getattr(self, 'handle_unload'), -20)
# load XML-RPC server
self.xmlrpc = SimpleXMLRPCServer((settings.IRCBOT_XMLRPC_HOST, settings.IRCBOT_XMLRPC_PORT),
requestHandler=IrcBotXMLRPCRequestHandler, allow_none=True)
self.xmlrpc.register_introspection_functions()
thread.start_new_thread(self._xmlrpc_listen, ())
# register XML-RPC stuff
self.xmlrpc.register_function(self.privmsg, 'privmsg')
def _connected_checker(self):
if not self.connection.is_connected():
self.connection.execute_delayed(self.reconnection_interval,
@ -468,6 +489,7 @@ class IRCBot(irc.client.SimpleIRCClient):
msg -- Quit message.
"""
self._xmlrpc_shutdown()
self.connection.disconnect(msg)
sys.exit(0)
@ -682,6 +704,32 @@ class IRCBot(irc.client.SimpleIRCClient):
if stop:
return "NO MORE"
def xmlrpc_register_function(self, func, name):
"""Add a method to the XML-RPC interface.
:param func: the method to register
:type func: a method
:param name: the name to expose the method as
:type name: str
"""
if func and self.xmlrpc:
if hasattr(func, '__call__'):
self.xmlrpc.register_function(func, name)
def _xmlrpc_listen(self):
"""Begin listening. Hopefully this was called in a new thread."""
self.xmlrpc.serve_forever()
def _xmlrpc_shutdown(self):
"""Shut down the XML-RPC server."""
if self.xmlrpc is not None:
self.xmlrpc.shutdown()
self.xmlrpc.server_close()
def start(self):
"""Start the bot."""