diff --git a/IRIS_VERSION b/IRIS_VERSION index 1c6dce98..df6486ea 100755 --- a/IRIS_VERSION +++ b/IRIS_VERSION @@ -1 +1 @@ -3.43.0 \ No newline at end of file +3.44.0 \ No newline at end of file diff --git a/mopidy_iris/core.py b/mopidy_iris/core.py index d9b21602..d341c1dd 100755 --- a/mopidy_iris/core.py +++ b/mopidy_iris/core.py @@ -452,68 +452,58 @@ class IrisCore(pykka.ThreadingActor): # Restart Mopidy # This requires sudo access to system.sh ## - def restart(self, *args, **kwargs): + async def restart(self, *args, **kwargs): callback = kwargs.get('callback', False) - # Trigger the action - IrisSystemThread('restart', self.restart_callback).start() - self.broadcast(data={ 'method': "restart_started" }) - response = { - 'message': "Restart started" - } if (callback): - callback(response) - else: - return response + callback({ + 'message': "Restarting..." + }) - def restart_callback(self, response, error): - if error: + task_response = await IrisSystemThread('restart').run() + + if 'error' in task_response: self.broadcast(data={ 'method': "restart_error", - 'params': error + 'params': task_response }) else: self.broadcast(data={ - 'method': "restart_finished" + 'method': "restart_finished", + 'params': task_response }) ## # Run an upgrade of Iris ## - def upgrade(self, *args, **kwargs): + async def upgrade(self, *args, **kwargs): callback = kwargs.get('callback', False) self.broadcast(data={ 'method': "upgrade_started" }) - # Trigger the action - IrisSystemThread('upgrade', self.upgrade_callback).start() - - response = { - 'message': "Upgrade started" - } - if (callback): - callback(response) - else: - return response + callback({ + 'message': "Upgrade started" + }) + + task_response = await IrisSystemThread('upgrade').run() - def upgrade_callback(self, response, error): - if error: + if 'error' in task_response: self.broadcast(data={ 'method': "upgrade_error", - 'params': error + 'params': task_response }) else: self.broadcast(data={ 'method': "upgrade_finished", - 'params': response + 'params': task_response }) self.restart() @@ -525,31 +515,26 @@ class IrisCore(pykka.ThreadingActor): async def local_scan(self, *args, **kwargs): callback = kwargs.get('callback', False) - # Trigger the action - await IrisSystemThread('local_scan', self.local_scan_callback).start() - self.broadcast(data={ 'method': "local_scan_started" }) - response = { - 'message': "Local scan started" - } if (callback): - callback(response) - else: - return response + callback({ + 'message': "Local scan started" + }) + + task_response = await IrisSystemThread('local_scan').run() - def local_scan_callback(self, response, error): - if error: + if 'error' in task_response: self.broadcast(data={ 'method': "local_scan_error", - 'params': error + 'params': task_response }) else: self.broadcast(data={ 'method': "local_scan_finished", - 'params': response + 'params': task_response }) @@ -988,7 +973,7 @@ class IrisCore(pykka.ThreadingActor): try: http_client = tornado.httpclient.HTTPClient() - request = tornado.httpclient.HTTPRequest(url, method='POST', body=urllib.urlencode(data)) + request = tornado.httpclient.HTTPRequest(url, method='POST', body=urllib.parse.urlencode(data)) response = http_client.fetch(request) token = json.loads(response.body) @@ -1085,33 +1070,27 @@ class IrisCore(pykka.ThreadingActor): ## # Simple test method. Not for use in production for any purposes. ## - def test(self, *args, **kwargs): + async def test(self, *args, **kwargs): callback = kwargs.get('callback', False) self.broadcast(data={ 'method': "test_started" }) - # Trigger the action - IrisSystemThread('test', self.test_callback).start() - - response = { - 'message': "Running test... please wait" - } if (callback): - callback(response) - else: - return response + callback({ + 'message': "Running test... please wait" + }) - def test_callback(self, response, error): - if error: + task_response = await IrisSystemThread('test').run() + + if 'error' in task_response: self.broadcast(data={ 'method': "test_error", - 'params': error + 'params': task_response }) else: self.broadcast(data={ 'method': "test_finished", - 'params': response + 'params': task_response }) - diff --git a/mopidy_iris/handlers.py b/mopidy_iris/handlers.py index 821ca3c4..b625f135 100755 --- a/mopidy_iris/handlers.py +++ b/mopidy_iris/handlers.py @@ -67,6 +67,8 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): # make sure the method exists if hasattr(iris, message['method']): try: + + # For async methods we need to await, but it must be ommited for syncronous methods if asyncio.iscoroutinefunction(getattr(iris, message['method'])): await getattr(iris, message['method'])(data=params, callback=lambda response, error=False: self.handle_result(id=id, method=message['method'], response=response, error=error)) else: @@ -147,6 +149,8 @@ class HttpHandler(tornado.web.RequestHandler): # make sure the method exists if hasattr(iris, slug): try: + + # For async methods we need to await, but it must be ommited for syncronous methods if asyncio.iscoroutinefunction(getattr(iris, slug)): await getattr(iris, slug)(request=self, callback=lambda response, error=False: self.handle_result(id=id, method=slug, response=response, error=error)) else: diff --git a/mopidy_iris/system.py b/mopidy_iris/system.py index 186bc0c1..6391c819 100755 --- a/mopidy_iris/system.py +++ b/mopidy_iris/system.py @@ -1,21 +1,19 @@ from threading import Thread -import os, logging, subprocess, json +import os, logging, subprocess, json, asyncio # import logger logger = logging.getLogger(__name__) -class IrisSystemThread(Thread): - def __init__(self, action, callback): - Thread.__init__(self) +class IrisSystemThread: + def __init__(self, action): self.action = action - self.callback = callback self.path = os.path.dirname(__file__) ## # Run the defined action ## - def run(self): + async def run(self): logger.info("Running system action '"+self.action+"'") try: @@ -27,23 +25,29 @@ class IrisSystemThread(Thread): 'message': "Permission denied", 'description': str(e) } - - if self.callback: - self.callback(False, error) - return - - # Run the actual task (this is the process-blocking instruction) - output = subprocess.check_output([self.path+"/system.sh "+self.action], shell=True) - - logger.debug("System action '"+self.action+"' completed with output:") - logger.debug(output) - - # And then, when complete, return to our callback - if self.callback: - response = { - 'output': str(output) + + return { + 'error': error + } + + logger.debug("sudo "+ self.path +"/system.sh "+ self.action) + + proc = subprocess.Popen(["sudo", self.path+"/system.sh", self.action], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + + stdout,stderr = proc.communicate() + + if stderr: + logger.error(stderr.decode()) + return { + 'error': stderr.decode() + } + else: + logger.info(stdout.decode()) + return { + 'output': stdout.decode() } - self.callback(response, False) ## diff --git a/mopidy_iris/system.sh b/mopidy_iris/system.sh index 8efc6eee..3b9bd867 100755 --- a/mopidy_iris/system.sh +++ b/mopidy_iris/system.sh @@ -1,7 +1,5 @@ #!/bin/bash -echo -e "Running $1 yeah nah" - if [[ "$(pwd)" = "/iris/mopidy_iris/system.sh" ]]; then IS_CONTAINER=true else @@ -34,9 +32,9 @@ elif [[ $1 = "local_scan" ]]; then elif [[ $1 = "test" ]]; then - sleep 3 + sleep 5 - TEST="$(echo 'Hello, this is your bash speaking. I was sleeping for 3 seconds.')" + TEST="$(echo 'Hello, this is your bash speaking. I was sleeping for 5 seconds.')" echo -e "${TEST}" else