diff --git a/mopidy_iris/core.py b/mopidy_iris/core.py index a3242e52..39fca300 100755 --- a/mopidy_iris/core.py +++ b/mopidy_iris/core.py @@ -5,7 +5,9 @@ import random, string, logging, json, pykka, pylast, urllib, urllib2, os, sys, m import tornado.web import tornado.websocket import tornado.ioloop +import tornado.httpclient import requests +from promise import Promise from mopidy import config, ext from mopidy.core import CoreListener from pkg_resources import parse_version @@ -584,7 +586,6 @@ class IrisCore(object): } - ## # Proxy a request to an external provider # @@ -594,6 +595,9 @@ class IrisCore(object): ## def proxy_request(self, *args, **kwargs): + callback = kwargs.get('callback', None) + origin_request = kwargs.get('request', None) + try: data = kwargs.get('data', {}) except: @@ -604,7 +608,6 @@ class IrisCore(object): 'source': 'proxy_request' } - origin_request = kwargs.get('request', None) # Our request includes data, so make sure we POST the data if 'url' not in data: @@ -645,7 +648,9 @@ class IrisCore(object): try: # Our request includes data, so make sure we POST the data if ('data' in data and data['data']): - response = requests.post(data['url'], data=data['data'], headers=headers, verify=False) + http_client = tornado.httpclient.AsyncHTTPClient() + request = tornado.httpclient.HTTPRequest(data['url'], method='POST', data=data['data'], headers=headers, validate_cert=False) + http_client.fetch(request, callback=callback) # No data, so just a simple GET request else: @@ -655,7 +660,9 @@ class IrisCore(object): if "Content-Length" in headers: del headers["Content-Length"] - response = requests.get(data['url'], headers=headers, verify=False) + http_client = tornado.httpclient.AsyncHTTPClient() + request = tornado.httpclient.HTTPRequest(data['url'], headers=headers, validate_cert=False) + http_client.fetch(request, callback=callback) # Attempt to decode body as JSON, otherwise just return plain text @@ -679,3 +686,25 @@ class IrisCore(object): 'response_code': int(e.response_code), 'original_request': data } + + + def test(self, *args, **kwargs): + + print "running test 1" + response = requests.get("http://platform.james.plasticstudio.co/test.php?sleep=1") + + return Promise( + lambda resolve, reject: resolve(response.text) + ) + + + def test2(self, *args, **kwargs): + + print "running test 5" + response = requests.get("http://test.barnsley.nz/test.php?sleep=5") + + return Promise( + lambda resolve, reject: resolve(response.text) + ) + + diff --git a/mopidy_iris/handlers.py b/mopidy_iris/handlers.py index c7d67ade..c3cc011e 100755 --- a/mopidy_iris/handlers.py +++ b/mopidy_iris/handlers.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from datetime import datetime from tornado.escape import json_encode, json_decode import tornado.ioloop, tornado.web, tornado.websocket, tornado.template -import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem +import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, urllib2, mem, requests logger = logging.getLogger(__name__) @@ -76,22 +76,17 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): data['connection_id'] = self.connection_id if 'request_id' in message: - request_id = message['request_id'] + data['request_id'] = message['request_id'] else: - request_id = False + data['request_id'] = False # call the method, as specified in payload if 'method' in message: # make sure the method exists if hasattr(mem.iris, message['method']): + getattr(mem.iris, message['method'])(data=data, callback=self.handle_response) - # make the call, and return it's response - response = getattr(mem.iris, message['method'])(data=data) - - if response: - response['request_id'] = request_id - mem.iris.send_message(connection_id=self.connection_id, data=response) else: mem.iris.raven_client.captureMessage("Method "+message['method']+" does not exist") response = { @@ -113,6 +108,23 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): def on_close(self): mem.iris.remove_connection(connection_id=self.connection_id) + ## + # Handle a response from our core + # This is just our callback from an Async request + ## + def handle_response(self, response): + if isinstance(response, tornado.httpclient.HTTPResponse): + response_obj = { + 'body': response.body, + 'request_id': request_id + } + else: + response['request_id'] = request_id + mem.iris.send_message(connection_id=self.connection_id, data=response) + + mem.iris.send_message(connection_id=self.connection_id, data=response) + self.finish() + @@ -134,39 +146,61 @@ class HttpHandler(tornado.web.RequestHandler): self.set_status(204) self.finish() + @tornado.web.asynchronous def get(self, slug=None): # make sure the method exists if hasattr(mem.iris, slug): + self.handle_request(getattr(mem.iris, slug)(request=self.request)) - # make the call, and return it's response - self.write(getattr(mem.iris, slug)(request=self.request)) else: mem.iris.raven_client.captureMessage("Method "+slug+" does not exist") self.write({ 'error': 'Method "'+slug+'" does not exist' }) - + self.finish() + + @tornado.web.asynchronous def post(self, slug=None): # make sure the method exists if hasattr(mem.iris, slug): - try: data = json.loads(self.request.body.decode('utf-8')) - - # make the call, and return it's response - self.write(getattr(mem.iris, slug)(data=data, request=self.request)) + getattr(mem.iris, slug)(data=data, request=self.request, callback=self.handle_response) except urllib2.HTTPError as e: - self.raven_client.captureException() self.write({ 'error': 'Invalid JSON payload' }) + self.finish() else: mem.iris.raven_client.captureMessage("Method "+slug+" does not exist") self.write({ 'error': 'Method "'+slug+'" does not exist' }) + self.finish() + + ## + # Handle a response from our core + # This is just our callback from an Async request + ## + def handle_request(self, request): + response = request.then(lambda response: response).get() + self.write(response) + self.finish() + + ## + # Handle a response from our core + # This is just our callback from an Async request + ## + def handle_response(self, response): + if isinstance(response, tornado.httpclient.HTTPResponse): + self.write(response.body) + else: + self.write(response) + self.finish() + + diff --git a/setup.py b/setup.py index 771c5d81..993953aa 100755 --- a/setup.py +++ b/setup.py @@ -26,7 +26,8 @@ setup( 'Mopidy-Local-Images >= 1.0', 'ConfigObj >= 5.0.6', 'raven >= 6.1.0', - 'requests >= 2.0.0' + 'requests >= 2.0.0', + 'promise >= 2.0.1' ], classifiers=[ 'Environment :: No Input/Output (Daemon)',