Merge pull request #180 from jcass77/enhance/tox_build
Add tox environments for running linters
This commit is contained in:
commit
85f5fe006b
1
.csslintrc
Normal file
1
.csslintrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
--format=compact
|
||||||
11
.eslintrc
Normal file
11
.eslintrc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": "standard",
|
||||||
|
"env": {
|
||||||
|
"jquery": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": [2, 4, {"SwitchCase": 1}],
|
||||||
|
"no-undef": 0, // TODO: Set this to '2' once Javascript has been modularised.
|
||||||
|
"no-unused-vars": 0, // TODO: Set this to '2' once Javascript has been modularised.
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ docs/_build/
|
|||||||
mopidy.log*
|
mopidy.log*
|
||||||
node_modules/
|
node_modules/
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
|
npm-debug.log
|
||||||
.project
|
.project
|
||||||
*.pbxproj
|
*.pbxproj
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
|||||||
@ -8,6 +8,9 @@ python:
|
|||||||
env:
|
env:
|
||||||
- TOX_ENV=py27
|
- TOX_ENV=py27
|
||||||
- TOX_ENV=flake8
|
- TOX_ENV=flake8
|
||||||
|
- TOX_ENV=eslint
|
||||||
|
- TOX_ENV=csslint
|
||||||
|
- TOX_ENV=tidy
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- "pip install tox"
|
- "pip install tox"
|
||||||
|
|||||||
29
README.rst
29
README.rst
@ -10,14 +10,26 @@ Mopidy-MusicBox-Webclient
|
|||||||
:target: https://pypi.python.org/pypi/Mopidy-MusicBox-Webclient/
|
:target: https://pypi.python.org/pypi/Mopidy-MusicBox-Webclient/
|
||||||
:alt: Number of PyPI downloads
|
:alt: Number of PyPI downloads
|
||||||
|
|
||||||
With Mopidy MusicBox Webclient, you can play your music on your computer (`Rapsberry Pi <http://www.raspberrypi.org/>`_)
|
.. image:: https://img.shields.io/travis/pimusicbox/mopidy-musicbox-webclient/develop.svg?style=flat
|
||||||
|
:target: https://travis-ci.org/rectalogic/mopidy-pandora
|
||||||
|
:alt: Travis CI build status
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/coveralls/pimusicbox/mopidy-musicbox-webclient/develop.svg?style=flat
|
||||||
|
:target: https://coveralls.io/r/rectalogic/mopidy-pandora?branch=develop
|
||||||
|
:alt: Test coverage
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat
|
||||||
|
:target: http://standardjs.com/
|
||||||
|
:alt: JavaScript Standard Style
|
||||||
|
|
||||||
|
With Mopidy MusicBox Webclient (MMW), you can play your music on your computer (`Rapsberry Pi <http://www.raspberrypi.org/>`_)
|
||||||
and remotely control it using your computer, tablet or phone.
|
and remotely control it using your computer, tablet or phone.
|
||||||
|
|
||||||
This is a responsive webclient especially written for Mopidy, a music server. Responsive, so it works on desktop and
|
This is a responsive webclient especially written for `Mopidy <http://www.mopidy.com/>`_: a music server that can play
|
||||||
mobile browsers. You can browse, search and play albums, artists, playlists, and it has cover art from Last.fm.
|
music from many different sources including Spotify, Google Music, SoundCloud, etc. or from your hard drive. The
|
||||||
|
webclient is responsive, so it works on desktop and mobile browsers. You can browse, search and play albums, artists,
|
||||||
|
playlists, and it has cover art from Last.fm.
|
||||||
|
|
||||||
`Mopidy <http://www.mopidy.com/>`_ is a music server which can play music from Spotify, Google Music, SoundCloud, etc.
|
|
||||||
or from your hard drive.
|
|
||||||
|
|
||||||
If you want to run Mopidy with this webclient on a Raspberry Pi, do yourself a favor and use my custom built SD-image:
|
If you want to run Mopidy with this webclient on a Raspberry Pi, do yourself a favor and use my custom built SD-image:
|
||||||
`Pi MusicBox <http://www.pimusicbox.com/>`_.
|
`Pi MusicBox <http://www.pimusicbox.com/>`_.
|
||||||
@ -30,7 +42,7 @@ Installation
|
|||||||
|
|
||||||
Install by running::
|
Install by running::
|
||||||
|
|
||||||
pip install Mopidy-MusicBox-Webclient
|
pip install mopidy-musicbox-webclient
|
||||||
|
|
||||||
|
|
||||||
Alternatively, clone the repository and run ``sudo python setup.py install`` from within the project directory. e.g. ::
|
Alternatively, clone the repository and run ``sudo python setup.py install`` from within the project directory. e.g. ::
|
||||||
@ -58,6 +70,11 @@ Project resources
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v2.3.0 (UNRELEASED)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Enhance build workflow to include style checks and syntax validation for HTML, CSS, and Javascript.
|
||||||
|
|
||||||
v2.2.0 (2016-03-01)
|
v2.2.0 (2016-03-01)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|||||||
16
mopidy_musicbox_webclient/static/js/controls.js
vendored
16
mopidy_musicbox_webclient/static/js/controls.js
vendored
@ -35,7 +35,7 @@ function playBrowsedTracks(action, trackIndex) {
|
|||||||
mopidy.playback.play({'tl_track': tlTracks[playIndex]});
|
mopidy.playback.play({'tl_track': tlTracks[playIndex]});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case PLAY_NOW:
|
case PLAY_NOW:
|
||||||
case PLAY_NEXT:
|
case PLAY_NEXT:
|
||||||
@ -65,7 +65,7 @@ function playTrack(action) {
|
|||||||
if (action == PLAY_NOW && divid == 'search') {
|
if (action == PLAY_NOW && divid == 'search') {
|
||||||
action = PLAY_NOW_SEARCH;
|
action = PLAY_NOW_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#popupTracks').popup('close');
|
$('#popupTracks').popup('close');
|
||||||
$('#controlspopup').popup('close');
|
$('#controlspopup').popup('close');
|
||||||
toast('Loading...');
|
toast('Loading...');
|
||||||
@ -142,7 +142,7 @@ function playTrackByUri(track_uri, playlist_uri) {
|
|||||||
toast('Loading...');
|
toast('Loading...');
|
||||||
|
|
||||||
mopidy.tracklist.add({'uris': [playlist_uri]}).then(function(tlTracks) {
|
mopidy.tracklist.add({'uris': [playlist_uri]}).then(function(tlTracks) {
|
||||||
// Can fail for all sorts of reasons. If so, just add individually.
|
// Can fail for all sorts of reasons. If so, just add individually.
|
||||||
if (tlTracks.length === 0) {
|
if (tlTracks.length === 0) {
|
||||||
var trackUris = getTracksFromUri(playlist_uri, false);
|
var trackUris = getTracksFromUri(playlist_uri, false);
|
||||||
mopidy.tracklist.add({'uris': trackUris}).then(findAndPlayTrack);
|
mopidy.tracklist.add({'uris': trackUris}).then(findAndPlayTrack);
|
||||||
@ -474,7 +474,7 @@ function playStreamUri(uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentlyPlaying() {
|
function getCurrentlyPlaying() {
|
||||||
$('#streamuriinput').val(songdata.track.uri);
|
$('#streamuriinput').val(songdata.track.uri);
|
||||||
var name = songdata.track.name;
|
var name = songdata.track.name;
|
||||||
if (songdata.track.artists) {
|
if (songdata.track.artists) {
|
||||||
var artistStr = artistsToString(songdata.track.artists);
|
var artistStr = artistsToString(songdata.track.artists);
|
||||||
@ -482,7 +482,7 @@ function getCurrentlyPlaying() {
|
|||||||
name = artistStr + ' - ' + name;
|
name = artistStr + ' - ' + name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('#streamnameinput').val(name);
|
$('#streamnameinput').val(name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ function getPlaylistFull(uri) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFavourites() {
|
function getFavourites() {
|
||||||
return getPlaylistByName(STREAMS_PLAYLIST_NAME,
|
return getPlaylistByName(STREAMS_PLAYLIST_NAME,
|
||||||
STREAMS_PLAYLIST_SCHEME,
|
STREAMS_PLAYLIST_SCHEME,
|
||||||
true).then(function(playlist) {
|
true).then(function(playlist) {
|
||||||
if (playlist) {
|
if (playlist) {
|
||||||
@ -593,7 +593,7 @@ function showFavourites() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var tmp = '';
|
var tmp = '';
|
||||||
|
|
||||||
$.cookie.json = true;
|
$.cookie.json = true;
|
||||||
if ($.cookie('streamUris')) {
|
if ($.cookie('streamUris')) {
|
||||||
tmp = '<button class="btn" style="padding: 5px; width: 100%" type="button" onclick="return upgradeStreamUrisToFavourites();">Convert StreamUris</button>';
|
tmp = '<button class="btn" style="padding: 5px; width: 100%" type="button" onclick="return upgradeStreamUrisToFavourites();">Convert StreamUris</button>';
|
||||||
@ -609,7 +609,7 @@ function showFavourites() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('#streamuristable').html(tmp);
|
$('#streamuristable').html(tmp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this upgrade path in next major release.
|
// TODO: Remove this upgrade path in next major release.
|
||||||
|
|||||||
@ -235,7 +235,7 @@ function initSocketevents() {
|
|||||||
getPlaylists();
|
getPlaylists();
|
||||||
getUriSchemes().then(function() {
|
getUriSchemes().then(function() {
|
||||||
showFavourites();
|
showFavourites();
|
||||||
});
|
});
|
||||||
getBrowseDir();
|
getBrowseDir();
|
||||||
getSearchSchemes();
|
getSearchSchemes();
|
||||||
showLoading(false);
|
showLoading(false);
|
||||||
@ -580,7 +580,7 @@ $(document).ready(function(event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if ($(window).width() < 980) {
|
if ($(window).width() < 980) {
|
||||||
$("#panel").panel("close");
|
$("#panel").panel("close");
|
||||||
|
|||||||
@ -240,7 +240,7 @@ function processAlbumResults(resultArr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
customTracklists[resultArr.uri] = resultArr;
|
customTracklists[resultArr.uri] = resultArr;
|
||||||
|
|
||||||
albumTracksToTable(resultArr, ALBUM_TABLE, resultArr.uri);
|
albumTracksToTable(resultArr, ALBUM_TABLE, resultArr.uri);
|
||||||
var albumname = getAlbum(resultArr);
|
var albumname = getAlbum(resultArr);
|
||||||
var artistname = getArtist(resultArr);
|
var artistname = getArtist(resultArr);
|
||||||
|
|||||||
33
package.json
Normal file
33
package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "Mopidy-MusicBox-Webclient",
|
||||||
|
"version": "2.1.1",
|
||||||
|
"description": "Mopidy MusicBox web extension",
|
||||||
|
"main": "gui.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "tests"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"eslint": "eslint mopidy_musicbox_webclient/static/js/**.js",
|
||||||
|
"csslint": "csslint mopidy_musicbox_webclient/static/css/**.css",
|
||||||
|
"tidy": "node tidy.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/pimusicbox/mopidy-musicbox-webclient.git"
|
||||||
|
},
|
||||||
|
"author": "Wouter van Wijk",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/pimusicbox/mopidy-musicbox-webclient/issues"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "latest",
|
||||||
|
"eslint-config-standard": "latest",
|
||||||
|
"eslint-plugin-standard": "latest",
|
||||||
|
"eslint-plugin-promise": "latest",
|
||||||
|
"csslint": "latest",
|
||||||
|
"tidy-html5": "latest"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/pimusicbox/mopidy-musicbox-webclient#readme"
|
||||||
|
}
|
||||||
88
tidy.js
Normal file
88
tidy.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
var tidy = require('tidy-html5').tidy_html5
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
|
||||||
|
// Traverse directory structure looking for 'html' or 'htm' files.
|
||||||
|
var getAllHtmlFilesFromFolder = function (dir) {
|
||||||
|
var filesystem = require('fs')
|
||||||
|
var results = []
|
||||||
|
filesystem.readdirSync(dir).forEach(function (file) {
|
||||||
|
file = dir + '/' + file
|
||||||
|
var stat = filesystem.statSync(file)
|
||||||
|
|
||||||
|
if (stat && stat.isDirectory()) {
|
||||||
|
results = results.concat(getAllHtmlFilesFromFolder(file))
|
||||||
|
} else {
|
||||||
|
var extension = file.substr(file.lastIndexOf('.') + 1).toUpperCase()
|
||||||
|
if (extension === 'HTM' || extension === 'HTML') {
|
||||||
|
results.push(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file contents.
|
||||||
|
function readFiles (dirname, onFileContent) {
|
||||||
|
var filenames = getAllHtmlFilesFromFolder(dirname)
|
||||||
|
filenames.forEach(function (filename) {
|
||||||
|
fs.readFile(filename, 'utf-8', function (err, content) {
|
||||||
|
if (err) {
|
||||||
|
throw (err)
|
||||||
|
}
|
||||||
|
onFileContent(filename, content)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var util = require('util')
|
||||||
|
|
||||||
|
// Trap stderr output so that we can detect parsing errors.
|
||||||
|
function hook_stderr (callback) {
|
||||||
|
var old_write = process.stderr.write
|
||||||
|
|
||||||
|
process.stderr.write = (function (write) {
|
||||||
|
return function (string, encoding, fd) {
|
||||||
|
write.apply(process.stdout, arguments)
|
||||||
|
callback(string, encoding, fd)
|
||||||
|
}
|
||||||
|
})(process.stderr.write)
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
process.stderr.write = old_write
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var unhook = hook_stderr(function (string, encoding, fd) {
|
||||||
|
if (string.indexOf('Error:') > 0) {
|
||||||
|
errors.push(string)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var errorsOccurred = false
|
||||||
|
var errors = []
|
||||||
|
|
||||||
|
// Exit with status 1 so that tox can detect errors.
|
||||||
|
process.on('exit', function () {
|
||||||
|
if (errorsOccurred === true) {
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Start linter
|
||||||
|
function processFiles (callback) {
|
||||||
|
console.log('Starting HTML linter...')
|
||||||
|
readFiles('mopidy_musicbox_webclient/static', function (filename, content) {
|
||||||
|
console.log('\n' + filename)
|
||||||
|
var result = tidy(content, {'quiet': true})
|
||||||
|
if (errors.length > 0) {
|
||||||
|
console.error('\nHTML errors detected:\n' + errors.join(''))
|
||||||
|
errors = []
|
||||||
|
errorsOccurred = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
processFiles(function () {
|
||||||
|
unhook()
|
||||||
|
})
|
||||||
36
tox.ini
36
tox.ini
@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27, flake8
|
envlist = py27, flake8, eslint, csslint, tidy
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
@ -13,11 +13,41 @@ commands =
|
|||||||
--basetemp={envtmpdir} \
|
--basetemp={envtmpdir} \
|
||||||
--junit-xml=xunit-{envname}.xml \
|
--junit-xml=xunit-{envname}.xml \
|
||||||
--cov=mopidy_musicbox_webclient --cov-report=term-missing \
|
--cov=mopidy_musicbox_webclient --cov-report=term-missing \
|
||||||
{posargs}
|
{posargs:tests/}
|
||||||
|
|
||||||
[testenv:flake8]
|
[testenv:flake8]
|
||||||
deps =
|
deps =
|
||||||
flake8
|
flake8
|
||||||
flake8-import-order
|
flake8-import-order
|
||||||
skip_install = true
|
skip_install = true
|
||||||
commands = flake8
|
commands = flake8 {posargs:mopidy_musicbox_webclient}
|
||||||
|
|
||||||
|
[testenv:eslint]
|
||||||
|
whitelist_externals =
|
||||||
|
/bin/bash
|
||||||
|
deps =
|
||||||
|
nodeenv
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
- nodeenv --prebuilt {toxworkdir}/node_env
|
||||||
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run eslint'
|
||||||
|
|
||||||
|
[testenv:csslint]
|
||||||
|
whitelist_externals =
|
||||||
|
/bin/bash
|
||||||
|
deps =
|
||||||
|
nodeenv
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
- nodeenv --prebuilt {toxworkdir}/node_env
|
||||||
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run csslint'
|
||||||
|
|
||||||
|
[testenv:tidy]
|
||||||
|
whitelist_externals =
|
||||||
|
/bin/bash
|
||||||
|
deps =
|
||||||
|
nodeenv
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
- nodeenv --prebuilt {toxworkdir}/node_env
|
||||||
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run tidy'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user