111 lines
3.0 KiB
Python
Executable File
111 lines
3.0 KiB
Python
Executable File
# coding=utf-8
|
|
"""
|
|
reload.py - Sopel Module Reloader Module
|
|
Copyright 2008, Sean B. Palmer, inamidst.com
|
|
Licensed under the Eiffel Forum License 2.
|
|
|
|
http://sopel.chat
|
|
"""
|
|
from __future__ import unicode_literals, absolute_import, print_function, division
|
|
|
|
import collections
|
|
import sys
|
|
import time
|
|
from tools import iteritems
|
|
import loader
|
|
import module
|
|
import subprocess
|
|
|
|
|
|
def load_module(bot, name, path, type_):
|
|
module, mtime = loader.load_module(name, path, type_)
|
|
relevant_parts = loader.clean_module(module, bot.config)
|
|
|
|
bot.register(*relevant_parts)
|
|
|
|
# TODO sys.modules[name] = module
|
|
if hasattr(module, 'setup'):
|
|
module.setup(bot)
|
|
|
|
modified = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(mtime))
|
|
|
|
bot.reply('%r (version: %s)' % (module, modified))
|
|
|
|
|
|
@module.require_admin
|
|
@module.commands("reload")
|
|
@module.priority("low")
|
|
@module.thread(False)
|
|
def f_reload(bot, trigger):
|
|
"""Reloads a module, for use by admins only."""
|
|
|
|
name = trigger.group(2)
|
|
|
|
if not name or name == '*' or name.upper() == 'ALL THE THINGS':
|
|
bot._callables = {
|
|
'high': collections.defaultdict(list),
|
|
'medium': collections.defaultdict(list),
|
|
'low': collections.defaultdict(list)
|
|
}
|
|
bot._command_groups = collections.defaultdict(list)
|
|
bot.setup()
|
|
return bot.reply('done')
|
|
|
|
if name not in sys.modules:
|
|
return bot.reply('%s: not loaded, try the `load` command' % name)
|
|
|
|
old_module = sys.modules[name]
|
|
|
|
old_callables = {}
|
|
for obj_name, obj in iteritems(vars(old_module)):
|
|
bot.unregister(obj)
|
|
|
|
# Also remove all references to sopel callables from top level of the
|
|
# module, so that they will not get loaded again if reloading the
|
|
# module does not override them.
|
|
for obj_name in old_callables.keys():
|
|
delattr(old_module, obj_name)
|
|
|
|
# Also delete the setup function
|
|
if hasattr(old_module, "setup"):
|
|
delattr(old_module, "setup")
|
|
|
|
modules = loader.enumerate_modules(bot.config)
|
|
path, type_ = modules[name]
|
|
load_module(bot, name, path, type_)
|
|
|
|
|
|
@module.require_admin
|
|
@module.commands('update')
|
|
def f_update(bot, trigger):
|
|
|
|
"""Pulls the latest versions of all modules from Git"""
|
|
proc = subprocess.Popen('/usr/bin/git pull',
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE, shell=True)
|
|
bot.reply(proc.communicate()[0])
|
|
|
|
f_reload(bot, trigger)
|
|
|
|
|
|
@module.require_admin
|
|
@module.commands("load")
|
|
@module.priority("low")
|
|
@module.thread(False)
|
|
def f_load(bot, trigger):
|
|
"""Loads a module, for use by admins only."""
|
|
|
|
name = trigger.group(2)
|
|
path = ''
|
|
if not name:
|
|
return bot.reply('Load what?')
|
|
|
|
if name in sys.modules:
|
|
return bot.reply('Module already loaded, use reload')
|
|
|
|
mods = loader.enumerate_modules(bot.config)
|
|
if name not in mods:
|
|
return bot.reply('Module %s not found' % name)
|
|
path, type_ = mods[name]
|
|
load_module(bot, name, path, type_)
|