Merge pull request #360 from jodal/feature/mopidy-for-node
Mopidy.js on Node.js
This commit is contained in:
commit
27d424ff5b
@ -15,11 +15,6 @@ module.exports = function (grunt) {
|
||||
minified: "../mopidy/frontends/http/data/mopidy.min.js"
|
||||
}
|
||||
},
|
||||
buster: {
|
||||
test: {
|
||||
config: "buster.js"
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
options: {
|
||||
banner: "<%= meta.banner %>",
|
||||
|
||||
82
js/README.md
Normal file
82
js/README.md
Normal file
@ -0,0 +1,82 @@
|
||||
Mopidy.js
|
||||
=========
|
||||
|
||||
Mopidy.js is a JavaScript library that is installed as a part of Mopidy's HTTP
|
||||
frontend or from npm. The library makes Mopidy's core API available from the
|
||||
browser or a Node.js environment, using JSON-RPC messages over a WebSocket to
|
||||
communicate with Mopidy.
|
||||
|
||||
|
||||
Getting it for browser use
|
||||
--------------------------
|
||||
|
||||
Regular and minified versions of Mopidy.js, ready for use, is installed
|
||||
together with Mopidy. When the HTTP frontend is running, the files are
|
||||
available at:
|
||||
|
||||
- http://localhost:6680/mopidy/mopidy.js
|
||||
- http://localhost:6680/mopidy/mopidy.min.js
|
||||
|
||||
You may need to adjust hostname and port for your local setup.
|
||||
|
||||
In the source repo, you can find the files at:
|
||||
|
||||
- `mopidy/frontends/http/data/mopidy.js`
|
||||
- `mopidy/frontends/http/data/mopidy.min.js`
|
||||
|
||||
|
||||
Getting it for Node.js use
|
||||
--------------------------
|
||||
|
||||
If you want to use Mopidy.js from Node.js instead of a browser, you can install
|
||||
Mopidy.js using npm:
|
||||
|
||||
npm install mopidy
|
||||
|
||||
After npm completes, you can import Mopidy.js using ``require()``:
|
||||
|
||||
var Mopidy = require("mopidy").Mopidy;
|
||||
|
||||
|
||||
Using the library
|
||||
-----------------
|
||||
|
||||
See Mopidy's [HTTP frontend
|
||||
documentation](http://docs.mopidy.com/en/latest/modules/frontends/http/).
|
||||
|
||||
|
||||
Building from source
|
||||
--------------------
|
||||
|
||||
1. Install [Node.js](http://nodejs.org/) and npm. There is a PPA if you're
|
||||
running Ubuntu:
|
||||
|
||||
sudo apt-get install python-software-properties
|
||||
sudo add-apt-repository ppa:chris-lea/node.js
|
||||
sudo apt-get update
|
||||
sudo apt-get install nodejs npm
|
||||
|
||||
2. Enter the `js/` in Mopidy's Git repo dir and install all dependencies:
|
||||
|
||||
cd js/
|
||||
npm install
|
||||
|
||||
That's it.
|
||||
|
||||
You can now run the tests:
|
||||
|
||||
npm test
|
||||
|
||||
To run tests automatically when you save a file:
|
||||
|
||||
npm run-script watch
|
||||
|
||||
To run tests, concatenate, minify the source, and update the JavaScript files
|
||||
in `mopidy/frontends/http/data/`:
|
||||
|
||||
npm run-script build
|
||||
|
||||
To run other [grunt](http://gruntjs.com/) targets which isn't predefined in
|
||||
`package.json` and thus isn't available through `npm run-script`:
|
||||
|
||||
PATH=./node_modules/.bin:$PATH grunt foo
|
||||
@ -1,62 +0,0 @@
|
||||
*********
|
||||
Mopidy.js
|
||||
*********
|
||||
|
||||
This is the source for the JavaScript library that is installed as a part of
|
||||
Mopidy's HTTP frontend. The library makes Mopidy's core API available from the
|
||||
browser, using JSON-RPC messages over a WebSocket to communicate with Mopidy.
|
||||
|
||||
|
||||
Getting it
|
||||
==========
|
||||
|
||||
Regular and minified versions of Mopidy.js, ready for use, is installed
|
||||
together with Mopidy. When the HTTP frontend is running, the files are
|
||||
available at:
|
||||
|
||||
- http://localhost:6680/mopidy/mopidy.js
|
||||
- http://localhost:6680/mopidy/mopidy.min.js
|
||||
|
||||
You may need to adjust hostname and port for your local setup.
|
||||
|
||||
In the source repo, you can find the files at:
|
||||
|
||||
- ``mopidy/frontends/http/data/mopidy.js``
|
||||
- ``mopidy/frontends/http/data/mopidy.min.js``
|
||||
|
||||
|
||||
Building from source
|
||||
====================
|
||||
|
||||
1. Install `Node.js <http://nodejs.org/>`_ and npm. There is a PPA if you're
|
||||
running Ubuntu::
|
||||
|
||||
sudo apt-get install python-software-properties
|
||||
sudo add-apt-repository ppa:chris-lea/node.js
|
||||
sudo apt-get update
|
||||
sudo apt-get install nodejs npm
|
||||
|
||||
2. Enter the ``js/`` dir and install development dependencies::
|
||||
|
||||
cd js/
|
||||
npm install
|
||||
|
||||
That's it.
|
||||
|
||||
You can now run the tests::
|
||||
|
||||
npm test
|
||||
|
||||
To run tests automatically when you save a file::
|
||||
|
||||
npm run-script watch
|
||||
|
||||
To run tests, concatenate, minify the source, and update the JavaScript files
|
||||
in ``mopidy/frontends/http/data/``::
|
||||
|
||||
npm run-script build
|
||||
|
||||
To run other `grunt <http://gruntjs.com/>`_ targets which isn't predefined in
|
||||
``package.json`` and thus isn't available through ``npm run-script``::
|
||||
|
||||
PATH=./node_modules/.bin:$PATH grunt foo
|
||||
10
js/buster.js
10
js/buster.js
@ -1,9 +1,17 @@
|
||||
var config = module.exports;
|
||||
|
||||
config["tests"] = {
|
||||
config.browser_tests = {
|
||||
environment: "browser",
|
||||
libs: ["lib/**/*.js"],
|
||||
sources: ["src/**/*.js"],
|
||||
testHelpers: ["test/**/*-helper.js"],
|
||||
tests: ["test/**/*-test.js"]
|
||||
};
|
||||
|
||||
config.node_tests = {
|
||||
environment: "node",
|
||||
libs: ["lib/**/*.js"],
|
||||
sources: ["src/**/*.js"],
|
||||
testHelpers: ["test/**/*-helper.js"],
|
||||
tests: ["test/**/*-test.js"]
|
||||
};
|
||||
|
||||
@ -1,6 +1,23 @@
|
||||
{
|
||||
"name": "mopidy",
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"description": "Client lib for controlling a Mopidy music server over a WebSocket",
|
||||
"homepage": "http://www.mopidy.com/",
|
||||
"author": {
|
||||
"name": "Stein Magnus Jodal",
|
||||
"email": "stein.magnus@jodal.no",
|
||||
"url": "http://www.jodal.no"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mopidy/mopidy.git"
|
||||
},
|
||||
"main": "src/mopidy.js",
|
||||
"dependencies": {
|
||||
"bane": "~0.4.0",
|
||||
"faye-websocket": "~0.4.4",
|
||||
"when": "~1.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"buster": "~0.6.12",
|
||||
"grunt": "~0.4.0",
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
/*global bane:false, when:false*/
|
||||
/*global exports:false, require:false*/
|
||||
|
||||
if (typeof module === "object" && typeof require === "function") {
|
||||
var bane = require("bane");
|
||||
var websocket = require("faye-websocket");
|
||||
var when = require("when");
|
||||
}
|
||||
|
||||
function Mopidy(settings) {
|
||||
if (!(this instanceof Mopidy)) {
|
||||
@ -20,9 +26,17 @@ function Mopidy(settings) {
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module === "object" && typeof require === "function") {
|
||||
Mopidy.WebSocket = websocket.Client;
|
||||
} else {
|
||||
Mopidy.WebSocket = window.WebSocket;
|
||||
}
|
||||
|
||||
Mopidy.prototype._configure = function (settings) {
|
||||
var currentHost = (typeof document !== "undefined" &&
|
||||
document.location.host) || "localhost";
|
||||
settings.webSocketUrl = settings.webSocketUrl ||
|
||||
"ws://" + document.location.host + "/mopidy/ws/";
|
||||
"ws://" + currentHost + "/mopidy/ws/";
|
||||
|
||||
if (settings.autoConnect !== false) {
|
||||
settings.autoConnect = true;
|
||||
@ -35,7 +49,7 @@ Mopidy.prototype._configure = function (settings) {
|
||||
};
|
||||
|
||||
Mopidy.prototype._getConsole = function () {
|
||||
var console = window.console || {};
|
||||
var console = typeof console !== "undefined" && console || {};
|
||||
|
||||
console.log = console.log || function () {};
|
||||
console.warn = console.warn || function () {};
|
||||
@ -63,7 +77,7 @@ Mopidy.prototype._delegateEvents = function () {
|
||||
|
||||
Mopidy.prototype.connect = function () {
|
||||
if (this._webSocket) {
|
||||
if (this._webSocket.readyState === WebSocket.OPEN) {
|
||||
if (this._webSocket.readyState === Mopidy.WebSocket.OPEN) {
|
||||
return;
|
||||
} else {
|
||||
this._webSocket.close();
|
||||
@ -71,7 +85,7 @@ Mopidy.prototype.connect = function () {
|
||||
}
|
||||
|
||||
this._webSocket = this._settings.webSocket ||
|
||||
new WebSocket(this._settings.webSocketUrl);
|
||||
new Mopidy.WebSocket(this._settings.webSocketUrl);
|
||||
|
||||
this._webSocket.onclose = function (close) {
|
||||
this.emit("websocket:close", close);
|
||||
@ -136,17 +150,17 @@ Mopidy.prototype._send = function (message) {
|
||||
var deferred = when.defer();
|
||||
|
||||
switch (this._webSocket.readyState) {
|
||||
case WebSocket.CONNECTING:
|
||||
case Mopidy.WebSocket.CONNECTING:
|
||||
deferred.resolver.reject({
|
||||
message: "WebSocket is still connecting"
|
||||
});
|
||||
break;
|
||||
case WebSocket.CLOSING:
|
||||
case Mopidy.WebSocket.CLOSING:
|
||||
deferred.resolver.reject({
|
||||
message: "WebSocket is closing"
|
||||
});
|
||||
break;
|
||||
case WebSocket.CLOSED:
|
||||
case Mopidy.WebSocket.CLOSED:
|
||||
deferred.resolver.reject({
|
||||
message: "WebSocket is closed"
|
||||
});
|
||||
@ -280,3 +294,7 @@ Mopidy.prototype._snakeToCamel = function (name) {
|
||||
return match.toUpperCase().replace("_", "");
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof exports === "object") {
|
||||
exports.Mopidy = Mopidy;
|
||||
}
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
/*global buster:false, assert:false, refute:false, when:false, Mopidy:false*/
|
||||
/*global require:false, assert:false, refute:false*/
|
||||
|
||||
if (typeof module === "object" && typeof require === "function") {
|
||||
var buster = require("buster");
|
||||
var Mopidy = require("../src/mopidy").Mopidy;
|
||||
var when = require("when");
|
||||
}
|
||||
|
||||
buster.testCase("Mopidy", {
|
||||
setUp: function () {
|
||||
@ -14,10 +20,11 @@ buster.testCase("Mopidy", {
|
||||
fakeWebSocket.OPEN = 1;
|
||||
fakeWebSocket.CLOSING = 2;
|
||||
fakeWebSocket.CLOSED = 3;
|
||||
this.realWebSocket = WebSocket;
|
||||
window.WebSocket = fakeWebSocket;
|
||||
|
||||
this.webSocketConstructorStub = this.stub(window, "WebSocket");
|
||||
this.realWebSocket = Mopidy.WebSocket;
|
||||
Mopidy.WebSocket = fakeWebSocket;
|
||||
|
||||
this.webSocketConstructorStub = this.stub(Mopidy, "WebSocket");
|
||||
|
||||
this.webSocket = {
|
||||
close: this.stub(),
|
||||
@ -27,15 +34,18 @@ buster.testCase("Mopidy", {
|
||||
},
|
||||
|
||||
tearDown: function () {
|
||||
window.WebSocket = this.realWebSocket;
|
||||
Mopidy.WebSocket = this.realWebSocket;
|
||||
},
|
||||
|
||||
"constructor": {
|
||||
"connects when autoConnect is true": function () {
|
||||
new Mopidy({autoConnect: true});
|
||||
|
||||
var currentHost = typeof document !== "undefined" &&
|
||||
document.location.host || "localhost";
|
||||
|
||||
assert.calledOnceWith(this.webSocketConstructorStub,
|
||||
"ws://" + document.location.host + "/mopidy/ws/");
|
||||
"ws://" + currentHost + "/mopidy/ws/");
|
||||
},
|
||||
|
||||
"does not connect when autoConnect is false": function () {
|
||||
@ -67,12 +77,15 @@ buster.testCase("Mopidy", {
|
||||
|
||||
mopidy.connect();
|
||||
|
||||
var currentHost = typeof document !== "undefined" &&
|
||||
document.location.host || "localhost";
|
||||
|
||||
assert.calledOnceWith(this.webSocketConstructorStub,
|
||||
"ws://" + document.location.host + "/mopidy/ws/");
|
||||
"ws://" + currentHost + "/mopidy/ws/");
|
||||
},
|
||||
|
||||
"does nothing when the WebSocket is open": function () {
|
||||
this.webSocket.readyState = WebSocket.OPEN;
|
||||
this.webSocket.readyState = Mopidy.WebSocket.OPEN;
|
||||
var mopidy = new Mopidy({webSocket: this.webSocket});
|
||||
|
||||
mopidy.connect();
|
||||
@ -367,7 +380,7 @@ buster.testCase("Mopidy", {
|
||||
},
|
||||
|
||||
"immediately rejects request if CONNECTING": function (done) {
|
||||
this.mopidy._webSocket.readyState = WebSocket.CONNECTING;
|
||||
this.mopidy._webSocket.readyState = Mopidy.WebSocket.CONNECTING;
|
||||
|
||||
var promise = this.mopidy._send({method: "foo"});
|
||||
|
||||
@ -381,7 +394,7 @@ buster.testCase("Mopidy", {
|
||||
},
|
||||
|
||||
"immediately rejects request if CLOSING": function (done) {
|
||||
this.mopidy._webSocket.readyState = WebSocket.CLOSING;
|
||||
this.mopidy._webSocket.readyState = Mopidy.WebSocket.CLOSING;
|
||||
|
||||
var promise = this.mopidy._send({method: "foo"});
|
||||
|
||||
@ -395,7 +408,7 @@ buster.testCase("Mopidy", {
|
||||
},
|
||||
|
||||
"immediately rejects request if CLOSED": function (done) {
|
||||
this.mopidy._webSocket.readyState = WebSocket.CLOSED;
|
||||
this.mopidy._webSocket.readyState = Mopidy.WebSocket.CLOSED;
|
||||
|
||||
var promise = this.mopidy._send({method: "foo"});
|
||||
|
||||
|
||||
@ -128,8 +128,8 @@ you quickly started with working on your client instead of figuring out how to
|
||||
communicate with Mopidy.
|
||||
|
||||
|
||||
Getting the library
|
||||
-------------------
|
||||
Getting the library for browser use
|
||||
-----------------------------------
|
||||
|
||||
Regular and minified versions of Mopidy.js, ready for use, is installed
|
||||
together with Mopidy. When the HTTP frontend is running, the files are
|
||||
@ -154,6 +154,25 @@ the Git repo at:
|
||||
- ``mopidy/frontends/http/data/mopidy.js``
|
||||
- ``mopidy/frontends/http/data/mopidy.min.js``
|
||||
|
||||
|
||||
Getting the library for Node.js use
|
||||
-----------------------------------
|
||||
|
||||
If you want to use Mopidy.js from Node.js instead of a browser, you can install
|
||||
Mopidy.js using npm::
|
||||
|
||||
npm install mopidy
|
||||
|
||||
After npm completes, you can import Mopidy.js using ``require()``:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
var Mopidy = require("mopidy").Mopidy;
|
||||
|
||||
|
||||
Getting the library for development on the library
|
||||
--------------------------------------------------
|
||||
|
||||
If you want to work on the Mopidy.js library itself, you'll find a complete
|
||||
development setup in the ``js/`` dir in our repo. The instructions in
|
||||
``js/README.rst`` will guide you on your way.
|
||||
@ -170,8 +189,8 @@ Once you got Mopidy.js loaded, you need to create an instance of the wrapper:
|
||||
|
||||
When you instantiate ``Mopidy()`` without arguments, it will connect to
|
||||
the WebSocket at ``/mopidy/ws/`` on the current host. Thus, if you don't host
|
||||
your web client using Mopidy's web server, you'll need to pass the URL to the
|
||||
WebSocket end point:
|
||||
your web client using Mopidy's web server, or if you use Mopidy.js from a
|
||||
Node.js environment, you'll need to pass the URL to the WebSocket end point:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user