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:
commit
d507f6c681
@ -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)
|
||||||
-------------------
|
-------------------
|
||||||
|
|||||||
@ -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 *
|
||||||
********************/
|
********************/
|
||||||
|
|||||||
@ -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 -->
|
||||||
|
|||||||
@ -652,7 +652,6 @@
|
|||||||
window.history.back()
|
window.history.back()
|
||||||
}, 10000)
|
}, 10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return controls
|
return controls
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -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'
|
||||||
})
|
})
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
CACHE MANIFEST
|
CACHE MANIFEST
|
||||||
|
|
||||||
# 2016-05-15:v1
|
# 2016-12-04:v1
|
||||||
|
|
||||||
NETWORK:
|
NETWORK:
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user