3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-30 14:49:28 +01:00

Move utils' global variables to world.py

This commit is contained in:
James Lu 2015-08-29 09:39:33 -07:00
parent b71e508acc
commit 973aba6de7
10 changed files with 63 additions and 59 deletions

View File

@ -10,6 +10,7 @@ import hashlib
from log import log
import utils
from conf import conf
import world
### Exceptions
@ -214,7 +215,7 @@ class Irc():
hook_cmd = parsed_args.get('parse_as') or hook_cmd
log.debug('Parsed args %r received from %s handler (calling hook %s)', parsed_args, command, hook_cmd)
# Iterate over hooked functions, catching errors accordingly
for hook_func in utils.command_hooks[hook_cmd]:
for hook_func in world.command_hooks[hook_cmd]:
try:
log.debug('Calling function %s', hook_func)
hook_func(self, numeric, command, parsed_args)

View File

@ -2,6 +2,7 @@
import utils
from log import log
import world
# Handle KILLs sent to the PyLink client and respawn
def handle_kill(irc, source, command, args):
@ -25,7 +26,7 @@ def handle_commands(irc, source, command, args):
cmd = cmd_args[0].lower()
cmd_args = cmd_args[1:]
try:
func = utils.bot_commands[cmd]
func = world.bot_commands[cmd]
except KeyError:
utils.msg(irc, source, 'Error: Unknown command %r.' % cmd)
return
@ -84,7 +85,7 @@ def handle_whois(irc, source, command, args):
# idle time, so we simply return 0.
# <- 317 GL GL 15 1437632859 :seconds idle, signon time
f(irc, server, 317, source, "%s 0 %s :seconds idle, signon time" % (nick, user.ts))
for func in utils.whois_handlers:
for func in world.whois_handlers:
# Iterate over custom plugin WHOIS handlers. They return a tuple
# or list with two arguments: the numeric, and the text to send.
try:

10
main.py
View File

@ -25,7 +25,7 @@ if __name__ == '__main__':
# Import plugins first globally, because they can listen for events
# that happen before the connection phase.
utils.plugins.append(coreplugin)
world.plugins.append(coreplugin)
to_load = conf.conf['plugins']
plugins_folder = [os.path.join(os.getcwd(), 'plugins')]
# Here, we override the module lookup and import the plugins
@ -34,7 +34,7 @@ if __name__ == '__main__':
try:
moduleinfo = imp.find_module(plugin, plugins_folder)
pl = imp.load_source(plugin, moduleinfo[1])
utils.plugins.append(pl)
world.plugins.append(pl)
except ImportError as e:
if str(e) == ('No module named %r' % plugin):
log.error('Failed to load plugin %r: The plugin could not be found.', plugin)
@ -57,7 +57,7 @@ if __name__ == '__main__':
log.critical('Failed to load protocol module: ImportError: %s', protoname, str(e))
sys.exit(2)
else:
utils.networkobjects[network] = classes.Irc(network, proto, conf.conf)
utils.started.set()
log.info("loaded plugins: %s", utils.plugins)
world.networkobjects[network] = classes.Irc(network, proto, conf.conf)
world.started.set()
log.info("loaded plugins: %s", world.plugins)

View File

@ -6,6 +6,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import utils
from conf import conf
from log import log
import world
@utils.add_cmd
def status(irc, source, args):
@ -46,7 +47,7 @@ def listcommands(irc, source, args):
"""takes no arguments.
Returns a list of available commands PyLink has to offer."""
cmds = list(utils.bot_commands.keys())
cmds = list(world.bot_commands.keys())
cmds.sort()
utils.msg(irc, source, 'Available commands include: %s' % ', '.join(cmds))
utils.msg(irc, source, 'To see help on a specific command, type \x02help <command>\x02.')
@ -63,7 +64,7 @@ def help(irc, source, args):
listcommands(irc, source, args)
return
try:
func = utils.bot_commands[command]
func = world.bot_commands[command]
except KeyError:
utils.msg(irc, source, 'Error: Unknown command %r.' % command)
return

View File

@ -13,6 +13,7 @@ from expiringdict import ExpiringDict
import utils
from log import log
from conf import confname
import world
dbname = "pylinkrelay"
if confname != 'pylink':
@ -28,11 +29,11 @@ def relayWhoisHandlers(irc, target):
orig = getLocalUser(irc, target)
if orig:
network, remoteuid = orig
remotenick = utils.networkobjects[network].users[remoteuid].nick
remotenick = world.networkobjects[network].users[remoteuid].nick
return [320, "%s :is a remote user connected via PyLink Relay. Home "
"network: %s; Home nick: %s" % (user.nick, network,
remotenick)]
utils.whois_handlers.append(relayWhoisHandlers)
world.whois_handlers.append(relayWhoisHandlers)
def normalizeNick(irc, netname, nick, separator=None, uid=''):
separator = separator or irc.serverdata.get('separator') or "/"
@ -94,7 +95,7 @@ def loadDB():
db = {}
def exportDB(reschedule=False):
scheduler = utils.schedulers.get('relaydb')
scheduler = world.schedulers.get('relaydb')
if reschedule and scheduler:
scheduler.enter(30, 1, exportDB, argument=(True,))
log.debug("Relay: exporting links database to %s", dbname)
@ -179,7 +180,7 @@ def getLocalUser(irc, user, targetirc=None):
# If targetirc is given, we'll return simply the UID of the user on the
# target network, if it exists. Otherwise, we'll return a tuple
# with the home network name and the original user's UID.
sourceobj = utils.networkobjects.get(remoteuser[0])
sourceobj = world.networkobjects.get(remoteuser[0])
if targetirc and sourceobj:
if remoteuser[0] == targetirc.name:
# The user we found's home network happens to be the one being
@ -236,7 +237,7 @@ def initializeChannel(irc, channel):
remotenet, remotechan = link
if remotenet == irc.name:
continue
remoteirc = utils.networkobjects.get(remotenet)
remoteirc = world.networkobjects.get(remotenet)
if remoteirc is None:
continue
rc = remoteirc.channels[remotechan]
@ -264,7 +265,7 @@ utils.add_hook(handle_join, 'JOIN')
def handle_quit(irc, numeric, command, args):
for netname, user in relayusers[(irc.name, numeric)].copy().items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
remoteirc.proto.quitClient(remoteirc, user, args['text'])
del relayusers[(irc.name, numeric)]
utils.add_hook(handle_quit, 'QUIT')
@ -278,7 +279,7 @@ utils.add_hook(handle_squit, 'SQUIT')
def handle_nick(irc, numeric, command, args):
for netname, user in relayusers[(irc.name, numeric)].items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
newnick = normalizeNick(remoteirc, irc.name, args['newnick'], uid=user)
if remoteirc.users[user].nick != newnick:
remoteirc.proto.nickClient(remoteirc, user, newnick)
@ -292,7 +293,7 @@ def handle_part(irc, numeric, command, args):
return
for channel in channels:
for netname, user in relayusers[(irc.name, numeric)].copy().items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
remotechan = findRemoteChan(irc, remoteirc, channel)
if remotechan is None:
continue
@ -328,7 +329,7 @@ def handle_privmsg(irc, numeric, command, args):
return
if utils.isChannel(target):
for netname, user in relayusers[(irc.name, numeric)].items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
real_target = findRemoteChan(irc, remoteirc, target)
if not real_target:
continue
@ -351,7 +352,7 @@ def handle_privmsg(irc, numeric, command, args):
'with %r in order to send messages.' % \
irc.users[target].nick, notice=True)
return
remoteirc = utils.networkobjects[homenet]
remoteirc = world.networkobjects[homenet]
user = getRemoteUser(irc, remoteirc, numeric, spawnIfMissing=False)
if notice:
remoteirc.proto.noticeClient(remoteirc, user, real_target, text)
@ -371,7 +372,7 @@ def handle_kick(irc, source, command, args):
if relay is None or target == irc.pseudoclient.uid:
return
origuser = getLocalUser(irc, target)
for name, remoteirc in utils.networkobjects.items():
for name, remoteirc in world.networkobjects.items():
if irc.name == name or not remoteirc.connected.is_set():
continue
remotechan = findRemoteChan(irc, remoteirc, channel)
@ -462,7 +463,7 @@ def handle_chgclient(irc, source, command, args):
text = args['newgecos']
if field:
for netname, user in relayusers[(irc.name, target)].items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
try:
remoteirc.proto.updateClient(remoteirc, user, field, text)
except NotImplementedError: # IRCd doesn't support changing the field we want
@ -589,7 +590,7 @@ def getSupportedUmodes(irc, remoteirc, modes):
def handle_mode(irc, numeric, command, args):
target = args['target']
modes = args['modes']
for name, remoteirc in utils.networkobjects.items():
for name, remoteirc in world.networkobjects.items():
if irc.name == name or not remoteirc.connected.is_set():
continue
if utils.isChannel(target):
@ -606,7 +607,7 @@ utils.add_hook(handle_mode, 'MODE')
def handle_topic(irc, numeric, command, args):
channel = args['channel']
topic = args['topic']
for name, remoteirc in utils.networkobjects.items():
for name, remoteirc in world.networkobjects.items():
if irc.name == name or not remoteirc.connected.is_set():
continue
@ -632,7 +633,7 @@ def handle_kill(irc, numeric, command, args):
# We don't allow killing over the relay, so we must respawn the affected
# client and rejoin it to its channels.
del relayusers[realuser][irc.name]
remoteirc = utils.networkobjects[realuser[0]]
remoteirc = world.networkobjects[realuser[0]]
for remotechan in remoteirc.channels:
localchan = findRemoteChan(remoteirc, irc, remotechan)
if localchan:
@ -674,7 +675,7 @@ def isRelayClient(irc, user):
return False
def relayJoins(irc, channel, users, ts):
for name, remoteirc in utils.networkobjects.items():
for name, remoteirc in world.networkobjects.items():
queued_users = []
if name == irc.name or not remoteirc.connected.is_set():
# Don't relay things to their source network...
@ -708,7 +709,7 @@ def relayJoins(irc, channel, users, ts):
remoteirc.proto.sjoinServer(remoteirc, remoteirc.sid, remotechan, queued_users, ts=ts)
def relayPart(irc, channel, user):
for name, remoteirc in utils.networkobjects.items():
for name, remoteirc in world.networkobjects.items():
if name == irc.name or not remoteirc.connected.is_set():
# Don't relay things to their source network...
continue
@ -789,7 +790,7 @@ def destroy(irc, source, args):
entry = (irc.name, channel)
if entry in db:
for link in db[entry]['links']:
removeChannel(utils.networkobjects.get(link[0]), link[1])
removeChannel(world.networkobjects.get(link[0]), link[1])
removeChannel(irc, channel)
del db[entry]
utils.msg(irc, source, 'Done.')
@ -823,7 +824,7 @@ def link(irc, source, args):
if not utils.isOper(irc, source):
utils.msg(irc, source, 'Error: You must be opered in order to complete this operation.')
return
if remotenet not in utils.networkobjects:
if remotenet not in world.networkobjects:
utils.msg(irc, source, 'Error: No network named %r exists.' % remotenet)
return
localentry = findRelay((irc.name, localchan))
@ -882,7 +883,7 @@ def delink(irc, source, args):
else:
for link in db[entry]['links'].copy():
if link[0] == remotenet:
removeChannel(utils.networkobjects.get(remotenet), link[1])
removeChannel(world.networkobjects.get(remotenet), link[1])
db[entry]['links'].remove(link)
else:
removeChannel(irc, channel)
@ -892,8 +893,8 @@ def delink(irc, source, args):
utils.msg(irc, source, 'Error: No such relay %r.' % channel)
def initializeAll(irc):
log.debug('(%s) initializeAll: waiting for utils.started', irc.name)
utils.started.wait()
log.debug('(%s) initializeAll: waiting for world.started', irc.name)
world.started.wait()
for chanpair, entrydata in db.items():
network, channel = chanpair
initializeChannel(irc, channel)
@ -903,7 +904,7 @@ def initializeAll(irc):
def main():
loadDB()
utils.schedulers['relaydb'] = scheduler = sched.scheduler()
world.schedulers['relaydb'] = scheduler = sched.scheduler()
scheduler.enter(30, 1, exportDB, argument=(True,))
# Thread this because exportDB() queues itself as part of its
# execution, in order to get a repeating loop.
@ -935,7 +936,7 @@ def handle_save(irc, numeric, command, args):
# It's one of our relay clients; try to fix our nick to the next
# available normalized nick.
remotenet, remoteuser = realuser
remoteirc = utils.networkobjects[remotenet]
remoteirc = world.networkobjects[remotenet]
nick = remoteirc.users[remoteuser].nick
# Limit how many times we can attempt to fix our nick, to prevent
# floods and such.
@ -961,7 +962,7 @@ def linked(irc, source, args):
"""takes no arguments.
Returns a list of channels shared across the relay."""
networks = list(utils.networkobjects.keys())
networks = list(world.networkobjects.keys())
networks.remove(irc.name)
s = 'Connected networks: \x02%s\x02 %s' % (irc.name, ' '.join(networks))
utils.msg(irc, source, s)
@ -976,7 +977,7 @@ def linked(irc, source, args):
def handle_away(irc, numeric, command, args):
for netname, user in relayusers[(irc.name, numeric)].items():
remoteirc = utils.networkobjects[netname]
remoteirc = world.networkobjects[netname]
remoteirc.proto.awayClient(remoteirc, user, args['text'])
utils.add_hook(handle_away, 'AWAY')

View File

@ -9,7 +9,7 @@ import unittest
# Yes, we're going to even test the testing classes. Testception? I think so.
class TestFakeIRC(unittest.TestCase):
def setUp(self):
self.irc = classes.FakeIRC('unittest', classes.FakeProto(), classes.testconf)
self.irc = classes.FakeIRC('unittest', classes.FakeProto())
def testFakeIRC(self):
self.irc.run('this should do nothing')

View File

@ -7,7 +7,6 @@ import unittest
import utils
import classes
import relay
import conf
def dummyf():
pass

View File

@ -6,7 +6,7 @@ import itertools
import utils
import classes
import conf
import world
def dummyf():
pass
@ -26,16 +26,16 @@ class TestUtils(unittest.TestCase):
utils.add_cmd(dummyf)
utils.add_cmd(dummyf, 'TEST')
# All command names should be automatically lowercased.
self.assertIn('dummyf', utils.bot_commands)
self.assertIn('test', utils.bot_commands)
self.assertNotIn('TEST', utils.bot_commands)
self.assertIn('dummyf', world.bot_commands)
self.assertIn('test', world.bot_commands)
self.assertNotIn('TEST', world.bot_commands)
def test_add_hook(self):
utils.add_hook(dummyf, 'join')
self.assertIn('JOIN', utils.command_hooks)
self.assertIn('JOIN', world.command_hooks)
# Command names stored in uppercase.
self.assertNotIn('join', utils.command_hooks)
self.assertIn(dummyf, utils.command_hooks['JOIN'])
self.assertNotIn('join', world.command_hooks)
self.assertIn(dummyf, world.command_hooks['JOIN'])
def testIsNick(self):
self.assertFalse(utils.isNick('abcdefgh', nicklen=3))

View File

@ -1,19 +1,9 @@
import string
import re
from collections import defaultdict
import threading
import inspect
from log import log
global bot_commands, command_hooks
# This should be a mapping of command names to functions
bot_commands = {}
command_hooks = defaultdict(list)
networkobjects = {}
schedulers = {}
plugins = []
whois_handlers = []
started = threading.Event()
import world
# This is separate from classes.py to prevent import loops.
class NotAuthenticatedError(Exception):
@ -118,12 +108,12 @@ def add_cmd(func, name=None):
if name is None:
name = func.__name__
name = name.lower()
bot_commands[name] = func
world.bot_commands[name] = func
def add_hook(func, command):
"""Add a hook <func> for command <command>."""
command = command.upper()
command_hooks[command].append(func)
world.command_hooks[command].append(func)
def toLower(irc, text):
if irc.proto.casemapping == 'rfc1459':

View File

@ -1,7 +1,18 @@
# world.py: global state variables go here
from collections import defaultdict
import threading
# Global variable to indicate whether we're being ran directly, or imported
# for a testcase.
testing = True
global bot_commands, command_hooks
# This should be a mapping of command names to functions
bot_commands = {}
command_hooks = defaultdict(list)
networkobjects = {}
schedulers = {}
plugins = []
whois_handlers = []
started = threading.Event()