New watchdog module based file change watching

This commit is contained in:
shortcutme 2019-03-16 02:42:43 +01:00
parent 75d8338f2d
commit e92f3ea100
No known key found for this signature in database
GPG key ID: 5B63BAE6CB9613AE
5 changed files with 41 additions and 42 deletions

View file

@ -1,53 +1,52 @@
import logging import logging
import time import time
import threading
from Config import config from Config import config
if config.debug: # Only load pyfilesytem if using debug mode if config.debug and config.action == "main":
try: try:
import fs.watch import watchdog
import fs.osfs import watchdog.observers
pyfilesystem = fs.osfs.OSFS("src") import watchdog.events
pyfilesystem_plugins = fs.osfs.OSFS("plugins") logging.debug("Watchdog fs listener detected, source code autoreload enabled")
logging.debug("Pyfilesystem detected, source code autoreload enabled") enabled = True
except Exception, err: except Exception as err:
pyfilesystem = False logging.debug("Watchdog fs listener could not be loaded: %s" % err)
enabled = False
else: else:
pyfilesystem = False enabled = False
class DebugReloader: class DebugReloader:
def __init__(self, paths=["src", "plugins"]):
def __init__(self, callback, directory="/"): self.log = logging.getLogger("DebugReloader")
self.last_chaged = 0 self.last_chaged = 0
if pyfilesystem: self.callbacks = []
self.directory = directory if enabled:
self.callback = callback observer = watchdog.observers.Observer()
if config.action == "main": event_handler = watchdog.events.FileSystemEventHandler()
logging.debug("Adding autoreload: %s, cb: %s" % (directory, callback)) event_handler.on_modified = event_handler.on_deleted = self.onChanged
thread = threading.Thread(target=self.addWatcher) event_handler.on_created = event_handler.on_moved = self.onChanged
thread.daemon = True for path in paths:
thread.start() self.log.debug("Adding autoreload: %s" % path)
observer.schedule(event_handler, path, recursive=True)
observer.start()
def addWatcher(self, recursive=True): def addCallback(self, f):
try: self.callbacks.append(f)
time.sleep(1) # Wait for .pyc compiles
watch_events = [fs.watch.CREATED, fs.watch.MODIFIED]
pyfilesystem.add_watcher(self.changed, path=self.directory, events=watch_events, recursive=recursive)
pyfilesystem_plugins.add_watcher(self.changed, path=self.directory, events=watch_events, recursive=recursive)
except Exception, err:
print "File system watcher failed: %s (on linux pyinotify not gevent compatible yet :( )" % err
def changed(self, evt): def onChanged(self, evt):
if ( path = evt.src_path
not evt.path or "%s/" % config.data_dir in evt.path or ext = path.rsplit(".", 1)[-1]
(not evt.path.endswith("py") and not evt.path.endswith("json")) or if ext not in ["py", "json"] or "Test" in path or time.time() - self.last_chaged < 1.0:
"Test" in evt.path or return False
time.time() - self.last_chaged < 5.0
):
return False # Ignore *.pyc changes and no reload within 1 sec
self.last_chaged = time.time() self.last_chaged = time.time()
logging.debug("File changed: %s, cb: %s reloading source code" % (evt.path, self.callback)) self.log.debug("File changed: %s reloading source code" % path)
time.sleep(0.1) # Wait for lock release time.sleep(0.1) # Wait for lock release
self.callback() for callback in self.callbacks:
try:
callback()
except Exception as err:
self.log.exception(err)
watcher = DebugReloader()

View file

@ -345,7 +345,7 @@ class FileServer(ConnectionServer):
if config.debug: if config.debug:
# Auto reload FileRequest on change # Auto reload FileRequest on change
from Debug import DebugReloader from Debug import DebugReloader
DebugReloader(self.reload) DebugReloader.watcher.addCallback(self.reload)
if check_sites: # Open port, Update sites, Check files integrity if check_sites: # Open port, Update sites, Check files integrity
gevent.spawn(self.checkSites) gevent.spawn(self.checkSites)

View file

@ -25,7 +25,7 @@ class PluginManager:
if config.debug: # Auto reload Plugins on file change if config.debug: # Auto reload Plugins on file change
from Debug import DebugReloader from Debug import DebugReloader
DebugReloader(self.reloadPlugins) DebugReloader.watcher.addCallback(self.reloadPlugins)
def migratePlugins(self): def migratePlugins(self):
for dir_name in os.listdir(self.plugin_path): for dir_name in os.listdir(self.plugin_path):

View file

@ -39,7 +39,7 @@ class Translate(dict):
if config.debug: if config.debug:
# Auto reload FileRequest on change # Auto reload FileRequest on change
from Debug import DebugReloader from Debug import DebugReloader
DebugReloader(self.load) DebugReloader.watcher.addCallback(self.load)
translates.append(self) translates.append(self)

View file

@ -123,7 +123,7 @@ class UiServer:
if config.debug: if config.debug:
# Auto reload UiRequest on change # Auto reload UiRequest on change
from Debug import DebugReloader from Debug import DebugReloader
DebugReloader(self.reload) DebugReloader.watcher.addCallback(self.reload)
# Werkzeug Debugger # Werkzeug Debugger
try: try: