瀏覽代碼

Merge branch 'dev' into Doc

monf 8 年之前
父節點
當前提交
000aed0bff
共有 7 個文件被更改,包括 73 次插入54 次删除
  1. 15 15
      brain.yml
  2. 2 1
      brains/say.yml
  3. 1 1
      core/ConfigurationManager/ConfigurationChecker.py
  4. 21 33
      core/ConfigurationManager/YAMLLoader.py
  5. 25 2
      core/ShellGui.py
  6. 8 1
      kalliope.py
  7. 1 1
      settings.yml

+ 15 - 15
brain.yml

@@ -1,16 +1,16 @@
 ---
-- includes:
-  - brains/ansible_playbook.yml
-  - brains/gmail_checker.yml
-  - brains/kill_switch.yml
-  - brains/openweathermap.yml
-  - brains/push_message.yml
-  - brains/say.yml
-  - brains/script.yml
-  - brains/shell.yml
-  - brains/systemdate.yml
-  - brains/tasker_autoremote.yml
-  - brains/wake_on_lan.yml
-  - brains/twitter.yml
-  - brains/neurotransmitter.yml
-  - brains/wikipedia.yml
+  - includes:
+    - brains/ansible_playbook.yml
+    - brains/gmail_checker.yml
+    - brains/kill_switch.yml
+    - brains/openweathermap.yml
+    - brains/push_message.yml
+    - brains/say.yml
+    - brains/script.yml
+    - brains/shell.yml
+    - brains/systemdate.yml
+    - brains/tasker_autoremote.yml
+    - brains/wake_on_lan.yml
+    - brains/twitter.yml
+    - brains/neurotransmitter.yml
+    - brains/wikipedia.yml

+ 2 - 1
brains/say.yml

@@ -5,4 +5,5 @@
           message:
             - "Bonjour monsieur"
     signals:
-      - order: "bonjour"
+      - order: "bonjour"
+      - order: "Bonjour"

+ 1 - 1
core/ConfigurationManager/ConfigurationChecker.py

@@ -1,6 +1,6 @@
 import re
 
-from core.Utils import Utils, ModuleNotFoundError
+from core.Utils import ModuleNotFoundError
 
 
 class InvalidSynapeName(Exception):

+ 21 - 33
core/ConfigurationManager/YAMLLoader.py

@@ -1,8 +1,7 @@
 import logging
 import os
-import yaml
 
-from core.Utils import Utils
+import yaml
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -28,36 +27,14 @@ class YAMLLoader:
         root_dir = os.path.join(current_dir, "../../")
         root_dir = os.path.normpath(root_dir)
         logger.debug("Root dir: %s " % root_dir)
-        file_path_to_load = os.path.join(root_dir, yaml_file)
-        logger.debug("File path to load: %s " % file_path_to_load)
-        if os.path.isfile(yaml_file):
-            # data = IncludeLoader(open(file_path_to_load, 'r')).get_data()
-            # print Utils.print_yaml_nicely(data)
-            data = IncludeImport(file_path_to_load).get_data()
+        cls.file_path_to_load = os.path.join(root_dir, yaml_file)
+        logger.debug("File path to load: %s " % cls.file_path_to_load)
+        if os.path.isfile(cls.file_path_to_load):
+            inc_import = IncludeImport(cls.file_path_to_load)
+            data = inc_import.get_data()
             return data
         else:
-            raise YAMLFileNotFound("File %s not found" % file_path_to_load)
-
-
-class IncludeLoader(yaml.Loader):
-
-    def __init__(self, *args, **kwargs):
-        super(IncludeLoader, self).__init__(*args, **kwargs)
-        self.add_constructor('#include', self._include)
-        if 'root' in kwargs:
-            self.root = kwargs['root']
-        elif isinstance(self.stream, file):
-            self.root = os.path.dirname(self.stream.name)
-        else:
-            self.root = os.path.curdir
-
-    def _include(self, loader, node):
-        oldRoot = self.root
-        filename = os.path.join(self.root, loader.construct_scalar(node))
-        self.root = os.path.dirname(filename)
-        data = yaml.load(open(filename, 'r'))
-        self.root = oldRoot
-        return data
+            raise YAMLFileNotFound("File %s not found" % cls.file_path_to_load)
 
 
 class IncludeImport(object):
@@ -67,12 +44,22 @@ class IncludeImport(object):
         Load yaml file, with includes statement
         :param file_path: path to the yaml file to load
         """
+        # get the parent dir. will be used in case of relative path
+        parent_dir = os.path.normpath(file_path + os.sep + os.pardir)
+
+        # load the yaml file
         self.data = yaml.load(open(file_path, 'r'))
-        # print "content: %s" % self.data
+
+        # add included brain
         if isinstance(self.data, list):
             for el in self.data:
                 if "includes" in el:
                     for inc in el["includes"]:
+                        # if the path is relative, we add the root path
+                        if not os.path.isabs(inc):  # os.path.isabs returns True if the path is absolute
+                            # logger.debug("File path %s is relative, adding the root path" % inc)
+                            inc = os.path.join(parent_dir, inc)
+                            # logger.debug("New path: %s" % inc)
                         self.update(yaml.load(open(inc)))
 
     def get_data(self):
@@ -82,7 +69,8 @@ class IncludeImport(object):
         # print "cur_data: %s" % self.data
         # print "data to add %s" % data_to_add
         # we add each synapse inside the extended brain into the main brain data
-        for el in data_to_add:
-            self.data.append(el)
+        if data_to_add is not None:
+            for el in data_to_add:
+                self.data.append(el)
         # print "final data: %s" % self.data
 

+ 25 - 2
core/ShellGui.py

@@ -18,6 +18,12 @@ logger = logging.getLogger("kalliope")
 
 
 def signal_handler(signal, frame):
+    """
+    Used to catch a keyboard signal like Ctrl+C in order to kill the kalliope program
+    :param signal: signal handler
+    :param frame: execution frame
+    :return:
+    """
     print "\n"
     Utils.print_info("Ctrl+C pressed. Killing Kalliope")
     sys.exit(0)
@@ -27,6 +33,10 @@ signal.signal(signal.SIGINT, signal_handler)
 
 class ShellGui:
     def __init__(self, brain=None):
+        """
+        Load a GUI in a shell console for testing TTS, STT and brain configuration
+        :param brain:
+        """
         # override brain
         self.brain = brain
 
@@ -61,6 +71,11 @@ class ShellGui:
                 self.show_synapses_test_menu()
 
     def show_stt_test_menu(self):
+        """
+        Show the list of available STT.
+        Clicking on a STT will load the engine to catch the user audio and return a text
+        :return:
+        """
         # we get STT from settings
         stt_list = self.settings.stts
         logger.debug("Loaded stt list: %s" % str(stt_list))
@@ -69,17 +84,23 @@ class ShellGui:
         code, tag = self.d.menu("Select the STT to test:",
                                 choices=choices)
 
+        # go back to the main menu if we choose "cancel"
         if code == self.d.CANCEL:
             self.show_main_menu()
 
+        # if ok, call the target TTS engine and catch audio
         if code == self.d.OK:
             self.d.infobox("Please talk now")
+            # the callback funtion will print the translated audio into text on the screen
             order_listener = OrderListener(callback=self.callback_stt, stt=str(tag))
             order_listener.load_stt_plugin()
 
     def show_tts_test_menu(self, sentence_to_test=None):
         """
-         A menu for testing text to speech
+        A menu for testing text to speech
+        - select a TTS engine to test
+        - type a sentence
+        - press ok and listen the generated audio from the typed text
         :return:
         """
         continue_bool = True
@@ -109,6 +130,7 @@ class ShellGui:
             if code == self.d.OK:
                 self._run_tts_test(tag, sentence_to_test)
                 # then go back to this menu with the same sentence
+                # if the user want to test the same text with another TTS
                 self.show_tts_test_menu(sentence_to_test=sentence_to_test)
 
     @staticmethod
@@ -116,7 +138,7 @@ class ShellGui:
         """
         Call the TTS
         :param tts_name: Name of the TTS module to launch
-        :param sentence_to_test:
+        :param sentence_to_test: String text to send to the TTS engine
         :return:
         """
         sentence_to_test = sentence_to_test.encode('utf-8')
@@ -142,6 +164,7 @@ class ShellGui:
     def callback_stt(self, audio):
         """
         Callback function called after the STT has finish his job
+        Print the text of what the STT engine think we said on the screen
         :param audio: Text from the translated audio
         """
         code = self.d.msgbox("The STT engine think you said:\n %s" % audio, width=50)

+ 8 - 1
kalliope.py

@@ -18,10 +18,17 @@ logger = logging.getLogger("kalliope")
 
 
 def signal_handler(signal, frame):
+    """
+    Used to catch a keyboard signal like Ctrl+C in order to kill the kalliope program
+    :param signal: signal handler
+    :param frame: execution frame
+    :return:
+    """
     print "\n"
     Utils.print_info("Ctrl+C pressed. Killing Kalliope")
     sys.exit(0)
 
+# actions available
 ACTION_LIST = ["start", "gui"]
 
 
@@ -39,6 +46,7 @@ def main():
     # parse arguments from script parameters
     args = parser.parse_args()
 
+    # require at least one parameter, the action
     if len(sys.argv[1:]) == 0:
         parser.print_usage()
         sys.exit(1)
@@ -62,7 +70,6 @@ def main():
         parser.print_help()
 
     if args.action == "start":
-
         # user set a synapse to start
         if args.run_synapse is not None:
             SynapseLauncher.start_synapse(args.run_synapse, brain=brain)

+ 1 - 1
settings.yml

@@ -48,7 +48,7 @@ speech_to_text:
 # Text to speech
 # ---------------------------
 # This is the default TTS that will be used by Kalliope to talk.
-default_text_to_speech: "voicerss"
+default_text_to_speech: "acapela"
 # where we store generated audio files from TTS engine to reuse them
 cache_path: "/tmp/kalliope_tts_cache"