http: List installed web clients at /mopidy/
This commit is contained in:
parent
3fb225233a
commit
5861071bb1
@ -35,7 +35,7 @@ class Extension(ext.Extension):
|
|||||||
|
|
||||||
def setup(self, registry):
|
def setup(self, registry):
|
||||||
from .actor import HttpFrontend
|
from .actor import HttpFrontend
|
||||||
from .handlers import mopidy_app_factory
|
from .handlers import make_mopidy_app_factory
|
||||||
|
|
||||||
HttpFrontend.apps = registry['http:app']
|
HttpFrontend.apps = registry['http:app']
|
||||||
HttpFrontend.statics = registry['http:static']
|
HttpFrontend.statics = registry['http:static']
|
||||||
@ -43,5 +43,6 @@ class Extension(ext.Extension):
|
|||||||
registry.add('frontend', HttpFrontend)
|
registry.add('frontend', HttpFrontend)
|
||||||
registry.add('http:app', {
|
registry.add('http:app', {
|
||||||
'name': 'mopidy',
|
'name': 'mopidy',
|
||||||
'factory': mopidy_app_factory,
|
'factory': make_mopidy_app_factory(
|
||||||
|
registry['http:app'], registry['http:static']),
|
||||||
})
|
})
|
||||||
|
|||||||
31
mopidy/http/data/clients.html
Normal file
31
mopidy/http/data/clients.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Mopidy</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="mopidy.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="box focus">
|
||||||
|
<h1>Mopidy</h1>
|
||||||
|
|
||||||
|
<p>This web server is a part of the Mopidy music server. To learn more
|
||||||
|
about Mopidy, please visit
|
||||||
|
<a href="http://www.mopidy.com/">www.mopidy.com</a>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<h2>Web clients</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for app in apps %}
|
||||||
|
<li><a href="/{{ url_escape(app) }}/">{{ escape(app) }}</a></li>
|
||||||
|
{% end %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Web clients which are installed as Mopidy extensions will
|
||||||
|
automatically appear here.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -15,19 +15,24 @@ from mopidy.utils import jsonrpc
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def mopidy_app_factory(config, core):
|
def make_mopidy_app_factory(apps, statics):
|
||||||
return [
|
def mopidy_app_factory(config, core):
|
||||||
(r'/ws/?', WebSocketHandler, {
|
return [
|
||||||
'core': core,
|
(r'/ws/?', WebSocketHandler, {
|
||||||
}),
|
'core': core,
|
||||||
(r'/rpc', JsonRpcHandler, {
|
}),
|
||||||
'core': core,
|
(r'/rpc', JsonRpcHandler, {
|
||||||
}),
|
'core': core,
|
||||||
(r'/(.*)', StaticFileHandler, {
|
}),
|
||||||
'path': os.path.join(os.path.dirname(__file__), 'data'),
|
(r'/(.+)', StaticFileHandler, {
|
||||||
'default_filename': 'index.html'
|
'path': os.path.join(os.path.dirname(__file__), 'data'),
|
||||||
}),
|
}),
|
||||||
]
|
(r'/', ClientListHandler, {
|
||||||
|
'apps': apps,
|
||||||
|
'statics': statics,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
return mopidy_app_factory
|
||||||
|
|
||||||
|
|
||||||
def make_jsonrpc_wrapper(core_actor):
|
def make_jsonrpc_wrapper(core_actor):
|
||||||
@ -142,6 +147,24 @@ class JsonRpcHandler(tornado.web.RequestHandler):
|
|||||||
self.set_header('Content-Type', 'application/json; utf-8')
|
self.set_header('Content-Type', 'application/json; utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
class ClientListHandler(tornado.web.RequestHandler):
|
||||||
|
def initialize(self, apps, statics):
|
||||||
|
self.apps = apps
|
||||||
|
self.statics = statics
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
set_mopidy_headers(self)
|
||||||
|
|
||||||
|
names = set()
|
||||||
|
for app in self.apps:
|
||||||
|
names.add(app['name'])
|
||||||
|
for static in self.statics:
|
||||||
|
names.add(static['name'])
|
||||||
|
names.discard('mopidy')
|
||||||
|
|
||||||
|
self.render('data/clients.html', apps=sorted(list(names)))
|
||||||
|
|
||||||
|
|
||||||
class StaticFileHandler(tornado.web.StaticFileHandler):
|
class StaticFileHandler(tornado.web.StaticFileHandler):
|
||||||
def set_extra_headers(self, path):
|
def set_extra_headers(self, path):
|
||||||
set_mopidy_headers(self)
|
set_mopidy_headers(self)
|
||||||
|
|||||||
@ -25,10 +25,13 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase):
|
|||||||
core.get_version = mock.MagicMock(name='get_version')
|
core.get_version = mock.MagicMock(name='get_version')
|
||||||
core.get_version.return_value = mopidy.__version__
|
core.get_version.return_value = mopidy.__version__
|
||||||
|
|
||||||
|
apps = [dict(name='testapp')]
|
||||||
|
statics = [dict(name='teststatic')]
|
||||||
|
|
||||||
http_frontend = actor.HttpFrontend(config=config, core=core)
|
http_frontend = actor.HttpFrontend(config=config, core=core)
|
||||||
http_frontend.apps = [{
|
http_frontend.apps = [{
|
||||||
'name': 'mopidy',
|
'name': 'mopidy',
|
||||||
'factory': handlers.mopidy_app_factory,
|
'factory': handlers.make_mopidy_app_factory(apps, statics),
|
||||||
}]
|
}]
|
||||||
|
|
||||||
return tornado.web.Application(http_frontend._get_request_handlers())
|
return tornado.web.Application(http_frontend._get_request_handlers())
|
||||||
@ -57,10 +60,12 @@ class RootAppTest(HttpServerTest):
|
|||||||
class MopidyAppTest(HttpServerTest):
|
class MopidyAppTest(HttpServerTest):
|
||||||
def test_should_return_index(self):
|
def test_should_return_index(self):
|
||||||
response = self.fetch('/mopidy/', method='GET')
|
response = self.fetch('/mopidy/', method='GET')
|
||||||
|
body = tornado.escape.to_unicode(response.body)
|
||||||
|
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
'This web server is a part of the Mopidy music server.',
|
'This web server is a part of the Mopidy music server.', body)
|
||||||
tornado.escape.to_unicode(response.body))
|
self.assertIn('testapp', body)
|
||||||
|
self.assertIn('teststatic', body)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
response.headers['X-Mopidy-Version'], mopidy.__version__)
|
||||||
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
self.assertEqual(response.headers['Cache-Control'], 'no-cache')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user