From b8ab8d254fc3d34fc08bcd30eb337f2f46af7159 Mon Sep 17 00:00:00 2001
From: Florian RICHER <florian.richer.97@outlook.com>
Date: Sun, 1 May 2022 01:28:36 +0200
Subject: [PATCH] Begin add run app from desktop entries

---
 brain.yml                             |  1 +
 brains/run.yml                        |  9 ++++
 resources/neurons/run_app/.gitignore  |  1 +
 resources/neurons/run_app/__init__.py |  1 +
 resources/neurons/run_app/run_app.py  | 73 +++++++++++++++++++++++++++
 5 files changed, 85 insertions(+)
 create mode 100644 brains/run.yml
 create mode 100644 resources/neurons/run_app/.gitignore
 create mode 100644 resources/neurons/run_app/__init__.py
 create mode 100644 resources/neurons/run_app/run_app.py

diff --git a/brain.yml b/brain.yml
index 694145e..2a7b31d 100755
--- a/brain.yml
+++ b/brain.yml
@@ -6,6 +6,7 @@
         - brains/neurotransmitter.yml
         - brains/kill.yml
         - brains/search.yml
+        - brains/run.yml
 
   - name: "order-not-found-synapse"
     signals: []
diff --git a/brains/run.yml b/brains/run.yml
new file mode 100644
index 0000000..638b8ee
--- /dev/null
+++ b/brains/run.yml
@@ -0,0 +1,9 @@
+- name: "run-app-fr"
+  signals:
+    - order: "lance {{ app }}"
+    - order: "ouvre {{ app }}"
+  neurons:
+    - run_app:
+        app: "{{ app }}"
+        found_message: "Lancement de l'application {{ app }}"
+        not_found_message: "Impossible de trouver l'application {{ app }}"
\ No newline at end of file
diff --git a/resources/neurons/run_app/.gitignore b/resources/neurons/run_app/.gitignore
new file mode 100644
index 0000000..ed8ebf5
--- /dev/null
+++ b/resources/neurons/run_app/.gitignore
@@ -0,0 +1 @@
+__pycache__
\ No newline at end of file
diff --git a/resources/neurons/run_app/__init__.py b/resources/neurons/run_app/__init__.py
new file mode 100644
index 0000000..4d74ecd
--- /dev/null
+++ b/resources/neurons/run_app/__init__.py
@@ -0,0 +1 @@
+from .run_app import Run_app
\ No newline at end of file
diff --git a/resources/neurons/run_app/run_app.py b/resources/neurons/run_app/run_app.py
new file mode 100644
index 0000000..ff12808
--- /dev/null
+++ b/resources/neurons/run_app/run_app.py
@@ -0,0 +1,73 @@
+import subprocess
+import os
+
+from kalliope.core import NeuronModule
+from kalliope.core.NeuronModule import MissingParameterException, MissingParameterException
+
+home_dir = os.path.expanduser('~')
+
+entries_dirs = [
+    os.path.join(home_dir, ".local/share/applications"),
+    "/usr/local/share/applications",
+    "/usr/share/applications"
+]
+
+def parse_exec(line):
+    splitted_line = line.split("=")
+    if len(splitted_line) < 2:
+        return None
+    else:
+        return splitted_line[1]
+
+def check_file(file_path, query):
+    exec = None # Equals to Exec command of .desktop if is before search terms
+    found = False
+    for line in open(file_path, 'r').readlines():
+        if "exec" in line.lower():
+            exec = parse_exec(line)
+        if query.lower() in line.lower():
+            found = True
+        if exec is not None and found is True:
+            return exec
+    return None
+
+def search_app_name_in_desktop_entries(query: str):
+    for d in entries_dirs:
+        if os.path.exists(d):
+            for f in os.listdir(d):
+                if ".desktop" in f:
+                    result = check_file(os.path.join(d, f), query)
+                    if result is not None:
+                        return result
+    return None
+
+class Run_app(NeuronModule):
+    def __init__(self, **kwargs):
+        NeuronModule.__init__(self, **kwargs)
+
+        self.query = kwargs.get('app', None)
+        self.found_message = kwargs.get('found_message', None)
+        self.not_found_message = kwargs.get('not_found_message', None)
+
+        if self._is_parameters_ok():
+            result = search_app_name_in_desktop_entries(self.query)
+            if result is not None:
+                subprocess.Popen(result, shell=True)
+                self.say(self.found_message)
+            else:
+                self.say(self.not_found_message)
+    
+    def _is_parameters_ok(self):
+        """
+        Check if received parameters are ok to perform operations in the neuron
+        :return: true if parameters are ok, raise an exception otherwise
+        .. raises:: MissingParameterException
+        """
+        if self.query is None:
+            raise MissingParameterException("Query parameter is missing.")
+        if self.found_message is None:
+            raise MissingParameterException("Found message parameter is missing.")
+        if self.not_found_message is None:
+            raise MissingParameterException("Not found message parameter is missing.")
+        
+        return True
\ No newline at end of file