mirror of
https://github.com/solero/houdini.git
synced 2025-10-25 08:48:13 +00:00
Initial commit
This commit is contained in:
79
Houdini/Events/HandlerFileEvent.py
Normal file
79
Houdini/Events/HandlerFileEvent.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import sys
|
||||
import importlib
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
|
||||
from Houdini.Handlers import listeners_from_module
|
||||
from Houdini.Events import evaluate_handler_file_event, remove_handlers_by_module
|
||||
|
||||
|
||||
class HandlerFileEventHandler(FileSystemEventHandler):
|
||||
|
||||
def __init__(self, server):
|
||||
self.logger = server.logger
|
||||
self.server = server
|
||||
|
||||
def on_created(self, event):
|
||||
handler_module_details = evaluate_handler_file_event(event)
|
||||
|
||||
if not handler_module_details:
|
||||
return
|
||||
|
||||
handler_module_path, handler_module = handler_module_details
|
||||
|
||||
if "__init__.py" in handler_module_path:
|
||||
return
|
||||
|
||||
self.logger.debug("New handler module detected %s", handler_module)
|
||||
|
||||
try:
|
||||
module = importlib.import_module(handler_module)
|
||||
listeners_from_module(self.server.xt_listeners, self.server.xml_listeners, module)
|
||||
except Exception as import_error:
|
||||
self.logger.error("%s detected in %s, not importing.", import_error.__class__.__name__, handler_module)
|
||||
|
||||
def on_deleted(self, event):
|
||||
handler_module_details = evaluate_handler_file_event(event)
|
||||
|
||||
if not handler_module_details:
|
||||
return
|
||||
|
||||
handler_module_path, handler_module = handler_module_details
|
||||
|
||||
if handler_module not in sys.modules:
|
||||
return
|
||||
|
||||
self.logger.debug("Deleting listeners registered by %s..", handler_module)
|
||||
|
||||
remove_handlers_by_module(self.server.xt_listeners, self.server.xml_listeners, handler_module_path)
|
||||
|
||||
def on_modified(self, event):
|
||||
handler_module_details = evaluate_handler_file_event(event)
|
||||
|
||||
if not handler_module_details:
|
||||
return
|
||||
|
||||
handler_module_path, handler_module = handler_module_details
|
||||
|
||||
if handler_module not in sys.modules:
|
||||
return False
|
||||
|
||||
self.logger.info("Reloading %s", handler_module)
|
||||
|
||||
xt_listeners, xml_listeners = remove_handlers_by_module(self.server.xt_listeners, self.server.xml_listeners,
|
||||
handler_module_path)
|
||||
|
||||
handler_module_object = sys.modules[handler_module]
|
||||
|
||||
try:
|
||||
module = importlib.reload(handler_module_object)
|
||||
listeners_from_module(self.server.xt_listeners, self.server.xml_listeners, module)
|
||||
|
||||
self.logger.info("Successfully reloaded %s!", handler_module)
|
||||
except Exception as rebuild_error:
|
||||
self.logger.error("%s detected in %s, not reloading.", rebuild_error.__class__.__name__, handler_module)
|
||||
self.logger.info("Restoring handler references...")
|
||||
|
||||
self.server.xt_listeners = xt_listeners
|
||||
self.server.xml_listeners = xml_listeners
|
||||
|
||||
self.logger.info("Handler references restored. Phew!")
|
||||
54
Houdini/Events/__init__.py
Normal file
54
Houdini/Events/__init__.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import os
|
||||
import copy
|
||||
|
||||
|
||||
def evaluate_handler_file_event(handler_file_event):
|
||||
# Ignore all directory events
|
||||
if handler_file_event.is_directory:
|
||||
return False
|
||||
|
||||
handler_module_path = handler_file_event.src_path[2:]
|
||||
|
||||
# Ignore non-Python files
|
||||
if handler_module_path[-3:] != ".py":
|
||||
return False
|
||||
|
||||
handler_module = handler_module_path.replace(os.path.sep, ".")[:-3]
|
||||
|
||||
return handler_module_path, handler_module
|
||||
|
||||
|
||||
def evaluate_plugin_file_event(plugin_file_event):
|
||||
# Ignore all directory events
|
||||
if plugin_file_event.is_directory:
|
||||
return False
|
||||
|
||||
handler_module_path = plugin_file_event.src_path[2:]
|
||||
|
||||
# Ignore non-Python files
|
||||
if handler_module_path[-3:] != ".py":
|
||||
return False
|
||||
|
||||
# Remove file extension and replace path separator with dots. Then make like a banana.. and split.
|
||||
handler_module_tokens = handler_module_path.replace(os.path.sep, ".")[:-3].split(".")
|
||||
|
||||
if handler_module_tokens.pop() == "__init__":
|
||||
return handler_module_path, ".".join(handler_module_tokens)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def remove_handlers_by_module(xt_listeners, xml_listeners, handler_module_path):
|
||||
def remove_handlers(remove_handler_items):
|
||||
for handler_id, handler_listeners in remove_handler_items:
|
||||
for handler_listener in handler_listeners:
|
||||
if handler_listener.handler_file == handler_module_path:
|
||||
handler_listeners.remove(handler_listener)
|
||||
|
||||
xt_handler_collection = copy.copy(xt_listeners)
|
||||
remove_handlers(xt_listeners.items())
|
||||
|
||||
xml_handler_collection = copy.copy(xml_listeners)
|
||||
remove_handlers(xml_listeners.items())
|
||||
|
||||
return xt_handler_collection, xml_handler_collection
|
||||
Reference in New Issue
Block a user