Merge pull request #215 from jcass77/enhance/host_info

Detect if MMW is running on 'MusicBox' and show correct server info.
This commit is contained in:
Nick Steel 2016-12-08 09:51:18 +00:00 committed by GitHub
commit d507f6c681
10 changed files with 83 additions and 22 deletions

View File

@ -110,6 +110,8 @@ v2.4.0 (UNRELEASED)
- Only show 'Show Album' or 'Show Artist' options in popup menus if URI's for those resources are available. - Only show 'Show Album' or 'Show Artist' options in popup menus if URI's for those resources are available.
(Fixes: `#213 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/213>`_). (Fixes: `#213 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/213>`_).
- Now shows correct hostname information in loader popup. (Fixes: `#209 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/209>`_).
- Now shows server name/IP address and port number at the bottom of the navigation pane. (Fixes: `#67 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/67>`_).
v2.3.0 (2016-05-15) v2.3.0 (2016-05-15)
------------------- -------------------

View File

@ -160,6 +160,16 @@
display: inline; display: inline;
} }
div.hostInfo {
width: 100%;
text-align: center;
}
span.hostInfo {
font-weight: normal;
font-size: 0.75em;
}
/******************** /********************
* Pages, content * * Pages, content *
********************/ ********************/

View File

@ -16,7 +16,7 @@
<link rel="shortcut icon" type="image/x-icon" href="images/icons/musicbox32.gif" /> <link rel="shortcut icon" type="image/x-icon" href="images/icons/musicbox32.gif" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="MusicBox" /> <meta name="apple-mobile-web-app-title" content="{{ title }}" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="HandheldFriendly" content="True" /> <meta name="HandheldFriendly" content="True" />
<meta name="MobileOptimized" content="320" /> <meta name="MobileOptimized" content="320" />
@ -36,8 +36,8 @@
</head> </head>
<body data-websocket-url="{{websocketUrl}}" data-is-musicbox="{{isMusicBox}}" data-has-alarmclock="{{hasAlarmClock}}" data-on-track-click="{{onTrackClick}}"> <body data-websocket-url="{{ websocketUrl }}" data-is-musicbox="{{ isMusicBox }}" data-has-alarmclock="{{ hasAlarmClock }}" data-on-track-click="{{ onTrackClick }}" data-program-name="{{ programName }}" data-hostname="{{ hostname }}">
<div data-role="page" id="page" class="ui-responsive-panel" data-theme="c"> <div data-role="page" id="page" class="ui-responsive-panel" data-theme="c" data-title="{{ title }}">
<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="reveal" data-position-fixed="true"> <div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="reveal" data-position-fixed="true">
<ul class="ui-listview mainNav" data-role="listview" data-theme="a"> <ul class="ui-listview mainNav" data-role="listview" data-theme="a">
@ -93,6 +93,15 @@
value="0" max="100"/> value="0" max="100"/>
</div> </div>
</li> </li>
<li data-icon="false">
<div class="hostInfo">
{% if hostname == serverIP %}
<span class="hostInfo">{{programName}} running on {{ hostname }}:{{ serverPort}}</span>
{% else %}
<span class="hostInfo">{{programName}} running on {{ hostname }}/{{ serverIP }}:{{ serverPort}}</span>
{% end %}
</div>
</li>
</ul> </ul>
</div> </div>
@ -216,7 +225,7 @@
<div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="header-breakpoint headerbtn"> <div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="header-breakpoint headerbtn">
<a id="headermenubtn" href="#panel"><i class="fa fa-align-justify"></i></a> <a id="headermenubtn" href="#panel"><i class="fa fa-align-justify"></i></a>
<h1 id="contentHeadline">Musicbox</h1> <h1 id="contentHeadline">Initializing...</h1>
<a id="headersearchbtn" href="#" onclick="switchContent('search' ); return false;" title="Search"><i class="fa fa-search"></i></a> <a id="headersearchbtn" href="#" onclick="switchContent('search' ); return false;" title="Search"><i class="fa fa-search"></i></a>
</div> </div>
<!-- /header --> <!-- /header -->

View File

@ -652,7 +652,6 @@
window.history.back() window.history.back()
}, 10000) }, 10000)
} }
} }
return controls return controls
})) }))

View File

@ -49,7 +49,8 @@ var isMobile = /Mobile/.test(ua)
var isWebkit = /WebKit/.test(ua) var isWebkit = /WebKit/.test(ua)
// constants // constants
PROGRAM_NAME = 'MusicBox' PROGRAM_NAME = $(document.body).data('program-name')
HOSTNAME = $(document.body).data('hostname')
ARTIST_TABLE = '#artiststable' ARTIST_TABLE = '#artiststable'
ALBUM_TABLE = '#albumstable' ALBUM_TABLE = '#albumstable'
BROWSE_TABLE = '#browsetable' BROWSE_TABLE = '#browsetable'
@ -456,7 +457,7 @@ function showLoading (on) {
if (on) { if (on) {
$('body').css('cursor', 'progress') $('body').css('cursor', 'progress')
$.mobile.loading('show', { $.mobile.loading('show', {
text: 'Loading data from ' + PROGRAM_NAME + '. Please wait...', text: 'Loading data from ' + PROGRAM_NAME + ' on ' + HOSTNAME + '. Please wait...',
textVisible: true, textVisible: true,
theme: 'a' theme: 'a'
}) })
@ -469,7 +470,7 @@ function showLoading (on) {
function showOffline (on) { function showOffline (on) {
if (on) { if (on) {
$.mobile.loading('show', { $.mobile.loading('show', {
text: 'Trying to reach ' + PROGRAM_NAME + '. Please wait...', text: 'Trying to reach ' + PROGRAM_NAME + ' on ' + HOSTNAME + '. Please wait...',
textVisible: true, textVisible: true,
theme: 'a' theme: 'a'
}) })

View File

@ -449,8 +449,6 @@ function locationHashChanged () {
$('#normalFooter').show() $('#normalFooter').show()
$('#nowPlayingFooter').hide() $('#nowPlayingFooter').hide()
} }
// Set the page title based on the hash.
document.title = PROGRAM_NAME
return false return false
} }

View File

@ -1,6 +1,6 @@
CACHE MANIFEST CACHE MANIFEST
# 2016-05-15:v1 # 2016-12-04:v1
NETWORK: NETWORK:
* *

View File

@ -3,7 +3,9 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import json import json
import logging import logging
import socket
import string import string
import urlparse
import tornado.web import tornado.web
@ -33,23 +35,34 @@ class IndexHandler(tornado.web.RequestHandler):
webclient = mmw.Webclient(config) webclient = mmw.Webclient(config)
if webclient.is_music_box():
program_name = 'MusicBox'
else:
program_name = 'Mopidy'
url = urlparse.urlparse('%s://%s' % (self.request.protocol, self.request.host))
port = url.port or 80
self.__dict = { self.__dict = {
'isMusicBox': json.dumps(webclient.is_music_box()), 'isMusicBox': json.dumps(webclient.is_music_box()),
'websocketUrl': webclient.get_websocket_url(self.request), 'websocketUrl': webclient.get_websocket_url(self.request),
'hasAlarmClock': json.dumps(webclient.has_alarm_clock()), 'hasAlarmClock': json.dumps(webclient.has_alarm_clock()),
'onTrackClick': webclient.get_default_click_action() 'onTrackClick': webclient.get_default_click_action(),
'programName': program_name,
'hostname': url.hostname,
'serverIP': socket.gethostbyname(url.hostname),
'serverPort': port
} }
self.__path = path self.__path = path
self.__title = string.Template('MusicBox on $hostname') self.__title = string.Template('{} on $hostname'.format(program_name))
def get(self, path): def get(self, path):
return self.render(path, title=self.get_title(), **self.__dict) return self.render(path, title=self.get_title(), **self.__dict)
def get_title(self): def get_title(self):
hostname, sep, port = self.request.host.rpartition(':') url = urlparse.urlparse('%s://%s' % (self.request.protocol, self.request.host))
if not sep or not port.isdigit(): return self.__title.safe_substitute(hostname=url.hostname)
hostname, port = self.request.host, '80'
return self.__title.safe_substitute(hostname=hostname, port=port)
def get_template_path(self): def get_template_path(self):
return self.__path return self.__path

View File

@ -26,16 +26,16 @@ class Webclient(object):
if host or port: if host or port:
if not host: if not host:
host = request.host.partition(':')[0] host = request.host.partition(':')[0]
logger.warning('Musicbox websocket_host not specified, ' logger.warning('Mopidy websocket_host not specified, '
'using %s', host) 'using %s', host)
elif not port: elif not port:
port = self.config['http']['port'] port = self.config['http']['port']
logger.warning('Musicbox websocket_port not specified, ' logger.warning('Mopidy websocket_port not specified, '
'using %s', port) 'using %s', port)
protocol = 'ws' protocol = 'ws'
if request.protocol == 'https': if request.protocol == 'https':
protocol = 'wss' protocol = 'wss'
ws_url = "%s://%s:%d/mopidy/ws" % (protocol, host, port) ws_url = '%s://%s:%d/mopidy/ws' % (protocol, host, port)
return ws_url return ws_url

View File

@ -46,13 +46,13 @@ class RedirectHandlerTest(BaseTest):
response.headers['Location'].endswith('index.html') response.headers['Location'].endswith('index.html')
class IndexHandlerTest(BaseTest): class IndexHandlerTestMusicBox(BaseTest):
def test_index_handler(self): def test_index_handler(self):
response = self.fetch('/index.html', method='GET') response = self.fetch('/index.html', method='GET')
assert response.code == 200 assert response.code == 200
def test_get_title(self): def test_get_title_musicbox(self):
response = self.fetch('/index.html', method='GET') response = self.fetch('/index.html', method='GET')
body = tornado.escape.to_unicode(response.body) body = tornado.escape.to_unicode(response.body)
@ -65,3 +65,32 @@ class IndexHandlerTest(BaseTest):
assert 'data-is-musicbox="true"' in body assert 'data-is-musicbox="true"' in body
assert 'data-has-alarmclock="false"' in body assert 'data-has-alarmclock="false"' in body
assert 'data-websocket-url=""' in body assert 'data-websocket-url=""' in body
assert 'data-on-track-click="' in body
assert 'data-program-name="' in body
assert 'data-hostname="' in body
class IndexHandlerTestMopidy(BaseTest):
def get_app(self):
extension = Extension()
self.config = config.Proxy({'musicbox_webclient': {
'enabled': True,
'musicbox': False,
'websocket_host': '',
'websocket_port': '',
}
})
return tornado.web.Application(extension.factory(self.config, mock.Mock()))
def test_initialize_sets_dictionary_objects(self):
response = self.fetch('/index.html', method='GET')
body = tornado.escape.to_unicode(response.body)
assert 'data-is-musicbox="false"' in body
def test_get_title_mopidy(self):
response = self.fetch('/index.html', method='GET')
body = tornado.escape.to_unicode(response.body)
assert '<title>Mopidy on localhost</title>' in body