changeset 1155:813d54af8c0c

server (tasks): tasks can now be automatically ran when something happen in a watched dir: A task can specify directories to watch in "WATCH_DIRS" list of path. In dev_mode, when a file is created of modified in a watched dir, the task is run again.
author Goffi <goffi@goffi.org>
date Fri, 22 Feb 2019 18:50:33 +0100
parents a1625e68b726
children 3048bd137aaf
files libervia/server/tasks.py
diffstat 1 files changed, 40 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/server/tasks.py	Fri Feb 22 18:42:47 2019 +0100
+++ b/libervia/server/tasks.py	Fri Feb 22 18:50:33 2019 +0100
@@ -73,7 +73,8 @@
         """Check values in data"""
 
         for var, default, allowed in ((u"ON_ERROR", u"stop", (u"continue", u"stop")),
-                                      (u"LOG_OUTPUT", True, bool)):
+                                      (u"LOG_OUTPUT", True, bool),
+                                      (u"WATCH_DIRS", [], list)):
             value = data.setdefault(var, default)
             if isinstance(allowed, type):
                 if not isinstance(value, allowed):
@@ -128,29 +129,50 @@
             else:
                 prepare(self)
             self.validateData(task_data)
+            if self.host.options['dev_mode']:
+                dirs = task_data.get['WATCH_DIRS']
+                for dir_ in dirs:
+                    self.host.files_watcher.watchDir(
+                        dir_, auto_add=True, recursive=True,
+                        callback=self._autorunTask, task_name=task_name)
+
+    def _autorunTask(self, host, filepath, flags, task_name):
+        """Called when an event is received from a watched directory"""
+        if flags == ['create']:
+            return
+        return self.runTask(task_name)
+
+    @defer.inlineCallbacks
+    def runTask(self, task_name):
+        """Run a single task
+
+        @param task_name(unicode): name of the task to run
+        """
+        task_value = self.tasks[task_name]
+        self._current_task = task_name
+        log.info(_(u'== running task "{task_name}" for {site_name} =='.format(
+            task_name=task_name, site_name=self.site_name)))
+        data = task_value[u'data']
+        os.chdir(self.site_path)
+        try:
+            yield data['start'](self)
+        except Exception as e:
+            on_error = data[u'ON_ERROR']
+            if on_error == u'stop':
+                raise e
+            elif on_error == u'continue':
+                log.warning(_(u'Task "{task_name}" failed for {site_name}: {reason}')
+                    .format(task_name=task_name, site_name=self.site_name, reason=e))
+            else:
+                raise exceptions.InternalError(u"we should never reach this point")
+        self._current_task = None
 
     @defer.inlineCallbacks
     def runTasks(self):
         """Run all the tasks found"""
         old_path = os.getcwd()
         for task_name, task_value in self.tasks.iteritems():
-            self._current_task = task_name
-            log.info(_(u'== running task "{task_name}" for {site_name} =='.format(
-                task_name=task_name, site_name=self.site_name)))
-            data = task_value[u'data']
-            os.chdir(self.site_path)
-            try:
-                yield data['start'](self)
-            except Exception as e:
-                on_error = data[u'ON_ERROR']
-                if on_error == u'stop':
-                    raise e
-                elif on_error == u'continue':
-                    log.warning(_(u'Task "{task_name}" failed for {site_name}: {reason}')
-                        .format(task_name = task_name, site_name = self.site_name, reason = e))
-                else:
-                    raise exceptions.InternalError(u"we should never reach this point")
-            self._current_task = None
+            yield self.runTask(task_name)
         os.chdir(old_path)
 
     def findCommand(self, name, *args):