From db5c671bd4a75e972bd8d242dd27e6a15efafffe Mon Sep 17 00:00:00 2001
From: Stein Magnus Jodal
Date: Wed, 21 Nov 2012 02:10:32 +0100
Subject: [PATCH] http: Remove the REST API
---
mopidy/frontends/http/__init__.py | 7 +-
mopidy/frontends/http/actor.py | 6 +-
mopidy/frontends/http/api.py | 95 --------------------
mopidy/frontends/http/data/index.html | 8 --
tests/frontends/http/api_test.py | 120 --------------------------
5 files changed, 4 insertions(+), 232 deletions(-)
delete mode 100644 mopidy/frontends/http/api.py
delete mode 100644 tests/frontends/http/api_test.py
diff --git a/mopidy/frontends/http/__init__.py b/mopidy/frontends/http/__init__.py
index d674e1d0..a23886f8 100644
--- a/mopidy/frontends/http/__init__.py
+++ b/mopidy/frontends/http/__init__.py
@@ -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
diff --git a/mopidy/frontends/http/actor.py b/mopidy/frontends/http/actor.py
index 66ba9f43..ce48b8b3 100644
--- a/mopidy/frontends/http/actor.py
+++ b/mopidy/frontends/http/actor.py
@@ -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,
diff --git a/mopidy/frontends/http/api.py b/mopidy/frontends/http/api.py
deleted file mode 100644
index f5a78f99..00000000
--- a/mopidy/frontends/http/api.py
+++ /dev/null
@@ -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],
- }
diff --git a/mopidy/frontends/http/data/index.html b/mopidy/frontends/http/data/index.html
index a426b4d5..74d85dd6 100644
--- a/mopidy/frontends/http/data/index.html
+++ b/mopidy/frontends/http/data/index.html
@@ -79,14 +79,6 @@
you'll always have the following services available.
-
-
Web service
-
-
Mopidy makes it's API available for use over HTTP at
- /api/. The service tries to be RESTful. It serves and
- eats JSON data.
-
-
WebSocket endpoint
diff --git a/tests/frontends/http/api_test.py b/tests/frontends/http/api_test.py
deleted file mode 100644
index cd77b923..00000000
--- a/tests/frontends/http/api_test.py
+++ /dev/null
@@ -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'])