2015-07-12 20:36:46 +02:00
|
|
|
import logging
|
|
|
|
import time
|
2019-07-10 03:15:46 +02:00
|
|
|
import os
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2015-03-11 16:25:29 +01:00
|
|
|
from Config import config
|
2015-01-12 02:03:45 +01:00
|
|
|
|
2019-03-16 02:42:43 +01:00
|
|
|
if config.debug and config.action == "main":
|
2015-07-12 20:36:46 +02:00
|
|
|
try:
|
2019-03-16 02:42:43 +01:00
|
|
|
import watchdog
|
|
|
|
import watchdog.observers
|
|
|
|
import watchdog.events
|
|
|
|
logging.debug("Watchdog fs listener detected, source code autoreload enabled")
|
|
|
|
enabled = True
|
|
|
|
except Exception as err:
|
|
|
|
logging.debug("Watchdog fs listener could not be loaded: %s" % err)
|
|
|
|
enabled = False
|
2015-03-11 16:25:29 +01:00
|
|
|
else:
|
2019-03-16 02:42:43 +01:00
|
|
|
enabled = False
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
class DebugReloader:
|
2019-08-02 16:19:05 +02:00
|
|
|
def __init__(self, paths=None):
|
|
|
|
if not paths:
|
|
|
|
paths = ["src", "plugins", config.data_dir + "/__plugins__"]
|
2019-03-16 02:42:43 +01:00
|
|
|
self.log = logging.getLogger("DebugReloader")
|
2015-07-12 20:36:46 +02:00
|
|
|
self.last_chaged = 0
|
2019-03-16 02:42:43 +01:00
|
|
|
self.callbacks = []
|
|
|
|
if enabled:
|
2019-04-10 14:56:10 +02:00
|
|
|
self.observer = watchdog.observers.Observer()
|
2019-03-16 02:42:43 +01:00
|
|
|
event_handler = watchdog.events.FileSystemEventHandler()
|
|
|
|
event_handler.on_modified = event_handler.on_deleted = self.onChanged
|
|
|
|
event_handler.on_created = event_handler.on_moved = self.onChanged
|
|
|
|
for path in paths:
|
2019-08-02 16:19:35 +02:00
|
|
|
if not os.path.isdir(path):
|
|
|
|
continue
|
2019-03-16 02:42:43 +01:00
|
|
|
self.log.debug("Adding autoreload: %s" % path)
|
2019-04-10 14:56:10 +02:00
|
|
|
self.observer.schedule(event_handler, path, recursive=True)
|
|
|
|
self.observer.start()
|
2015-01-12 02:03:45 +01:00
|
|
|
|
2019-03-16 02:42:43 +01:00
|
|
|
def addCallback(self, f):
|
|
|
|
self.callbacks.append(f)
|
2015-01-12 02:03:45 +01:00
|
|
|
|
2019-03-16 02:42:43 +01:00
|
|
|
def onChanged(self, evt):
|
|
|
|
path = evt.src_path
|
|
|
|
ext = path.rsplit(".", 1)[-1]
|
|
|
|
if ext not in ["py", "json"] or "Test" in path or time.time() - self.last_chaged < 1.0:
|
|
|
|
return False
|
2018-11-26 00:13:21 +01:00
|
|
|
self.last_chaged = time.time()
|
2019-08-02 16:19:35 +02:00
|
|
|
if os.path.isfile(path):
|
|
|
|
time_modified = os.path.getmtime(path)
|
|
|
|
else:
|
|
|
|
time_modified = 0
|
2019-07-10 03:15:46 +02:00
|
|
|
self.log.debug("File changed: %s reloading source code (modified %.3fs ago)" % (evt, time.time() - time_modified))
|
2019-07-17 16:30:56 +02:00
|
|
|
if time.time() - time_modified > 5: # Probably it's just an attribute change, ignore it
|
|
|
|
return False
|
|
|
|
|
2015-07-12 20:36:46 +02:00
|
|
|
time.sleep(0.1) # Wait for lock release
|
2019-03-16 02:42:43 +01:00
|
|
|
for callback in self.callbacks:
|
|
|
|
try:
|
|
|
|
callback()
|
|
|
|
except Exception as err:
|
|
|
|
self.log.exception(err)
|
|
|
|
|
2019-04-10 14:56:10 +02:00
|
|
|
def stop(self):
|
|
|
|
if enabled:
|
|
|
|
self.observer.stop()
|
|
|
|
self.log.debug("Stopped autoreload observer")
|
|
|
|
|
2019-03-16 02:42:43 +01:00
|
|
|
watcher = DebugReloader()
|