http: Remove the REST API

This commit is contained in:
Stein Magnus Jodal 2012-11-21 02:10:32 +01:00
parent 532a915db8
commit db5c671bd4
5 changed files with 4 additions and 232 deletions

View File

@ -20,10 +20,9 @@ Frontend which lets you control Mopidy through HTTP and WebSockets.
When this frontend is included in :attr:`mopidy.settings.FRONTENDS`, it starts
a web server at the port specified by :attr:`mopidy.settings.HTTP_SERVER_PORT`.
This web server exposes both a REST web service at the URL ``/api``, and a
WebSocket at ``/ws``. The REST API gives you access to most Mopidy
functionality, while the WebSocket enables Mopidy to instantly push events to
the client, as they happen.
This web server exposes a WebSocket at ``/ws``. The WebSocket gives you access
to Mopidy's full API and enables Mopidy to instantly push events to the client,
as they happen.
The web server can also host any static files, for example the HTML, CSS,
JavaScript and images needed by a web based Mopidy client. To host static

View File

@ -16,7 +16,7 @@ try:
except ImportError as import_error:
raise exceptions.OptionalDependencyError(import_error)
from . import api, ws
from . import ws
logger = logging.getLogger('mopidy.frontends.http')
@ -45,7 +45,6 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
def _create_app(self):
root = RootResource()
root.api = api.ApiResource(self.core)
root.ws = ws.WebSocketResource(self.core)
if settings.HTTP_SERVER_STATIC_DIR:
@ -60,9 +59,6 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener):
'tools.staticdir.index': 'index.html',
'tools.staticdir.dir': static_dir,
},
b'/api': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
},
b'/ws': {
'tools.websocket.on': True,
'tools.websocket.handler_cls': ws.WebSocketHandler,

View File

@ -1,95 +0,0 @@
from __future__ import unicode_literals
from mopidy import exceptions
try:
import cherrypy
except ImportError as import_error:
raise exceptions.OptionalDependencyError(import_error)
class ApiResource(object):
exposed = True
def __init__(self, core):
self.core = core
self.player = PlayerResource(core)
self.tracklist = TrackListResource(core)
self.playlists = PlaylistsResource(core)
@cherrypy.tools.json_out()
def GET(self):
return {
'resources': {
'player': {
'href': '/api/player/',
},
'tracklist': {
'href': '/api/tracklist/',
},
'playlists': {
'href': '/api/playlists/',
},
}
}
class PlayerResource(object):
exposed = True
def __init__(self, core):
self.core = core
@cherrypy.tools.json_out()
def GET(self):
properties = {
'state': self.core.playback.state,
'currentTrack': self.core.playback.current_track,
'consume': self.core.playback.consume,
'random': self.core.playback.random,
'repeat': self.core.playback.repeat,
'single': self.core.playback.single,
'volume': self.core.playback.volume,
'timePosition': self.core.playback.time_position,
}
for key, value in properties.items():
properties[key] = value.get()
if properties['currentTrack']:
properties['currentTrack'] = properties['currentTrack'].serialize()
return {'properties': properties}
class TrackListResource(object):
exposed = True
def __init__(self, core):
self.core = core
@cherrypy.tools.json_out()
def GET(self):
tl_tracks_future = self.core.tracklist.tl_tracks
current_tl_track_future = self.core.playback.current_tl_track
tracks = []
for tl_track in tl_tracks_future.get():
track = tl_track.track.serialize()
track['tlid'] = tl_track.tlid
tracks.append(track)
current_tl_track = current_tl_track_future.get()
return {
'currentTrackTlid': current_tl_track and current_tl_track.tlid,
'tracks': tracks,
}
class PlaylistsResource(object):
exposed = True
def __init__(self, core):
self.core = core
@cherrypy.tools.json_out()
def GET(self):
playlists = self.core.playlists.playlists.get()
return {
'playlists': [p.serialize() for p in playlists],
}

View File

@ -79,14 +79,6 @@
you'll always have the following services available.</p>
</div>
<div class="box">
<h2>Web service</h2>
<p>Mopidy makes it's API available for use over HTTP at
<a href="/api/">/api/</a>. The service tries to be RESTful. It serves and
eats JSON data.</p>
</div>
<div class="box">
<h2>WebSocket endpoint</h2>

View File

@ -1,120 +0,0 @@
from __future__ import unicode_literals
import pykka
from tests import unittest
from mopidy import core
from mopidy.backends import dummy
from mopidy.frontends.http import api
from mopidy.models import Track
class ApiResourceTest(unittest.TestCase):
def setUp(self):
self.backend = dummy.DummyBackend.start(audio=None).proxy()
self.core = core.Core.start(backends=[self.backend]).proxy()
self.api = api.ApiResource(core=self.core)
self.core.playlists.create('x')
self.core.playlists.create('y')
self.core.playlists.create('z')
self.core.tracklist.append([
Track(uri='dummy:a'),
Track(uri='dummy:b'),
Track(uri='dummy:c'),
])
def tearDown(self):
pykka.ActorRegistry.stop_all()
def test_api_get_returns_list_of_resources(self):
result = self.api.GET()
self.assertIn('resources', result)
self.assertIn('player', result['resources'])
self.assertEquals(
'/api/player/', result['resources']['player']['href'])
self.assertIn('tracklist', result['resources'])
self.assertEquals(
'/api/tracklist/', result['resources']['tracklist']['href'])
self.assertIn('playlists', result['resources'])
self.assertEquals(
'/api/playlists/', result['resources']['playlists']['href'])
def test_player_get_returns_playback_properties(self):
result = self.api.player.GET()
self.assertIn('properties', result)
self.assertIn('state', result['properties'])
self.assertEqual('stopped', result['properties']['state'])
self.assertIn('currentTrack', result['properties'])
self.assertEqual(None, result['properties']['currentTrack'])
self.assertIn('consume', result['properties'])
self.assertEqual(False, result['properties']['consume'])
self.assertIn('random', result['properties'])
self.assertEqual(False, result['properties']['random'])
self.assertIn('repeat', result['properties'])
self.assertEqual(False, result['properties']['repeat'])
self.assertIn('single', result['properties'])
self.assertEqual(False, result['properties']['single'])
self.assertIn('volume', result['properties'])
self.assertEqual(None, result['properties']['volume'])
self.assertIn('timePosition', result['properties'])
self.assertEqual(0, result['properties']['timePosition'])
def test_player_state_changes_when_playing(self):
self.core.playback.play()
result = self.api.player.GET()
self.assertEqual('playing', result['properties']['state'])
def test_player_volume_changes(self):
self.core.playback.volume = 37
result = self.api.player.GET()
self.assertEqual(37, result['properties']['volume'])
def test_tracklist_returns_tracklist(self):
result = self.api.tracklist.GET()
self.assertIn('tracks', result)
self.assertEqual(3, len(result['tracks']))
self.assertEqual('dummy:a', result['tracks'][0]['uri'])
self.assertEqual(0, result['tracks'][0]['tlid'])
self.assertEqual('dummy:b', result['tracks'][1]['uri'])
self.assertEqual(1, result['tracks'][1]['tlid'])
self.assertEqual('dummy:c', result['tracks'][2]['uri'])
self.assertEqual(2, result['tracks'][2]['tlid'])
def test_tracklist_includes_current_track(self):
self.core.playback.play()
result = self.api.tracklist.GET()
self.assertIn('currentTrackTlid', result)
self.assertEqual(0, result['currentTrackTlid'])
def test_playlists_returns_playlists(self):
result = self.api.playlists.GET()
self.assertIn('playlists', result)
self.assertEqual('x', result['playlists'][0]['name'])
self.assertEqual('y', result['playlists'][1]['name'])
self.assertEqual('z', result['playlists'][2]['name'])