move XML-RPC support into DrBotIRC so everything can eventually use it
This commit is contained in:
parent
91faebf33a
commit
05a3bd0af7
81
DrBotIRC.py
81
DrBotIRC.py
|
@ -21,11 +21,62 @@ import copy
|
||||||
from ConfigParser import NoOptionError, NoSectionError
|
from ConfigParser import NoOptionError, NoSectionError
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
|
from SimpleXMLRPCServer import SimpleXMLRPCServer
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import thread
|
||||||
|
|
||||||
from extlib import irclib
|
from extlib import irclib
|
||||||
|
|
||||||
|
class DrBotzoMethods:
|
||||||
|
|
||||||
|
"""Methods to expose to the XML-RPC server."""
|
||||||
|
|
||||||
|
def __init__(self, irc):
|
||||||
|
"""Store the same stuff the core module would, since we'll probably need it."""
|
||||||
|
|
||||||
|
self.irc = irc
|
||||||
|
|
||||||
|
def echo(self, message):
|
||||||
|
"""
|
||||||
|
Just reply to the client, for testing purposes.
|
||||||
|
Arguments: message - the message to echo
|
||||||
|
"""
|
||||||
|
|
||||||
|
return message
|
||||||
|
|
||||||
|
def say(self, target, message):
|
||||||
|
"""
|
||||||
|
Say a message in a channel/to a nick.
|
||||||
|
Arguments: target - the nick/channel to privmsg
|
||||||
|
message - the message to send
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.irc.server.privmsg(target, message)
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
def execute_module_method(self, modname, method, args):
|
||||||
|
"""
|
||||||
|
Execute the method (with arguments) of the specified module.
|
||||||
|
Arguments: modname - the loaded module to retrieve
|
||||||
|
method - the method to call from that module
|
||||||
|
args - the arguments to provide to the method as a pythonic tuple
|
||||||
|
"""
|
||||||
|
|
||||||
|
for module in self.irc.modlist:
|
||||||
|
if modname == module.__class__.__name__:
|
||||||
|
try:
|
||||||
|
func = getattr(module, method)
|
||||||
|
except AttributeError:
|
||||||
|
return "couldn't find " + method + " in found module " + modname
|
||||||
|
|
||||||
|
if hasattr(func, '__call__'):
|
||||||
|
return func(*args)
|
||||||
|
else:
|
||||||
|
return method + " in found module " + modname + " is not callable"
|
||||||
|
|
||||||
|
return "couldn't find " + modname
|
||||||
|
|
||||||
class DrBotServerConnection(irclib.ServerConnection):
|
class DrBotServerConnection(irclib.ServerConnection):
|
||||||
|
|
||||||
"""Subclass irclib's ServerConnection, in order to expand privmsg."""
|
"""Subclass irclib's ServerConnection, in order to expand privmsg."""
|
||||||
|
@ -90,10 +141,26 @@ class DrBotIRC(irclib.IRC):
|
||||||
irclib.IRC.__init__(self)
|
irclib.IRC.__init__(self)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.xmlrpc = None
|
||||||
|
|
||||||
# handle SIGINT
|
# handle SIGINT
|
||||||
signal.signal(signal.SIGINT, self.sigint_handler)
|
signal.signal(signal.SIGINT, self.sigint_handler)
|
||||||
|
|
||||||
|
# load XML-RPC server
|
||||||
|
try:
|
||||||
|
if self.config.has_section('XMLRPC'):
|
||||||
|
host = self.config.get('XMLRPC', 'host')
|
||||||
|
port = self.config.getint('XMLRPC', 'port')
|
||||||
|
if host and port:
|
||||||
|
self.funcs = DrBotzoMethods(self)
|
||||||
|
|
||||||
|
self.xmlrpc = SimpleXMLRPCServer((host, port))
|
||||||
|
self.xmlrpc.register_introspection_functions()
|
||||||
|
self.xmlrpc.register_instance(self.funcs)
|
||||||
|
|
||||||
|
thread.start_new_thread(self._xmlrpc_listen, ())
|
||||||
|
except NoOptionError: pass
|
||||||
|
|
||||||
def server(self):
|
def server(self):
|
||||||
"""Create a DrBotServerConnection."""
|
"""Create a DrBotServerConnection."""
|
||||||
self.server = DrBotServerConnection(self)
|
self.server = DrBotServerConnection(self)
|
||||||
|
@ -129,6 +196,11 @@ class DrBotIRC(irclib.IRC):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("exception floated up to DrBotIrc: " + str(e))
|
print("exception floated up to DrBotIrc: " + str(e))
|
||||||
|
|
||||||
|
def _xmlrpc_listen(self):
|
||||||
|
"""Begin listening. Hopefully this was called in a new thread."""
|
||||||
|
|
||||||
|
self.xmlrpc.serve_forever()
|
||||||
|
|
||||||
def try_to_replace_event_text_with_module_text(self, connection, event):
|
def try_to_replace_event_text_with_module_text(self, connection, event):
|
||||||
"""Do something very similar to _handle_event, but for recursion.
|
"""Do something very similar to _handle_event, but for recursion.
|
||||||
|
|
||||||
|
@ -296,12 +368,20 @@ class DrBotIRC(irclib.IRC):
|
||||||
|
|
||||||
connection.quit(msg)
|
connection.quit(msg)
|
||||||
print(self.save_config())
|
print(self.save_config())
|
||||||
|
self._xmlrpc_shutdown()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def save_modules(self):
|
def save_modules(self):
|
||||||
for module in self.modlist:
|
for module in self.modlist:
|
||||||
module.save()
|
module.save()
|
||||||
|
|
||||||
|
def _xmlrpc_shutdown(self):
|
||||||
|
"""Shut down the XML-RPC server."""
|
||||||
|
|
||||||
|
if self.xmlrpc is not None:
|
||||||
|
self.xmlrpc.shutdown()
|
||||||
|
self.xmlrpc.server_close()
|
||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
with open('dr.botzo.cfg', 'w') as cfg:
|
with open('dr.botzo.cfg', 'w') as cfg:
|
||||||
self.config.write(cfg)
|
self.config.write(cfg)
|
||||||
|
@ -379,6 +459,7 @@ class DrBotIRC(irclib.IRC):
|
||||||
module.shutdown()
|
module.shutdown()
|
||||||
|
|
||||||
print(self.save_config())
|
print(self.save_config())
|
||||||
|
self._xmlrpc_shutdown()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
# vi:tabstop=4:expandtab:autoindent
|
# vi:tabstop=4:expandtab:autoindent
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
"""
|
|
||||||
XmlRpcServer - access dr.botzo functionality via XML-RPC
|
|
||||||
Copyright (C) 2012 Brian S. Stephan
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import thread
|
|
||||||
from SimpleXMLRPCServer import SimpleXMLRPCServer
|
|
||||||
|
|
||||||
from extlib import irclib
|
|
||||||
|
|
||||||
from Module import Module
|
|
||||||
|
|
||||||
class DrBotzoMethods:
|
|
||||||
|
|
||||||
"""Methods to expose to the XML-RPC server."""
|
|
||||||
|
|
||||||
def __init__(self, irc, config, server):
|
|
||||||
"""Store the same stuff the core module would, since we'll probably need it."""
|
|
||||||
|
|
||||||
self.irc = irc
|
|
||||||
self.config = config
|
|
||||||
self.server = server
|
|
||||||
|
|
||||||
def echo(self, message):
|
|
||||||
"""
|
|
||||||
Just reply to the client, for testing purposes.
|
|
||||||
Arguments: message - the message to echo
|
|
||||||
"""
|
|
||||||
|
|
||||||
return message
|
|
||||||
|
|
||||||
def say(self, target, message):
|
|
||||||
"""
|
|
||||||
Say a message in a channel/to a nick.
|
|
||||||
Arguments: target - the nick/channel to privmsg
|
|
||||||
message - the message to send
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.irc.server.privmsg(target, message)
|
|
||||||
return "OK"
|
|
||||||
|
|
||||||
def execute_module_method(self, modname, method, args):
|
|
||||||
"""
|
|
||||||
Execute the method (with arguments) of the specified module.
|
|
||||||
Arguments: modname - the loaded module to retrieve
|
|
||||||
method - the method to call from that module
|
|
||||||
args - the arguments to provide to the method as a pythonic tuple
|
|
||||||
"""
|
|
||||||
|
|
||||||
for module in self.irc.modlist:
|
|
||||||
if modname == module.__class__.__name__:
|
|
||||||
try:
|
|
||||||
func = getattr(module, method)
|
|
||||||
except AttributeError:
|
|
||||||
return "couldn't find " + method + " in found module " + modname
|
|
||||||
|
|
||||||
if hasattr(func, '__call__'):
|
|
||||||
return func(*args)
|
|
||||||
else:
|
|
||||||
return method + " in found module " + modname + " is not callable"
|
|
||||||
|
|
||||||
return "couldn't find " + modname
|
|
||||||
|
|
||||||
class XmlRpcServer(Module):
|
|
||||||
|
|
||||||
"""A module to expose an XML-RPC service, to achieve various things."""
|
|
||||||
|
|
||||||
def __init__(self, irc, config, server):
|
|
||||||
"""Create the XML-RPC server."""
|
|
||||||
|
|
||||||
Module.__init__(self, irc, config, server)
|
|
||||||
|
|
||||||
self.xmlrpc = None
|
|
||||||
self.funcs = DrBotzoMethods(irc, config, server)
|
|
||||||
|
|
||||||
self.xmlrpc = SimpleXMLRPCServer(("localhost", 8180))
|
|
||||||
self.xmlrpc.register_introspection_functions()
|
|
||||||
self.xmlrpc.register_instance(self.funcs)
|
|
||||||
|
|
||||||
thread.start_new_thread(self._listen, ())
|
|
||||||
|
|
||||||
def _listen(self):
|
|
||||||
"""Begin listening. Hopefully this was called in a new thread."""
|
|
||||||
|
|
||||||
self.xmlrpc.serve_forever()
|
|
||||||
|
|
||||||
def do(self, connection, event, nick, userhost, what, admin_unlocked):
|
|
||||||
"""Do nothing."""
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
"""Shut down the XML-RPC server."""
|
|
||||||
|
|
||||||
if self.xmlrpc is not None:
|
|
||||||
self.xmlrpc.shutdown()
|
|
||||||
self.xmlrpc.server_close()
|
|
||||||
|
|
||||||
# vi:tabstop=4:expandtab:autoindent
|
|
Loading…
Reference in New Issue