瀏覽代碼

add new event manager based on APScheduler lib

nico 8 年之前
父節點
當前提交
76d09cacde

+ 1 - 0
install/files/python_requirements.txt

@@ -20,3 +20,4 @@ httpretty==0.8.14
 mock==2.0.0
 feedparser==5.2.1
 Flask-Testing==0.6.1
+apscheduler==3.3.0

+ 10 - 0
kalliope/brain-test.yml

@@ -0,0 +1,10 @@
+---
+  - name: "say-hello-fr"
+    signals:
+      - event:
+          hour: "18"
+          minute: "08"
+    neurons:
+      - say:
+          message:
+            - "Bonjour monsieur"

+ 23 - 3
kalliope/core/ConfigurationManager/BrainLoader.py

@@ -165,8 +165,8 @@ class BrainLoader(object):
 
         return signals
 
-    @staticmethod
-    def _get_event_or_order_from_dict(signal_or_event_dict):
+    @classmethod
+    def _get_event_or_order_from_dict(cls, signal_or_event_dict):
         """
         The signal is either an Event or an Order
 
@@ -186,7 +186,7 @@ class BrainLoader(object):
             # print "is event"
             event = signal_or_event_dict["event"]
             if ConfigurationChecker.check_event_dict(event):
-                return Event(period=event)
+                return cls._get_event_object(event)
 
         if 'order' in signal_or_event_dict:
             order = signal_or_event_dict["order"]
@@ -215,3 +215,23 @@ class BrainLoader(object):
         if os.path.isfile(brain_path):
             return brain_path
         raise IOError("Default brain.yml file not found")
+
+    @classmethod
+    def _get_event_object(cls, event_dict):
+        def get_key(key_name):
+            try:
+                return event_dict[key_name]
+            except KeyError:
+                return None
+
+        year = get_key("year")
+        month = get_key("month")
+        day = get_key("day")
+        week = get_key("week")
+        day_of_week = get_key("day_of_week")
+        hour = get_key("hour")
+        minute = get_key("minute")
+        second = get_key("second")
+
+        return Event(year=year, month=month, day=day, week=week,
+                     day_of_week=day_of_week, hour=hour, minute=minute, second=second)

+ 26 - 1
kalliope/core/ConfigurationManager/ConfigurationChecker.py

@@ -196,8 +196,33 @@ class ConfigurationChecker:
         .. raises:: NoEventPeriod
         .. warnings:: Static and Public
         """
+        def get_key(key_name):
+            try:
+                return event_dict[key_name]
+            except KeyError:
+                return None
+
         if event_dict is None or event_dict == "":
-            raise NoEventPeriod("Event must contain a period: %s" % event_dict)
+            raise NoEventPeriod("Event must contain at least one of those elements: "
+                                "year, month, day, week, day_of_week, hour, minute, second")
+
+        # check content as at least on key
+        year = get_key("year")
+        month = get_key("month")
+        day = get_key("day")
+        week = get_key("week")
+        day_of_week = get_key("day_of_week")
+        hour = get_key("hour")
+        minute = get_key("minute")
+        second = get_key("second")
+
+        list_to_check = [year, month, day, week, day_of_week, hour, minute, second]
+        number_of_none_object = list_to_check.count(None)
+        list_size = len(list_to_check)
+        if number_of_none_object >= list_size:
+            raise NoEventPeriod("Event must contain at least one of those elements: "
+                                "year, month, day, week, day_of_week, hour, minute, second")
+
         return True
 
     @staticmethod

+ 51 - 0
kalliope/core/EventManager.py

@@ -0,0 +1,51 @@
+from apscheduler.schedulers.background import BackgroundScheduler
+from apscheduler.triggers.cron import CronTrigger
+
+from kalliope import BrainLoader
+from kalliope import SynapseLauncher
+from kalliope import Utils
+from kalliope.core.Models import Event
+
+
+class EventManager(object):
+
+    def __init__(self, synapses):
+        self.scheduler = BackgroundScheduler()
+        self.synapses = synapses
+
+        self.load_events()
+
+        self.scheduler.start()
+        Utils.print_info('Starting event manager')
+
+    def load_events(self):
+        """
+        For each received synapse that have an event as signal, we add a new job scheduled
+        to launch the synapse
+        :return:
+        """
+        for synapse in self.synapses:
+            for signal in synapse.signals:
+                # if the signal is an event we add it to the task list
+                if type(signal) == Event:
+                    my_cron = CronTrigger(year=signal.year,
+                                          month=signal.month,
+                                          day=signal.day,
+                                          week=signal.week,
+                                          day_of_week=signal.day_of_week,
+                                          hour=signal.hour,
+                                          minute=signal.minute,
+                                          second=signal.second)
+                    Utils.print_info("Add synapse name \"%s\" to the scheduler: %s" % (synapse.name, my_cron))
+                    self.scheduler.add_job(self.run_synapse_by_name, my_cron, args=[synapse.name])
+
+    @staticmethod
+    def run_synapse_by_name(synapse_name):
+        """
+        This method will run the synapse
+        """
+        print("EventManager, run synapse name %s" % synapse_name)
+        # get a brain
+        brain_loader = BrainLoader()
+        brain = brain_loader.brain
+        SynapseLauncher.start_synapse(synapse_name, brain=brain)

+ 23 - 5
kalliope/core/Models/Event.py

@@ -5,12 +5,21 @@ class Event(object):
     .. note:: Events are based on the system crontab
     """
 
-    def __init__(self, period):
-        self.period = period
+    def __init__(self, year=None, month=None, day=None, week=None, day_of_week=None,
+                 hour=None, minute=None, second=None):
+        self.year = year
+        self.month = month
+        self.day = day
+        self.week = week
+        self.day_of_week = day_of_week
+        self.hour = hour
+        self.minute = minute
+        self.second = second
 
     def __str__(self):
-        return "%s: period: %s" % (self.__class__.__name__,
-                                   self.period)
+        return "%s:  year: %s, month: %s, day: %s, week: %s, day_of_week: %s, hour: %s, minute: %s, second: %s" \
+               % (self.__class__.__name__, self.year, self.month, self.day, self.week,
+                  self.day_of_week, self.hour, self.minute, self.second)
 
     def serialize(self):
         """
@@ -21,7 +30,16 @@ class Event(object):
         """
 
         return {
-            'event': self.period
+            'event': {
+                "year": self.year,
+                "month": self.month,
+                "day": self.day,
+                "week": self.week,
+                "day_of_week": self.day_of_week,
+                "hour": self.hour,
+                "minute": self.minute,
+                "second": self.second,
+            }
         }
 
     def __eq__(self, other):

+ 2 - 1
setup.py

@@ -78,7 +78,8 @@ setup(
         'httpretty==0.8.14',
         'mock==2.0.0',
         'feedparser==5.2.1',
-        'Flask-Testing==0.6.1'
+        'Flask-Testing==0.6.1',
+        'apscheduler==3.3.0'
     ],