Add module touch reloading in pubsubbot

This commit is contained in:
dave 2017-11-27 23:21:48 -08:00
parent 7379d03153
commit 8606561074
2 changed files with 47 additions and 2 deletions

View File

@ -10,6 +10,7 @@ import pyircbot
import traceback import traceback
from pyircbot.pyircbot import PrimitiveBot from pyircbot.pyircbot import PrimitiveBot
from pyircbot.irccore import IRCEvent, UserPrefix from pyircbot.irccore import IRCEvent, UserPrefix
from pyircbot.common import TouchReload
from json import dumps from json import dumps
@ -109,6 +110,7 @@ if __name__ == "__main__":
parser.add_argument("-p", "--port", default=7100, type=int, help="Msgbus server port") parser.add_argument("-p", "--port", default=7100, type=int, help="Msgbus server port")
parser.add_argument("-n", "--name", default="default", help="bot name") parser.add_argument("-n", "--name", default="default", help="bot name")
parser.add_argument("--debug", action="store_true", help="increase logging level") parser.add_argument("--debug", action="store_true", help="increase logging level")
parser.add_argument("--touch-reload", action="store_true", help="reload modules on file modification")
args = parser.parse_args() args = parser.parse_args()
if args.debug: if args.debug:
@ -122,10 +124,25 @@ if __name__ == "__main__":
bot = PyIRCBotSub(args.name, args.server, int(args.port), config) bot = PyIRCBotSub(args.name, args.server, int(args.port), config)
# Load modules in config # Load modules in config
sys.path.append(os.path.dirname(pyircbot.__file__) + "/modules/") moddir = os.path.join(os.path.dirname(pyircbot.__file__), "modules")
modpaths = []
sys.path.append(moddir)
for modulename in config["modules"]: for modulename in config["modules"]:
print("Load: ", modulename)
bot.loadmodule(modulename) bot.loadmodule(modulename)
modpaths.append(os.path.join(moddir, modulename + ".py"))
if args.touch_reload:
def changed(path):
module_name = os.path.basename(path).split(".")[-2]
logging.warning("{} was modified, reloading".format(module_name))
if module_name in bot.moduleInstances.keys(): # TODO fix shitty mystery results from redomodule in core
bot.redomodule(module_name)
else:
bot.loadmodule(module_name)
reloader = TouchReload(modpaths, changed)
reloader.daemon = True
reloader.start()
bot.run() bot.run()

View File

@ -2,6 +2,9 @@ from time import time
from math import floor from math import floor
from json import load as json_load from json import load as json_load
from collections import namedtuple from collections import namedtuple
from time import sleep
import os
from threading import Thread
ParsedCommand = namedtuple("ParsedCommand", "command args args_str message") ParsedCommand = namedtuple("ParsedCommand", "command args args_str message")
@ -46,6 +49,31 @@ class burstbucket(object):
return self.bucket_period - since_fill return self.bucket_period - since_fill
class TouchReload(Thread):
def __init__(self, filepaths, do, resolution=0.75):
"""
Given a list of module files, call a lambda if the modification times changes
:param filepaths: list of filepaths
:param do: lambda to call with the altered filepath
"""
super().__init__()
self.files = [[os.path.normpath(i), None] for i in filepaths]
self.do = do
self.sleep = resolution
def run(self):
while True:
for num, (path, mtime) in enumerate(self.files):
new_mtime = os.stat(path).st_mtime
if mtime is None:
self.files[num][1] = new_mtime
continue
if mtime != new_mtime:
self.files[num][1] = new_mtime
self.do(path)
sleep(self.sleep)
def messageHasCommand(command, message, requireArgs=False): def messageHasCommand(command, message, requireArgs=False):
"""Check if a message has a command with or without args in it """Check if a message has a command with or without args in it