1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
9.4 KiB

/*jslint laxbreak:true */
/*jslint laxcomma:true */
/*jslint loopfunc:true */
/*jslint strict:true */
/*jslint browser:true */
/*jslint devel:true */
/**
* TODO: If the user agrees, set the username/passs in a cookie
**/
define([
"underscore"
, "backbone"
, "toolbox"
, "models/dmap-type"
, "models/dmap"
], function (_, Backbone, Toolbox, DMAPType, DMAPModel) {
"use strict";
var that
// TODO: Could be interesting to set a userage, could possibly affect transcoding on the server side
, xhr = function (url, responseType, callback) {
var xhr = new XMLHttpRequest();
var contentType = "text/plain; charset=utf-8";
if (typeof responseType === "function") {
callback = responseType;
responseType = "arraybuffer";
}
xhr.open("GET", url, true);
xhr.responseType = responseType;
xhr.timeout = 2000;
xhr.setRequestHeader("Content-type", contentType);
xhr.overrideMimeType("text/plain; charset=x-user-defined"); // Technically not need with v2 and responseType but for good measures
if (!_.isEmpty(that.attributes.basicauth)) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + that.attributes.basicauth);
}
try {
xhr.onerror = function () {console.log("Error", arguments, this);};
xhr.onabort = function () {console.log("Abort", arguments, this);};
xhr.ontimeout = function () {console.log("Timeout", arguments, this);};
xhr.onload = function (e) {
if (this.status === 200) {
callback(null, this.response);
} else if (this.status === 401) {
that.trigger("unauthorized", [this, e]);
} else {
callback(e.status);
}
};
xhr.send();
} catch (e) {
console.error(e);
callback(e, null);
}
}
, fetchXHR = function (path, success, error) {
xhr(that.url(path), function __fetchXHRCallback(err, content) {
if (err) {
if (!_.isFunction(error)) {
error = function (err, cont) {
throw [err, cont];
};
}
error(err, content);
} else {
success(content);
}
});
}
, fetchContentTypes = function (success, error) {
fetchXHR("/content-codes", function __fetchContentTypesCallback(content) {
that.collections.contentCodes = new DMAPModel(content);
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchServerInfo = function (success, error) {
fetchXHR("/server-info", function __fetchServerInfoCallback(content) {
that.collections.serverInfo = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchLogin = function (success, error) {
fetchXHR("/login", success, error);
}
, fetchDatabases = function (success, error) {
fetchXHR("/databases", function __fetchDatabasesCallback(content) {
that.collections.databasesInfo = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchDatabase = function (success, error, dbId) {
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
fetchXHR("/databases/" + dbId + "/items", function __fetchDatabaseCallback(content) {
that.collections.databases[dbId] = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchPlaylists = function (success, error, dbId) {
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
fetchXHR("/databases/" + dbId + "/containers", function __fetchPlaylistsCallback(content) {
that.collections.playlistsInfo = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchPlaylist = function (success, error, playlistId, dbId) {
if (_.isUndefined(playlistId) || !_.isNumeric(playlistId)) {
playlistId = 1;
}
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
var requestUri = "/databases/"
;
requestUri += dbId;
requestUri += "/containers/";
requestUri += playlistId;
requestUri += "/items";
requestUri += "?meta=dmap.itemid,dmap.persistentid,dmap.containeritemid";
fetchXHR(requestUri, function __fetchPlaylistCallback(content) {
if (!_.isArray(that.collections.playlists[dbId])) {
that.collections.playlists[dbId] = [];
}
that.collections.playlists[dbId][playlistId] = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchBrowse = function (success, error, dbId, type) {
// TODO: We need to detect if the server supports browsing or not an implement our own otherwise.
if (_.isEmpty(type) || !_.isString(type) || !_.isArray(that.collections.browser[type])) {
throw new Error("INVALID_BROWSE_TYPE");
}
var requestUri = "/databases/"
;
requestUri += dbId;
requestUri += "/browse/";
requestUri += type;
requestUri += "?meta=dmap.itemid,dmap.persistentid,dmap.containeritemid";
fetchXHR(requestUri, function __fetchBrowseCallback(content) {
that.collections.browser[type][dbId] = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
if (_.isFunction(success)) {
success(content);
}
}, error);
}
, fetchGenres = function (success, error, dbId) {
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
return fetchBrowse(success, error, dbId, "genres");
}
, fetchArtists = function (success, error, dbId) {
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
return fetchBrowse(success, error, dbId, "artists");
}
, fetchAlbums = function (success, error, dbId) {
if (_.isUndefined(dbId) || !_.isNumeric(dbId)) {
dbId = 1;
}
return fetchBrowse(success, error, dbId, "albums");
}
, Client = Toolbox.Base.extend({
constructor: function(attributes, options) {
that = this;
_.extend(that, Client.defaults);
_.extend(that.attributes, attributes);
that.setAuth();
return this;
}
, setAuth: function(username, password) {
if (!_.isUndefined(username)) {
that.attributes.username = username;
}
if (!_.isUndefined(password)) {
that.attributes.password = password;
}
if (!_.isEmpty(that.attributes.password) || !_.isEmpty(that.attributes.username)) {
that.attributes.basicauth = window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || ""));
}
}
, init: function () {
var that = this
;
that.console.debug("Fetching content types");
fetchContentTypes(function () {
that.console.debug("Fetching server info");
fetchServerInfo(function () {
that.console.debug("Fetching login");
fetchLogin(function () {
// TODO: Here we need to request /update for the database version
that.console.debug("Fetching databases info");
fetchDatabases(function () {
//that.console.debug("Fetching database 1");
//fetchDatabase(function () {
that.console.debug("Fetching playlists info");
fetchPlaylists(function () {
//that.console.debug("Fetching playlist 1 of db 1");
//fetchPlaylist(function () {
//that.console.debug("Fetching genres of db 1");
//fetchGenres(function () {
//that.console.debug("Fetching artists of db 1");
//fetchArtists(function () {
//that.console.debug("Fetching albums of db 1");
//fetchAlbums(function () {
that.trigger("inited", that.collections);
//});
//});
//});
//});
});
//});
});
});
});
});
return this;
}
,logout: function () {
}
, buildRequestUid: function(path, fields, query) {
if (_.isEmpty(path) || !_.isString(path)) {
throw new Error("INVALID_TYPE_ERROR");
}
if (!_.isArray(fields)) {
fields = [];
}
if (!_.isArray(query)) {
query = [];
}
}
,url: function (request) {
var uri = ""
;
if (typeof request === "string") {
uri = request; // Add leading slash here!
}
if (_.isNumber(this.collections.session.id)) {
var prefix = "?";
if (uri.indexOf("?") >= 0) {
prefix = "&";
}
uri += prefix + "session-id=" + this.collections.session.id;
}
return this.attributes.protocol + "://" + this.attributes.hostname + ":" + this.attributes.port + uri;
}
, console: {
log: function() {
var args = arguments;
if (_.isString(args[0])) {
args[0] = that.url() + " " + args[0];
}
console.log(args);
}
, debug: function() {
var args = arguments;
if (_.isString(args[0])) {
args[0] = that.url() + " " + args[0];
}
console.debug(args);
}
}
}, {
defaults: {
attributes: {
protocol: window.location.protocol.replace(":", "")
, hostname: window.location.hostname
, port: 3689
, path: ""
, username: ""
, password: ""
}
, status: 0
, statusCodes: {
disconnected: 0
, connecting: 1
, timedout: 2
, unauthorized: 3
, connected: 4
}
, collections: {
contentCodes: null
, serverInfo: null
, session: {
id: null
}
, databasesInfo:null
, databases: []
, playlistsInfo:null
, playlists: []
, browser: {
genres: []
, artists: []
, albums: []
}
}
}
});
_.extend(Client.prototype, Backbone.Events, {});
return Client;
});