mirror of
https://github.com/jlu5/PyLink.git
synced 2024-12-26 12:43:09 +01:00
Begin work on service bot abstraction (#216)
- State-keeping is done by coreplugin - utils.registerService() introduced - new PYLINK_NEW_SERVICE hook introduced
This commit is contained in:
parent
ce95e15897
commit
7d11f8c7e0
@ -186,6 +186,55 @@ def handle_version(irc, source, command, args):
|
|||||||
irc.proto.numeric(irc.sid, 351, source, fullversion)
|
irc.proto.numeric(irc.sid, 351, source, fullversion)
|
||||||
utils.add_hook(handle_version, 'VERSION')
|
utils.add_hook(handle_version, 'VERSION')
|
||||||
|
|
||||||
|
def handle_newservice(irc, source, command, args):
|
||||||
|
"""Handles new service bot introductions."""
|
||||||
|
|
||||||
|
if not irc.connected.is_set():
|
||||||
|
return
|
||||||
|
|
||||||
|
name = args['name']
|
||||||
|
ident = irc.botdata.get('ident') or 'pylink'
|
||||||
|
host = irc.serverdata["hostname"]
|
||||||
|
modes = []
|
||||||
|
for mode in ('oper', 'hideoper', 'hidechans'):
|
||||||
|
mode = irc.cmodes.get(mode)
|
||||||
|
if mode:
|
||||||
|
modes.append((mode, None))
|
||||||
|
|
||||||
|
# Track the service's UIDs on each network.
|
||||||
|
service = world.services[name]
|
||||||
|
service.uids[irc.name] = u = irc.proto.spawnClient(name, name,
|
||||||
|
irc.serverdata['hostname'], modes=modes, opertype="PyLink Service")
|
||||||
|
|
||||||
|
# TODO: channels should be tracked in a central database, not hardcoded
|
||||||
|
# in conf.
|
||||||
|
for chan in irc.serverdata['channels']:
|
||||||
|
irc.proto.join(u.uid, chan)
|
||||||
|
|
||||||
|
utils.add_hook(handle_newservice, 'PYLINK_NEW_SERVICE')
|
||||||
|
|
||||||
|
def handle_disconnect(irc, source, command, args):
|
||||||
|
"""Handles network disconnections."""
|
||||||
|
for name, sbot in world.services.items():
|
||||||
|
try:
|
||||||
|
del sbot.uids[irc.name]
|
||||||
|
log.debug("coreplugin: removing uids[%s] from service bot %s", irc.name, sbot.name)
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
utils.add_hook(handle_disconnect, 'PYLINK_DISCONNECT')
|
||||||
|
|
||||||
|
def handle_endburst(irc, source, command, args):
|
||||||
|
"""Handles network bursts."""
|
||||||
|
if source == irc.uplink:
|
||||||
|
log.debug('(%s): spawning service bots now.')
|
||||||
|
|
||||||
|
# We just connected. Burst all our registered services.
|
||||||
|
for name, sbot in world.services.items():
|
||||||
|
handle_newservice(irc, source, command, {'name': name})
|
||||||
|
|
||||||
|
utils.add_hook(handle_endburst, 'ENDBURST')
|
||||||
|
|
||||||
# Essential, core commands go here so that the "commands" plugin with less-important,
|
# Essential, core commands go here so that the "commands" plugin with less-important,
|
||||||
# but still generic functions can be reloaded.
|
# but still generic functions can be reloaded.
|
||||||
|
|
||||||
|
62
utils.py
62
utils.py
@ -9,6 +9,7 @@ import string
|
|||||||
import re
|
import re
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
|
import collections
|
||||||
|
|
||||||
from log import log
|
from log import log
|
||||||
import world
|
import world
|
||||||
@ -141,3 +142,64 @@ def getDatabaseName(dbname):
|
|||||||
dbname += '-%s' % conf.confname
|
dbname += '-%s' % conf.confname
|
||||||
dbname += '.db'
|
dbname += '.db'
|
||||||
return dbname
|
return dbname
|
||||||
|
|
||||||
|
class ServiceBot():
|
||||||
|
def __init__(self, name, default_help=True, default_request=True, default_list=True):
|
||||||
|
self.name = name
|
||||||
|
# We make the command definitions a dict of lists of functions. Multiple
|
||||||
|
# plugins are actually allowed to bind to one function name; this just causes
|
||||||
|
# them to be called in the order that they are bound.
|
||||||
|
self.commands = collections.defaultdict(list)
|
||||||
|
|
||||||
|
# This tracks the UIDs of the service bot on different networks, as they are
|
||||||
|
# spawned.
|
||||||
|
self.uids = {}
|
||||||
|
|
||||||
|
if default_help:
|
||||||
|
self.add_cmd(self.help)
|
||||||
|
|
||||||
|
if default_request:
|
||||||
|
self.add_cmd(self.request)
|
||||||
|
self.add_cmd(self.remove)
|
||||||
|
|
||||||
|
if default_list:
|
||||||
|
self.add_cmd(self.listcommands, 'list')
|
||||||
|
|
||||||
|
def spawn(self, irc=None):
|
||||||
|
# Spawn the new service by calling the PYLINK_NEW_SERVICE hook,
|
||||||
|
# which is handled by coreplugin.
|
||||||
|
if irc is None:
|
||||||
|
for irc in world.networkobjects.values():
|
||||||
|
irc.callHooks([None, 'PYLINK_NEW_SERVICE', {'name': self.name}])
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("Network specific plugins not supported yet.")
|
||||||
|
|
||||||
|
|
||||||
|
def add_cmd(self, func, name=None):
|
||||||
|
"""Binds an IRC command function to the given command name."""
|
||||||
|
if name is None:
|
||||||
|
name = func.__name__
|
||||||
|
name = name.lower()
|
||||||
|
|
||||||
|
self.commands[name].append(func)
|
||||||
|
return func
|
||||||
|
|
||||||
|
def help(self, irc, source, args):
|
||||||
|
irc.reply("Help command stub called.")
|
||||||
|
|
||||||
|
def request(self, irc, source, args):
|
||||||
|
irc.reply("Request command stub called.")
|
||||||
|
|
||||||
|
def remove(self, irc, source, args):
|
||||||
|
irc.reply("Remove command stub called.")
|
||||||
|
|
||||||
|
def listcommands(self, irc, source, args):
|
||||||
|
irc.reply("List command stub called.")
|
||||||
|
|
||||||
|
def registerService(name, *args, **kwargs):
|
||||||
|
name = name.lower()
|
||||||
|
if name in world.services:
|
||||||
|
raise ValueError("Service name %s is already bound!" % name)
|
||||||
|
|
||||||
|
world.services[name] = sbot = ServiceBot(name, *args, **kwargs)
|
||||||
|
sbot.spawn()
|
||||||
|
5
world.py
5
world.py
@ -14,13 +14,14 @@ testing = True
|
|||||||
# Sets the default protocol module to use with tests.
|
# Sets the default protocol module to use with tests.
|
||||||
testing_ircd = 'inspircd'
|
testing_ircd = 'inspircd'
|
||||||
|
|
||||||
global commands, hooks
|
|
||||||
# This should be a mapping of command names to functions
|
|
||||||
commands = defaultdict(list)
|
commands = defaultdict(list)
|
||||||
hooks = defaultdict(list)
|
hooks = defaultdict(list)
|
||||||
networkobjects = {}
|
networkobjects = {}
|
||||||
plugins = {}
|
plugins = {}
|
||||||
whois_handlers = []
|
whois_handlers = []
|
||||||
|
services = {}
|
||||||
|
|
||||||
started = threading.Event()
|
started = threading.Event()
|
||||||
|
|
||||||
plugins_folder = os.path.join(os.getcwd(), 'plugins')
|
plugins_folder = os.path.join(os.getcwd(), 'plugins')
|
||||||
|
Loading…
Reference in New Issue
Block a user