83 lines
2.2 KiB
Python
83 lines
2.2 KiB
Python
from time import sleep
|
|
from pathlib import Path
|
|
|
|
from module import Module, ModuleLoadError, MissingEntryFunctionError
|
|
from utils import printable_exception
|
|
|
|
|
|
class ModuleManager:
|
|
|
|
def __init__(self, folder, entry="run"): #TODO "run" as function name? or is "main" better?
|
|
self.folder = Path(folder)
|
|
self.entry = entry
|
|
self.modules = {}
|
|
self.update()
|
|
|
|
|
|
def run(self, sleep_time=2):
|
|
while True:
|
|
print("-" * 20)
|
|
self.update()
|
|
sleep(sleep_time)
|
|
|
|
|
|
def update(self):
|
|
self._update_cached()
|
|
self._update_new()
|
|
self._run_all()
|
|
|
|
|
|
def _update_cached(self):
|
|
for fn, mod in tuple(self.modules.items()):
|
|
mod_missing = not mod.file_exists()
|
|
mod_has_changed = mod.has_changed()
|
|
|
|
if mod_missing or mod_has_changed:
|
|
if mod_missing:
|
|
print(f"{fn} does not exist... removing cached module")
|
|
elif mod_has_changed:
|
|
print(f"{fn} has changed... removing cached module for reloading")
|
|
|
|
mod.kill()
|
|
del self.modules[fn]
|
|
|
|
|
|
def _update_new(self):
|
|
for fn in self.get_fnames():
|
|
if fn in self.modules:
|
|
print(f"{fn} already cached... skipping load")
|
|
continue
|
|
|
|
mod = Module(fn, self.entry)
|
|
print("loading:", mod)
|
|
|
|
try:
|
|
mod.load()
|
|
except ModuleLoadError as e:
|
|
print(f"loading {fn} raised", printable_exception(e))
|
|
except MissingEntryFunctionError:
|
|
print(f"missing function {self.entry}() in {fn}")
|
|
|
|
self.modules[fn] = mod
|
|
|
|
|
|
def _run_all(self):
|
|
for mod in self.modules.values():
|
|
if mod.is_running:
|
|
print(f"{mod.name} is running already")
|
|
continue
|
|
|
|
print(f"{mod.name} starting")
|
|
try:
|
|
mod.start()
|
|
except MissingEntryFunctionError:
|
|
print(f"{mod.name} has no function {self.entry}() to run")
|
|
|
|
|
|
def get_fnames(self):
|
|
fns = self.folder.glob("*.py")
|
|
return sorted(fns)
|
|
|
|
|
|
|