Jamstash/js/services/subsonic-service.js
Hyzual b190d2f99f Moves the subsonic controller into its own module.
Removes many injected params that weren't used at all in it.
Removes the old commented getStarred function from the subsonic service.
2014-11-09 16:05:12 +01:00

798 lines
No EOL
38 KiB
JavaScript

/**
* jamstash.subsonicService Module
*
* Provides access through $http to the Subsonic server's API.
* Also offers more fine-grained functionality that is not part of Subsonic's API.
*/
angular.module('jamstash.subsonic.service', ['jamstash.globals', 'jamstash.utils', 'jamstash.model',
'jamstash.notifications', 'angular-underscore/utils'])
.factory('subsonic', function ($rootScope, $http, $q, globals, utils, map, notifications) {
'use strict';
var index = { shortcuts: [], artists: [] };
var content = {
album: [],
song: [],
playlists: [],
breadcrumb: [],
playlistsPublic: [],
playlistsGenre: globals.SavedGenres,
selectedAutoAlbum: null,
selectedArtist: null,
selectedAlbum: null,
selectedPlaylist: null,
selectedAutoPlaylist: null,
selectedGenre: null,
selectedPodcast: null
};
var genres = [];
var podcasts = [];
var offset = 0;
var showIndex = false;
var showPlaylist = false;
var showPodcast = false;
var sortSubsonicAlbums = function (newValue) {
if (typeof newValue != 'undefined') {
//alert(newValue);
switch (newValue) {
case 'createdate desc':
content.album.sort(utils.sortDateFunction);
break;
case 'artist':
content.album.sort(utils.sortArtistFunction);
break;
case 'album':
content.album.sort(utils.sortAlbumFunction);
break;
}
}
};
var sortSubsonicSongs = function (newValue) {
if (typeof newValue != 'undefined') {
//alert(newValue);
switch (newValue) {
case 'createdate desc':
content.song.sort(utils.sortDateFunction);
break;
case 'artist':
content.song.sort(utils.sortArtistFunction);
break;
case 'album':
content.song.sort(utils.sortAlbumFunction);
break;
case 'track':
content.song.sort(utils.sortTrackFunction);
break;
}
}
};
return {
showIndex: showIndex,
showPlaylist: showPlaylist,
getSongTemplate: function (callback) {
var id = '16608';
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
/*
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
}
});
*/
$http.get(url).success(function (data) {
var items = [];
var song = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
items = data["subsonic-response"].directory.child;
} else {
items[0] = data["subsonic-response"].directory.child;
}
angular.forEach(items, function (item, key) {
if (!item.isDir) {
song.push(map.mapSong(item));
}
});
callback(song);
}
});
},
getArtists: function (id, refresh) {
var deferred = $q.defer();
if (refresh || index.artists.length == 0) {
var url;
if (utils.getValue('MusicFolders')) {
var folder = angular.fromJson(utils.getValue('MusicFolders'));
id = folder.id;
}
if (id) {
url = globals.BaseURL() + '/getIndexes.view?' + globals.BaseParams() + '&musicFolderId=' + id;
} else {
url = globals.BaseURL() + '/getIndexes.view?' + globals.BaseParams();
}
/*
$http.get(url).success(function (data) {
});
*/
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
var indexes = [];
if (typeof data["subsonic-response"].indexes.index != 'undefined') {
if (data["subsonic-response"].indexes.index.length > 0) {
indexes = data["subsonic-response"].indexes.index;
} else {
indexes[0] = data["subsonic-response"].indexes.index;
}
}
index.artists = [];
index.shortcuts = [];
var items = [];
if (typeof data["subsonic-response"].indexes.shortcut != 'undefined') {
if (data["subsonic-response"].indexes.shortcut.length > 0) {
items = data["subsonic-response"].indexes.shortcut;
} else {
items[0] = data["subsonic-response"].indexes.shortcut;
}
angular.forEach(items, function (item, key) {
index.shortcuts.push(map.mapIndex(item));
});
}
angular.forEach(indexes, function (item, key) {
index.artists.push(map.mapArtist(item));
});
deferred.resolve(index);
}
});
} else {
deferred.resolve(index);
}
return deferred.promise;
},
getAlbums: function (id, name) {
var deferred = $q.defer();
if (id) {
content.selectedAutoAlbum = null;
content.selectedPlaylist = null;
content.selectedArtist = id;
content.breadcrumb = [];
content.breadcrumb.push({ 'type': 'artist', 'id': id, 'name': name });
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
/*
$http.get(url).success(function (data) {
});
*/
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
var items = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
items = data["subsonic-response"].directory.child;
} else {
items[0] = data["subsonic-response"].directory.child;
}
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
if (item.isDir) {
content.album.push(map.mapAlbum(item));
} else {
content.song.push(map.mapSong(item));
}
});
if (SelectedAlbumSort.id != "default") {
sortSubsonicAlbums(SelectedAlbumSort.id);
}
} else {
notifications.updateMessage('No Albums Returned :(', true);
}
deferred.resolve(content);
}
});
} else {
deferred.resolve(content);
}
return deferred.promise;
},
getAlbumListBy: function (id, off) {
var deferred = $q.defer();
var size, url;
content.selectedArtist = null;
content.selectedPlaylist = null;
content.selectedAutoAlbum = id;
content.breadcrumb = [];
if (off == 'next') {
offset = offset + globals.settings.AutoAlbumSize;
} else if (offset == 'prev') {
offset = offset - globals.settings.AutoAlbumSize;
} else {
offset = 0;
}
if (offset > 0) {
url = globals.BaseURL() + '/getAlbumList.view?' + globals.BaseParams() + '&size=' + globals.settings.AutoAlbumSize.toString() + '&type=' + id + '&offset=' + offset;
} else {
url = globals.BaseURL() + '/getAlbumList.view?' + globals.BaseParams() + '&size=' + globals.settings.AutoAlbumSize.toString() + '&type=' + id;
}
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
var items = [];
if (typeof data["subsonic-response"].albumList.album != 'undefined') {
if (data["subsonic-response"].albumList.album.length > 0) {
items = data["subsonic-response"].albumList.album;
} else {
items[0] = data["subsonic-response"].albumList.album;
}
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
if (item.isDir) {
content.album.push(map.mapAlbum(item));
} else {
content.song.push(map.mapSong(item));
}
});
if (SelectedAlbumSort.id != "default") {
sortSubsonicAlbums(SelectedAlbumSort.id);
}
} else {
notifications.updateMessage('No Albums Returned :(', true);
}
deferred.resolve(content);
}
});
return deferred.promise;
},
getAlbumByTag: function (id) { // Gets Album by ID3 tag
var deferred = $q.defer();
$.ajax({
url: globals.BaseURL() + '/getAlbum.view?' + globals.BaseParams() + '&id=' + id,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (typeof data["subsonic-response"].album != 'undefined') {
content.album = [];
content.song = [];
var items = [];
if (data["subsonic-response"].album.song.length > 0) {
items = data["subsonic-response"].album.song;
} else {
items[0] = data["subsonic-response"].album.song;
}
angular.forEach(items, function (item, key) {
content.song.push(map.mapSong(item));
});
}
deferred.resolve(content);
}
});
return deferred.promise;
},
getSongs: function (id, action) {
var deferred = $q.defer();
if (id) {
content.selectedAlbum = id;
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
var items = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
items = data["subsonic-response"].directory.child;
} else {
items[0] = data["subsonic-response"].directory.child;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
var next = $rootScope.queue[0];
$rootScope.playSong(false, next);
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
if (typeof data["subsonic-response"].directory.id != 'undefined') {
var albumId = data["subsonic-response"].directory.id;
var albumName = data["subsonic-response"].directory.name;
if (content.breadcrumb.length > 0) { content.breadcrumb.splice(1, (content.breadcrumb.length - 1)); }
content.breadcrumb.push({ 'type': 'album', 'id': albumId, 'name': albumName });
}
content.song = [];
content.album = [];
var albums = [];
angular.forEach(items, function (item, key) {
if (item.isDir) {
albums.push(map.mapAlbum(item));
} else {
content.song.push(map.mapSong(item));
}
});
if (albums.length > 0) {
content.album = albums;
if ($scope.SelectedAlbumSort.id != "default") {
sortSubsonicAlbums(SelectedAlbumSort.id);
}
}
}
deferred.resolve(content);
} else {
notifications.updateMessage('No Songs Returned :(', true);
}
}
});
} else {
deferred.resolve(content);
}
return deferred.promise;
},
search: function (query, type) {
var deferred = $q.defer();
if (query !== '') {
$.ajax({
url: globals.BaseURL() + '/search2.view?' + globals.BaseParams() + '&query=' + query,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].searchResult2 !== "") {
var items = [];
if (type === '0') {
if (data["subsonic-response"].searchResult2.song !== undefined) {
if (data["subsonic-response"].searchResult2.song.length > 0) {
items = data["subsonic-response"].searchResult2.song;
} else {
items[0] = data["subsonic-response"].searchResult2.song;
}
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
content.song.push(map.mapSong(item));
});
}
}
if (type === '1') {
if (data["subsonic-response"].searchResult2.album !== undefined) {
if (data["subsonic-response"].searchResult2.album.length > 0) {
items = data["subsonic-response"].searchResult2.album;
} else {
items[0] = data["subsonic-response"].searchResult2.album;
}
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
if (item.isDir) {
content.album.push(map.mapAlbum(item));
} else {
content.song.push(map.mapAlbum(item));
}
});
}
}
if (type === '2') {
if (data["subsonic-response"].searchResult2.artist !== undefined) {
if (data["subsonic-response"].searchResult2.artist.length > 0) {
items = data["subsonic-response"].searchResult2.artist;
} else {
items[0] = data["subsonic-response"].searchResult2.artist;
}
angular.forEach(items, function (item, key) {
index.shortcuts.push(item);
});
}
}
deferred.resolve(content);
}
}
});
//$('#Search').val("");
}
return deferred.promise;
},
getRandomSongs: function (action, genre, folder) {
var deferred = $q.defer();
if (globals.settings.Debug) { console.log('action:' + action + ', genre:' + genre + ', folder:' + folder); }
var size = globals.settings.AutoPlaylistSize;
content.selectedPlaylist = null;
if (typeof folder == 'number') {
content.selectedAutoPlaylist = folder;
} else if (genre !== '') {
content.selectedAutoPlaylist = genre;
} else {
content.selectedAutoPlaylist = 'random';
}
var genreParams = '';
if (genre !== '' && genre != 'Random') {
genreParams = '&genre=' + genre;
}
var folderParams = '';
if (typeof folder == 'number' && folder !== '' && folder != 'all') {
//alert(folder);
folderParams = '&musicFolderId=' + folder;
} else if (typeof $rootScope.SelectedMusicFolder.id != 'undefined' && $rootScope.SelectedMusicFolder.id >= 0) {
//alert($rootScope.SelectedMusicFolder.id);
folderParams = '&musicFolderId=' + $rootScope.SelectedMusicFolder.id;
}
$.ajax({
url: globals.BaseURL() + '/getRandomSongs.view?' + globals.BaseParams() + '&size=' + size + genreParams + folderParams,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (typeof data["subsonic-response"].randomSongs.song != 'undefined') {
var items = [];
if (data["subsonic-response"].randomSongs.song.length > 0) {
items = data["subsonic-response"].randomSongs.song;
} else {
items[0] = data["subsonic-response"].randomSongs.song;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
var next = $rootScope.queue[0];
$rootScope.playSong(false, next);
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
content.song.push(map.mapSong(item));
});
}
}
deferred.resolve(content);
}
});
return deferred.promise;
},
getPlaylists: function (refresh) {
var deferred = $q.defer();
if (globals.settings.Debug) { console.log("LOAD PLAYLISTS"); }
if (refresh || content.playlists.length == 0) {
$.ajax({
url: globals.BaseURL() + '/getPlaylists.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].playlists.playlist !== undefined) {
var items = [];
if (data["subsonic-response"].playlists.playlist.length > 0) {
items = data["subsonic-response"].playlists.playlist;
} else {
items[0] = data["subsonic-response"].playlists.playlist;
}
content.playlists = [];
content.playlistsPublic = [];
angular.forEach(items, function (item, key) {
if (item.owner == globals.settings.Username) {
content.playlists.push(item);
} else if (item.public) {
content.playlistsPublic.push(item);
}
});
deferred.resolve(content);
}
}
});
} else {
deferred.resolve(content);
}
return deferred.promise;
},
getPlaylist: function (id, action) {
var deferred = $q.defer();
content.selectedAutoPlaylist = null;
content.selectedPlaylist = id;
$.ajax({
url: globals.BaseURL() + '/getPlaylist.view?' + globals.BaseParams() + '&id=' + id,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (typeof data["subsonic-response"].playlist.entry != 'undefined') {
var items = [];
var playlist = data["subsonic-response"].playlist;
if (playlist.entry.length > 0) {
items = playlist.entry;
} else {
items[0] = playlist.entry;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
$rootScope.queue.push(map.mapSong(item));
});
var next = $rootScope.queue[0];
$rootScope.playSong(false, next);
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
content.song.push(map.mapSong(item));
});
notifications.updateMessage(items.length + ' Song(s) in Playlist', true);
}
} else {
content.song = [];
}
deferred.resolve(content);
}
});
return deferred.promise;
},
getStarred: function (action, type) {
var exception = {reason: 'Error when contacting the Subsonic server.'};
var deferred = $q.defer();
var httpPromise;
if(globals.settings.Protocol === 'jsonp') {
httpPromise = $http.jsonp(globals.BaseURL() + '/getStarred.view?callback=JSON_CALLBACK&' + globals.BaseParams(),
{
timeout: globals.settings.Timeout,
cache: true
});
} else {
httpPromise = $http.get(globals.BaseURL() + '/getStarred.view?' + globals.BaseParams(),
{
timeout: globals.settings.Timeout,
cache: true
});
}
httpPromise.success(function(data, status) {
var subsonicResponse = (data['subsonic-response'] !== undefined) ? data['subsonic-response'] : {status: 'failed'};
if (subsonicResponse.status === 'ok') {
if(angular.equals(subsonicResponse.starred, {})) {
deferred.reject({reason: 'Nothing is starred on the Subsonic server.'});
} else {
deferred.resolve(subsonicResponse.starred);
}
} else {
if(subsonicResponse.status === 'failed' && subsonicResponse.error !== undefined) {
exception.subsonicError = subsonicResponse.error;
}
deferred.reject(exception);
}
}).error(function(data, status) {
exception.httpError = status;
deferred.reject(exception);
});
return deferred.promise;
},
getRandomStarredSongs: function() {
var exception = {reason: 'No starred songs found on the Subsonic server.'};
var deferred = $q.defer();
this.getStarred().then(function (data) {
if(data.song !== undefined && data.song.length > 0) {
// Return random subarray of songs
var randomSongs = [].concat(_.sample(data.song, globals.settings.AutoPlayListSize));
deferred.resolve(randomSongs);
} else {
deferred.reject(exception);
}
}, function (reason) {
deferred.reject(reason);
});
return deferred.promise;
},
newPlaylist: function (data, event) {
var deferred = $q.defer();
var reply = prompt("Choose a name for your new playlist.", "");
if (reply != 'null' && reply !== null && reply !== '') {
$.ajax({
url: globals.BaseURL() + '/createPlaylist.view?' + globals.BaseParams() + '&name=' + reply,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
deferred.resolve();
}
});
}
return deferred.promise;
},
deletePlaylist: function () {
var deferred = $q.defer();
if (content.selectedPlaylist !== null) {
var id = content.selectedPlaylist;
if (utils.confirmDelete('Are you sure you want to delete the selected playlist?')) {
$.ajax({
url: globals.BaseURL() + '/deletePlaylist.view?' + globals.BaseParams() + '&id=' + id,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
deferred.resolve();
}
});
}
}
return deferred.promise;
},
savePlaylist: function () {
var deferred = $q.defer();
if (content.selectedPlaylist !== null) {
var id = content.selectedPlaylist;
var songs = [];
angular.forEach(content.song, function (item, key) {
songs.push(item.id);
});
if (songs.length > 0) {
$.ajax({
type: 'GET',
url: globals.BaseURL() + '/createPlaylist.view?' + globals.BaseParams(),
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
data: { playlistId: id, songId: songs },
success: function () {
deferred.resolve();
},
traditional: true // Fixes POST with an array in JQuery 1.4
});
}
}
return deferred.promise;
},
songsRemoveSelected: function (songs) {
var deferred = $q.defer();
angular.forEach(songs, function (item, key) {
var index = content.song.indexOf(item)
content.song.splice(index, 1);
});
deferred.resolve(content);
return deferred.promise;
},
getGenres: function () {
var deferred = $q.defer();
var genresStr = 'Acid Rock,Acoustic,Alt Country,Alt/Indie,Alternative & Punk,Alternative Metal,Alternative,AlternRock,Awesome,Bluegrass,Blues,Blues-Rock,Classic Hard Rock,Classic Rock,Comedy,Country,Country-Rock,Dance,Dance-Rock,Deep Funk,Easy Listening,Electronic,Electronica,Electronica/Dance,Folk,Folk/Rock,Funk,Grunge,Hard Rock,Heavy Metal,Holiday,House,Improg,Indie Rock,Indie,International,Irish,Jam Band,Jam,Jazz Fusion,Jazz,Latin,Live Albums,Metal,Music,Oldies,Other,Pop,Pop/Rock,Post Rock,Progressive Rock,Psychedelic Rock,Psychedelic,Punk,R&B,Rap & Hip-Hop,Reggae,Rock & Roll,Rock,Rock/Pop,Roots,Ska,Soft Rock,Soul,Southern Rock,Thrash Metal,Unknown,Vocal,World';
genres = genresStr.split(',');
/* This is broken in version 4.8, unable to convert XML to JSON
$.ajax({
url: globals.BaseURL() + '/getGenres.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (typeof data["subsonic-response"].genres != 'undefined') {
var items = [];
if (data["subsonic-response"].genres.length > 0) {
items = data["subsonic-response"].genres;
} else {
items[0] = data["subsonic-response"].genres;
}
$rootScope.Genres = items;
$scope.$apply();
}
}
});
*/
deferred.resolve(genres);
return deferred.promise;
},
getPodcasts: function (refresh) {
var deferred = $q.defer();
if (globals.settings.Debug) { console.log("LOAD PODCASTS"); }
$.ajax({
url: globals.BaseURL() + '/getPodcasts.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].podcasts.channel !== undefined) {
var items = [];
if (data["subsonic-response"].podcasts.channel.length > 0) {
items = data["subsonic-response"].podcasts.channel;
} else {
items[0] = data["subsonic-response"].podcasts.channel;
}
podcasts = items;
}
deferred.resolve(podcasts);
}
});
return deferred.promise;
},
getPodcast: function (id, action) {
var deferred = $q.defer();
content.selectedPodcast = id;
$.ajax({
url: globals.BaseURL() + '/getPodcasts.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].podcasts.channel !== undefined) {
var podcasts = [];
if (data["subsonic-response"].podcasts.channel.length > 0) {
podcasts = data["subsonic-response"].podcasts.channel;
} else {
podcasts[0] = data["subsonic-response"].podcasts.channel;
}
var items = [];
$.each(podcasts, function (i, item) {
if (item.id == id) {
items = item.episode;
}
});
if (typeof items != 'undefined') {
if (action == 'add') {
angular.forEach(items, function (item, key) {
if (item.status != "skipped") {
$rootScope.queue.push(map.mapPodcast(item));
}
});
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
if (item.status != "skipped") {
$rootScope.queue.push(map.mapPodcast(item));
}
});
var next = $rootScope.queue[0];
$rootScope.playSong(false, next);
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
content.album = [];
content.song = [];
angular.forEach(items, function (item, key) {
if (item.status != "skipped") {
content.song.push(map.mapPodcast(item));
}
});
}
}
}
deferred.resolve(content);
}
});
return deferred.promise;
}
// End subsonic
};
});