mopidy/mopidy/http/handlers.py
dz0ny f1d1a4713b Squashed commit of the following:
commit dbb7005aa866cdc337bde9c8169e9bf15e5c8042
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 11 22:12:58 2014 +0200

    Fix: Make PR mergable

commit 5bb27da72c4276a930bf33955e6583f6781d23f6
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Thu May 8 23:31:54 2014 +0200

    Add: helper method for extensin url

commit 8a348b26b65102084a606ff73384a478bb785cf1
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Thu May 8 00:35:50 2014 +0200

    Add: Refactor ws and rpc to handlers, reuse code

commit 677c809d2b39a6c982ab835368fdb8a3ad9d1a92
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Thu May 8 00:18:10 2014 +0200

    Fix: Return proper HTTP headers

commit fe5fea2fc2a0d28a39532d6d4cd2b21013d57d24
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Wed May 7 23:48:19 2014 +0200

    Add: RPC post handler
    Add: tests for http post handler

commit e77e60310853b368758b09b303a96a95ff1b9b93
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 4 22:15:04 2014 +0200

    Add: Documentation on how to extend http api

commit a3a14fb5d15f095e5bab23a590e0a8360a039f9a
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 4 19:48:34 2014 +0200

    Add: HTTP tests for default router and static handler

commit 0d9544256bcb8f048eaedb5cdd57b1de027d387b
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 4 15:44:32 2014 +0200

    Fix: Move StaticFileHandler to main http package

commit c83c9f661e658e4a843dc5c8c6ba5dc3f1ea9c1e
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 4 15:29:49 2014 +0200

    Add: default Router implementation

commit 258cb7210bdf13833884c04cfb7fb4fa704394a7
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sun May 4 15:00:46 2014 +0200

    Add: Switch to registry for router registration

commit b7bfe7b814235b030d7ac30de90e2331e3d809d3
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sat May 3 21:52:58 2014 +0200

    Fix: Private methods
    Fix: Point to mopidy.html instead main.html
    Fix: Less noise in console

commit 232abe3029e93f78ce25db0c1bd44743cc23ed2d
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sat May 3 21:32:07 2014 +0200

    Fix: Start IOLoop in separate thread, so actor can stop it

commit d686892c2fa993cbedc99c8e8e7f9c961ac6f35a
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sat May 3 19:30:49 2014 +0200

    Fix: Router load order
    Fix: JS helper library WSS default url
    Add: Handlers from extensions

commit a1b0f5673a6719f229df27feccb284324675e9d1
Author: dz0ny <dz0ny@ubuntu.si>
Date:   Sat May 3 14:53:30 2014 +0200

    Add: Switch to Tornado framework
2014-05-12 14:54:50 +02:00

119 lines
3.6 KiB
Python

from __future__ import unicode_literals
import logging
from mopidy import __version__, core, models
from mopidy.utils import jsonrpc
import tornado.escape
import tornado.web
import tornado.websocket
logger = logging.getLogger(__name__)
def construct_rpc(actor):
inspector = jsonrpc.JsonRpcInspector(
objects={
'core.get_uri_schemes': core.Core.get_uri_schemes,
'core.get_version': core.Core.get_version,
'core.library': core.LibraryController,
'core.playback': core.PlaybackController,
'core.playlists': core.PlaylistsController,
'core.tracklist': core.TracklistController,
})
return jsonrpc.JsonRpcWrapper(
objects={
'core.describe': inspector.describe,
'core.get_uri_schemes': actor.core.get_uri_schemes,
'core.get_version': actor.core.get_version,
'core.library': actor.core.library,
'core.playback': actor.core.playback,
'core.playlists': actor.core.playlists,
'core.tracklist': actor.core.tracklist,
},
decoders=[models.model_json_decoder],
encoders=[models.ModelJSONEncoder]
)
class WebSocketHandler(tornado.websocket.WebSocketHandler):
actor = None
jsonrpc = None
def initialize(self, actor):
self.actor = actor
self.jsonrpc = construct_rpc(actor)
@classmethod
def broadcast(cls, clients, msg):
for client in clients:
client.write_message(msg)
def open(self):
self.set_nodelay(True)
self.actor.websocket_clients.add(self)
logger.debug(
'New WebSocket connection from %s', self.request.remote_ip)
def on_close(self):
self.actor.websocket_clients.discard(self)
logger.debug(
'Closed WebSocket connection from %s',
self.request.remote_ip)
def on_message(self, message):
if not message:
return
logger.debug(
'Received WebSocket message from %s: %r',
self.request.remote_ip, message)
try:
response = self.jsonrpc.handle_json(
tornado.escape.native_str(message)
)
if response and self.write_message(response):
logger.debug(
'Sent WebSocket message to %s: %r',
self.request.remote_ip, response)
except Exception as e:
logger.error('WebSocket request error:', e)
self.close()
class JsonRpcHandler(tornado.web.RequestHandler):
def initialize(self, actor):
self.jsonrpc = construct_rpc(actor)
def head(self):
self.set_extra_headers()
self.finish()
def post(self):
data = self.request.body
if not data:
return
logger.debug('Received RPC message from %s: %r',
self.request.remote_ip, data)
try:
self.set_extra_headers()
response = self.jsonrpc.handle_json(
tornado.escape.native_str(data))
if response and self.write(response):
logger.debug('Sent RPC message to %s: %r',
self.request.remote_ip, response)
except Exception as e:
logger.error('HTTP JSON-RPC request error:', e)
self.write_error(500)
def set_extra_headers(self):
self.set_header('Accept', 'application/json')
self.set_header('Cache-Control', 'no-cache')
self.set_header('X-Mopidy-Version', __version__.encode(
'utf-8'))
self.set_header('Content-Type', 'application/json; utf-8')