From 968de84b932589552327ddc4c0c0d293168d30f5 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 18 Nov 2012 19:02:36 +0100 Subject: [PATCH] http: Broadcast all events over the WebSocket --- mopidy/frontends/http/actor.py | 47 +++++++++-- tests/frontends/http/events_test.py | 124 ++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 tests/frontends/http/events_test.py diff --git a/mopidy/frontends/http/actor.py b/mopidy/frontends/http/actor.py index b0697409..66ba9f43 100644 --- a/mopidy/frontends/http/actor.py +++ b/mopidy/frontends/http/actor.py @@ -1,11 +1,12 @@ from __future__ import unicode_literals import logging +import json import os import pykka -from mopidy import exceptions, settings +from mopidy import exceptions, models, settings from mopidy.core import CoreListener try: @@ -88,11 +89,45 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener): cherrypy.engine.exit() logger.info('Stopped HTTP server') - def playback_state_changed(self, old_state, new_state): - cherrypy.engine.publish( - 'websocket-broadcast', - TextMessage('playback_state_changed: %s -> %s' % ( - old_state, new_state))) + def track_playback_paused(self, **data): + self._broadcast_event('track_playback_paused', data) + + def track_playback_resumed(self, **data): + self._broadcast_event('track_playback_resumed', data) + + def track_playback_started(self, **data): + self._broadcast_event('track_playback_started', data) + + def track_playback_ended(self, **data): + self._broadcast_event('track_playback_ended', data) + + def playback_state_changed(self, **data): + self._broadcast_event('playback_state_changed', data) + + def tracklist_changed(self, **data): + self._broadcast_event('tracklist_changed', data) + + def playlists_loaded(self, **data): + self._broadcast_event('playlists_loaded', data) + + def playlist_changed(self, **data): + self._broadcast_event('playlist_changed', data) + + def options_changed(self, **data): + self._broadcast_event('options_changed', data) + + def volume_changed(self, **data): + self._broadcast_event('volume_changed', data) + + def seeked(self, **data): + self._broadcast_event('seeked', data) + + def _broadcast_event(self, name, data): + event = {} + event.update(data) + event['event'] = name + message = json.dumps(event, cls=models.ModelJSONEncoder) + cherrypy.engine.publish('websocket-broadcast', TextMessage(message)) class RootResource(object): diff --git a/tests/frontends/http/events_test.py b/tests/frontends/http/events_test.py new file mode 100644 index 00000000..95812eb0 --- /dev/null +++ b/tests/frontends/http/events_test.py @@ -0,0 +1,124 @@ +import json + +import cherrypy +import mock + +from mopidy.frontends.http import HttpFrontend + +from tests import unittest + + +@mock.patch.object(cherrypy.engine, 'publish') +class HttpEventsTest(unittest.TestCase): + def setUp(self): + self.http = HttpFrontend(None) + + def test_track_playback_paused_is_broadcasted(self, publish): + publish.reset_mock() + self.http.track_playback_paused(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'track_playback_paused', + 'foo': 'bar', + }) + + def test_track_playback_resumed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.track_playback_resumed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'track_playback_resumed', + 'foo': 'bar', + }) + + def test_track_playback_started_is_broadcasted(self, publish): + publish.reset_mock() + self.http.track_playback_started(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'track_playback_started', + 'foo': 'bar', + }) + + def test_track_playback_ended_is_broadcasted(self, publish): + publish.reset_mock() + self.http.track_playback_ended(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'track_playback_ended', + 'foo': 'bar', + }) + + def test_playback_state_changed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.playback_state_changed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'playback_state_changed', + 'foo': 'bar', + }) + + def test_tracklist_changed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.tracklist_changed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'tracklist_changed', + 'foo': 'bar', + }) + + def test_playlists_loaded_is_broadcasted(self, publish): + publish.reset_mock() + self.http.playlists_loaded(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'playlists_loaded', + 'foo': 'bar', + }) + + def test_playlist_changed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.playlist_changed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'playlist_changed', + 'foo': 'bar', + }) + + def test_options_changed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.options_changed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'options_changed', + 'foo': 'bar', + }) + + def test_volume_changed_is_broadcasted(self, publish): + publish.reset_mock() + self.http.volume_changed(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'volume_changed', + 'foo': 'bar', + }) + + def test_seeked_is_broadcasted(self, publish): + publish.reset_mock() + self.http.seeked(foo='bar') + self.assertEqual(publish.call_args[0][0], 'websocket-broadcast') + self.assertDictEqual( + json.loads(str(publish.call_args[0][1])), { + 'event': 'seeked', + 'foo': 'bar', + })