瀏覽代碼

add feature uninstall resources

nico 8 年之前
父節點
當前提交
6478a1d619
共有 4 個文件被更改,包括 147 次插入28 次删除
  1. 82 0
      Docs/neuron_list.md
  2. 1 16
      Docs/neurons.md
  3. 17 2
      kalliope/__init__.py
  4. 47 10
      kalliope/core/ResourcesManager.py

+ 82 - 0
Docs/neuron_list.md

@@ -44,3 +44,85 @@ A neuron is a module that will perform some actions attached to an order. You ca
 Wanna add your neuron in the list? Open [an issue](../../issues) with the link of your neuron or send a pull request to update the list directly.
 
 To know how to install a community neuron, read the "Installation" section of the [neuron documentation](neurons.md).
+
+## Installation
+
+Core neurons are already packaged with the installation of kalliope an can be used out of the box. Community neuron need to be installed manually.
+>**Note:** To install a neuron, you must declare your `resource_directory` in your [settings](settings.md).
+
+### Via the kalliope's CLI
+
+CLI syntax
+```bash
+kalliope install --git-url <git_url>
+```
+
+E.g:
+```bash
+kalliope install --git-url https://github.com/kalliope-project/kalliope_neuron_wikipedia.git
+```
+You may be prompted to type your `sudo` password during the process.
+
+### Manually
+
+You can also install a neuron manually.
+Fist, clone the repo in the right resource folder. 
+```bash
+cd /path/to/resource_folder
+git clone <plugin_url>
+```
+
+Then install it manually via Ansible (Ansible has been installed with kalliope)
+```bash
+cd <cloned_repo>
+ansible-playbook install.yml -K
+```
+
+Full example
+```bash
+cd /home/me/my_kalliope_config/resources/neurons
+git clone https://github.com/kalliope-project/kalliope_neuron_hue.git
+cd hue
+ansible-playbook install.yml -K
+```
+
+## Uninstall a resource
+### Via the kalliope's CLI
+>**Note:** To uninstall a resource, you must declare the `resource_directory` in your [settings](settings.md).
+
+CLI syntax
+```bash
+kalliope uninstall --neuron-name <neuron_name>
+kalliope uninstall --stt-name <stt_name>
+kalliope uninstall --tts-name <tts_name>
+kalliope uninstall --trigger-name <trigger_name>
+```
+
+E.g:
+```bash
+kalliope uninstall --neuron-name hue
+```
+
+### Manually
+
+To remove a resource, you only need to delete the folder from the corresponding `resource_directory`.
+```bash
+cd /path/to/resource_folder
+rm -rf <resource_name>
+```
+
+E.g
+```bash
+cd /home/me/my_kalliope_config/resources/neurons
+rm -rf hue
+```
+
+>**Note:** When deleting a resource folder, libraries that have been installed by the resource are not removed from the system. If you want a complete cleanup, you'll have to open the install.yml file of the resource to see what have been installed and rollback manually each task.
+For example, when installing the neuron hue, the python lib called phue has been installed. To perform a complete cleanup, you need then to run "sudo pip uninstall phue".
+
+
+## Update a resource
+
+To update a resource, you can either:
+- uninstall the resource and then reinstall it back
+- go into the resource directory and run a `git pull`

+ 1 - 16
Docs/neurons.md

@@ -2,22 +2,7 @@
 
 A neuron is a plugin that performs a specific action. You use it to create a synapse.
 You can add as many neurons as you want to a synapse. The neurons are executed one by one when the input order is triggered.
-
-## Installation
-
-Core neurons are already packaged with the installation of kalliope an can be used out of the box. Community neuron need to be installed manually.
-
-Use the CLI
-```bash
-kalliope install --git-url <git_url>
-```
-
-E.g:
-```bash
-kalliope install --git-url https://github.com/kalliope-project/kalliope_neuron_wikipedia.git
-```
-
-You may be prompted to type your `sudo` password during the process. You can see the list of [available neuron here](neuron_list.md)
+If you want to install a community neuron, see the [neuron list documentation](neuron_list.md).
 
 ## Usage
 Neurons are declared in the `neurons` section of a synapse in your brain file.

+ 17 - 2
kalliope/__init__.py

@@ -34,7 +34,7 @@ def signal_handler(signal, frame):
     sys.exit(0)
 
 # actions available
-ACTION_LIST = ["start", "gui", "install"]
+ACTION_LIST = ["start", "gui", "install", "uninstall"]
 
 
 def main():
@@ -42,7 +42,7 @@ def main():
 
     # create arguments
     parser = argparse.ArgumentParser(description='Kalliope')
-    parser.add_argument("action", help="[start|gui|install]")
+    parser.add_argument("action", help="[start|gui|install|uninstall]")
     parser.add_argument("--run-synapse",
                         help="Name of a synapse to load surrounded by quote")
     parser.add_argument("--run-order", help="order surrounded by a quote")
@@ -50,6 +50,10 @@ def main():
     parser.add_argument("--debug", action='store_true',
                         help="Show debug output")
     parser.add_argument("--git-url", help="Git URL of the neuron to install")
+    parser.add_argument("--neuron-name", help="Neuron name to uninstall")
+    parser.add_argument("--stt-name", help="STT name to uninstall")
+    parser.add_argument("--tts-name", help="TTS name to uninstall")
+    parser.add_argument("--trigger-name", help="Trigger name to uninstall")
     parser.add_argument('-v', '--version', action='version',
                         version='Kalliope ' + version_str)
 
@@ -91,6 +95,17 @@ def main():
             res_manager.install()
         return
 
+    # uninstall modules
+    if args.action == "uninstall":
+        if not args.neuron_name and not args.stt_name and not args.tts_name and not args.trigger_name:
+            Utils.print_danger("You must specify a module name with --neuron-name or --stt-name or --tts-name "
+                               "or --trigger-name")
+        else:
+            res_manager = ResourcesManager()
+            res_manager.uninstall(neuron_name=args.neuron_name, stt_name=args.stt_name,
+                                  tts_name=args.tts_name, trigger_name=args.trigger_name)
+        return
+
     # load the brain once
     brain_loader = BrainLoader(file_path=brain_file)
     brain = brain_loader.brain

+ 47 - 10
kalliope/core/ResourcesManager.py

@@ -54,8 +54,7 @@ class ResourcesManager(object):
         self.git_url = kwargs.get('git_url', None)
 
         # temp path where we install the new module
-        self.tmp_path = tempfile.gettempdir() + "/kalliope/resources/" +\
-                TMP_GIT_FOLDER
+        self.tmp_path = tempfile.gettempdir() + "/kalliope/resources/" + TMP_GIT_FOLDER
         self.dna_file_path = self.tmp_path + os.sep + DNA_FILE_NAME
         self.install_file_path = self.tmp_path + os.sep + INSTALL_FILE_NAME
         self.dna = None
@@ -104,6 +103,39 @@ class ResourcesManager(object):
                                  % str(self.tmp_path))
                     shutil.rmtree(self.tmp_path)
 
+    def uninstall(self, neuron_name=None, tts_name=None, stt_name=None, trigger_name=None):
+        """
+        Uninstall a community resource
+        """
+        target_path_to_delete = None
+        module_name = ""
+        if neuron_name is not None:
+            target_path_to_delete = self._get_target_folder(resources=self.settings.resources,
+                                                            module_type="neuron")
+            module_name = neuron_name
+        if tts_name is not None:
+            target_path_to_delete = self._get_target_folder(resources=self.settings.resources,
+                                                            module_type="neuron")
+            module_name = tts_name
+        if stt_name is not None:
+            target_path_to_delete = self._get_target_folder(resources=self.settings.resources,
+                                                            module_type="neuron")
+            module_name = stt_name
+        if trigger_name is not None:
+            target_path_to_delete = self._get_target_folder(resources=self.settings.resources,
+                                                            module_type="neuron")
+            module_name = trigger_name
+
+        if target_path_to_delete is not None:
+            try:
+                shutil.rmtree(target_path_to_delete + os.sep + module_name)
+                Utils.print_success("Module %s deleted" % module_name)
+            except shutil.Error:
+                Utils.print_warning("The module %s doest not exist in the path %s" % (module_name, target_path_to_delete))
+            except OSError:
+                Utils.print_warning(
+                    "The module %s doest not exist in the path %s" % (module_name, target_path_to_delete))
+
     @staticmethod
     def is_settings_ok(resources, dna):
         """
@@ -169,23 +201,28 @@ class ResourcesManager(object):
         Return the folder from the resources and given a module type
         :param resources: Resource object
         :type resources: Resources
-        :param module_type: type of the module
+        :param module_type: type of the module (TYPE_NEURON, TYPE_STT, TYPE_TTS, TYPE_TRIGGER)
         :return: path of the folder
         """
+        module_type_converter = dict()
         # dict to get the path behind a type of resource
-        module_type_converter = {
-            TYPE_NEURON: resources.neuron_folder,
-            TYPE_STT: resources.stt_folder,
-            TYPE_TTS: resources.tts_folder,
-            TYPE_TRIGGER: resources.trigger_folder
-        }
+        try:
+            module_type_converter = {
+                TYPE_NEURON: resources.neuron_folder,
+                TYPE_STT: resources.stt_folder,
+                TYPE_TTS: resources.tts_folder,
+                TYPE_TRIGGER: resources.trigger_folder
+            }
+        except AttributeError:
+            # will be raised if the resource folder is not set in settings
+            pass
         # Let's find the right path depending of the type
         try:
             folder_path = module_type_converter[module_type]
         except KeyError:
             folder_path = None
         # No folder_path has been found
-        message = "No %s folder set in settings, cannot install." % module_type
+        message = "No %s folder set in settings." % module_type
         if folder_path is None:
             logger.debug(message)
             Utils.print_danger(message)