/* * $Id$ * Javascript for playlist.html * * Copyright (C) 2005 Anders Betnér (andbe611@users.sourceforge.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Detta script finns att hämta på http://www.jojoxx.net och får användas fritt så länge som dessa rader står kvar. */ function DataDumper(obj,n,prefix){ var str=""; prefix=(prefix)?prefix:""; n=(n)?n+1:1; var ind=""; for(var i=0;i<n;i++){ ind+=" "; } if(typeof(obj)=="string"){ str+=ind+prefix+"String:\""+obj+"\"\n"; } else if(typeof(obj)=="number"){ str+=ind+prefix+"Number:"+obj+"\n"; } else if(typeof(obj)=="function"){ str+=ind+prefix+"Function:"+obj+"\n"; } else if(typeof(obj) == 'boolean') { str+=ind+prefix+"Boolean:" + obj + "\n"; } else { var type="Array"; for(var i in obj){ type=(type=="Array"&&i==parseInt(i))?"Array":"Object" } str+=ind+prefix+type+"[\n"; if(type=="Array"){ for(var i in obj){ str+=DataDumper(obj[i],n,i+"=>"); } } else { for(var i in obj){ str+=DataDumper(obj[i],n,i+"=>"); } } str+=ind+"]\n"; } return str; } //var g_req; var g_requestor; var g_selectedGenres = Array(); var g_selectedAlbums = Array(); var g_selectedArtists = Array(); var baseUrl = window.location.toString(); baseUrl = baseUrl.substr(0,baseUrl.length-13); String.prototype.myEncodeURI = function () { s = encodeURI(this); s = s.replace(/\'/,'%27'); return s.replace(/&/,'%26'); }; Requestor = function(baseUrl) { g_requestor = this; this.req = ''; // holds the request this.responseHandler; this.baseUrl = baseUrl; this.que = Array(); // All browsers but IE if (window.XMLHttpRequest) { this.req = new XMLHttpRequest(); // MS IE } else if (window.ActiveXObject) { this.req = new ActiveXObject("Microsoft.XMLHTTP"); } this.busy = false; }; Requestor.prototype.setResponseHandler = function(resp) { this.responseHandler = resp; }; Requestor.prototype.addRequest = function(url) { if (this.busy) { this.que.push(url); } else { this._openRequest(url); } }; Requestor.prototype._openRequest = function(url) { this.busy = true; if (url.search(/\?/)> -1) { url += '&output=xml'; } else { url += '?output=xml'; } this.req.open('get',this.baseUrl+url,true); this.req.onreadystatechange = Requestor_handleRequest; this.req.send(null); }; Requestor_handleRequest = function() { // readystate 4 means the whole document is loaded if (4 == g_requestor.req.readyState) { // Only try to parse the response if we got // ok from the server if (200 == g_requestor.req.status) { // send the recieved document off to the handler g_requestor.responseHandler(g_requestor.req.responseXML); } // Check if there are requests qued up if (g_requestor.que.length > 0) { // Just to be able to pull ourseves up by our boot straps window.setTimeout(Requestor_queChecker,5); return; } else { g_requestor.busy = false; } } }; function Requestor_queChecker() { if (url = g_requestor.que.shift()) { g_requestor._openRequest(url); } } function response(xmldoc) { if ('daap.databaseplaylists' == xmldoc.firstChild.nodeName) { el = document.getElementById('source'); addPlaylists(el,xmldoc); } else if ('daap.databasebrowse' == xmldoc.firstChild.nodeName) { // Ok we have response from a browse query switch (xmldoc.firstChild.childNodes[3].nodeName) { case 'daap.browsegenrelisting': el = document.getElementById('genre'); addOptions(el,'genre',xmldoc); break; case 'daap.browseartistlisting': el = document.getElementById('artist'); addOptions(el,'artist',xmldoc); break; case 'daap.browsealbumlisting': el = document.getElementById('album'); addOptions(el,'album',xmldoc); // All other boxes are updated, now get the songs getSongs(); break; default: // We got something else back... } } else if ('daap.databasesongs' == xmldoc.firstChild.nodeName) { // Songlist addSongs(xmldoc); } } function init() { req = new Requestor(baseUrl); req.setResponseHandler(response); req.addRequest('databases/1/containers'); req.addRequest('databases/1/browse/genres'); req.addRequest('databases/1/browse/artists'); req.addRequest('databases/1/browse/albums'); el = document.getElementById('source'); el.addEventListener('change',playlistSelect,true); el = document.getElementById('genre'); el.addEventListener('change',genreSelect,true); el = document.getElementById('artist'); el.addEventListener('change',artistSelect,true); el = document.getElementById('album'); el.addEventListener('change',albumSelect,true); } function addOptions(el,label,xmldoc) { while(el.hasChildNodes()) { el.removeChild(el.firstChild); } itemCnt = xmldoc.getElementsByTagName('dmap.specifiedtotalcount').item(0).textContent; if (parseInt(itemCnt) > 1) { plural = 's'; } else { plural = ''; } option = document.createElement('option'); option.value = '1'; option.selected = false; option.appendChild(document.createTextNode('All ('+itemCnt+' '+label +plural+')')); el.appendChild(option); items = xmldoc.getElementsByTagName('dmap.listingitem'); selectAll = true; for (i=0; i<items.length; i++) { option = document.createElement('option'); itemName = items[i].textContent; option.value = itemName; switch (label) { case 'genre': if (g_selectedGenres[itemName]) { option.selected = true; selectAll = false; } break; case 'artist': if (g_selectedArtists[itemName]) { option.selected = true; selectAll = false; } break; case 'album': if (g_selectedAlbums[itemName]) { option.selected = true; selectAll = false; } default: // if we get here something is wrong // silently ignore it } //###FIXME do some kind of itelligent truncation of the string option.appendChild(document.createTextNode(itemName.substr(0,30))); el.appendChild(option); } if (selectAll) { // clear the global selections arrays el.options[0].selected = true; switch (label) { case 'genre': g_selectedGenres = Array(); break; case 'artist': g_selectedArtists = Array(); break; case 'album': g_selectedAlbums = Array(); break; default: // Can't get here } } else { el.options[0].selected = false; } } function addPlaylists(el,xmldoc) { //items = xmldoc.getElementsByTagName('dmap.listingitem'); list = xmldoc.childNodes[0].childNodes[4]; // Start on 1 since the first node is the name of the daap server for (i=1; i < list.childNodes.length; i++) { option = document.createElement('option'); listNumber = list.childNodes[i].childNodes[0].textContent; listName = list.childNodes[i].childNodes[2].textContent; option.appendChild(document.createTextNode(listName)); option.setAttribute('value',listNumber); el.appendChild(option); } } function playlistSelect(event) { table = document.getElementById('songs'); tableBody = removeRows(table); playlistNumber = document.getElementById('source').value; browse = document.getElementById('browse'); if (1 == playlistNumber) { browse.style.display = 'block'; } else { browse.style.display = 'none'; } g_req.open('get',baseUrl + 'databases/1/containers/' + playlistNumber + '/items?meta=dmap.itemname,daap.songalbum,daap.songartist,daap.songgenre,daap.songtime&output=xml',false); g_req.send(null); items = g_req.responseXML.getElementsByTagName('dmap.listingitem'); className = 'odd'; for (i=0; i < items.length; i++) { // Have to check if the tag really was returned from the server if (song = items[i].getElementsByTagName('dmap.itemname').item(0)) { song = song.textContent; } else { song = ''; } time = ''; //items[i].getElementsByTagName('daap.songtime').item(0).textContent; if (artist = items[i].getElementsByTagName('daap.songartist').item(0)) { artist = artist.textContent; } else { artist = ''; } if (album = items[i].getElementsByTagName('daap.songalbum').item(0)) { album = album.textContent; } else { album = ''; } if (genre = items[i].getElementsByTagName('daap.songgenre').item(0)) { genre = genre.textContent; } else { genre = ''; } if ('odd' == className) { className = 'even'; } else { className = 'odd'; } addRow(tableBody,className,song,time,artist,album,genre); } } function addRow(tbody,className,song,time,artist,album,genre) { row = document.createElement("tr"); row.setAttribute('class',className); cell = document.createElement("td"); cell.appendChild(document.createTextNode(song)); row.appendChild(cell); cell = document.createElement("td"); cell.appendChild(document.createTextNode(time)); row.appendChild(cell); cell = document.createElement("td"); //###FIXME do some kind of itelligent truncation of the string cell.appendChild(document.createTextNode(artist.substring(0,30))); row.appendChild(cell); cell = document.createElement("td"); cell.appendChild(document.createTextNode(album)); row.appendChild(cell); cell = document.createElement("td"); cell.appendChild(document.createTextNode(genre)); row.appendChild(cell); tbody.appendChild(row); } function removeRows(table) { tableBody = table.getElementsByTagName('tbody').item(0); table.removeChild(tableBody); tableBody = document.createElement('tbody'); tableBody.setAttribute('class','mytbody'); table.appendChild(tableBody); return tableBody; } function genreSelect(event) { selectObject = event.target; if (selectObject.options[0].selected) { filter = ''; g_selectedGenres = Array(); //###FIXME must dselect all others } else { filter = Array(); //###FIXME if there is just the all genre there will be an error here for (i=1; i<selectObject.options.length; i++) { genre = selectObject.options[i].value; if (selectObject.options[i].selected) { filter.push("'daap.songgenre:" + genre.myEncodeURI() + "'"); g_selectedGenres[genre] = true; } else { g_selectedGenres[genre] = false; } } filter = '?filter=' + filter.join(','); } //dump(DataDumper(g_selectedGenres)); g_requestor.addRequest('databases/1/browse/artists' + filter); g_requestor.addRequest('databases/1/browse/albums' + filter); } function artistSelect(event) { selectObject = event.target; filter = ''; if (selectObject.options[0].selected) { // All selected, sort according to genre filter = Array(); for (genre in g_selectedGenres) { if (g_selectedGenres[genre]) { filter.push("'daap.songgenre:" + genre.myEncodeURI() + "'"); } } if (0 == filter.length) { // If filter array is empty then "All genres" is selected // so set filter to empty filter = ''; } else { filter = '?filter=' + filter.join(','); } } else { filter = Array(); for (i=1; i<selectObject.options.length; i++) { artist = selectObject.options[i].value; if (selectObject.options[i].selected) { filter.push("'daap.songartist:" + artist.myEncodeURI() + "'"); g_selectedArtists[artist] = true; } else { g_selectedArtists[artist] = false; } } // If all is selected then search on all artists but honor genre filter = '?filter=' + filter.join(','); } g_requestor.addRequest('databases/1/browse/albums' + filter); } function albumSelect(event) { // just get the songs, the only box changed is this one getSongs(); } function getSongs() { genre = document.getElementById('genre').value; artist = document.getElementById('artist').value; album = document.getElementById('album').value; //alert("genre: "+genre +"\nartist: "+ artist + "\nalbum:"+ album); query = Array(); if (genre != '1') { query.push('\'daap.songgenre:' + genre.myEncodeURI() +"'"); } if (artist != '1') { query.push('\'daap.songartist:' + artist.myEncodeURI() +"'"); } if (album != '1') { query.push('\'daap.songalbum:' + album.myEncodeURI() +"'"); } if (0 == query.length) { // If filter array is empty then "All genres" is selected // so set filter to empty query = ''; } else { query = '&query=' + query.join(' '); } //alert(query); g_requestor.addRequest('databases/1/items' + '?meta=dmap.itemname,daap.songalbum,daap.songartist,daap.songgenre,daap.songtime'+query); ///items?meta=dmap.itemname,daap.songalbum,daap.songartist,daap.songgenre,daap.songtime&output=xml } function addSongs(xmldoc) { items = xmldoc.getElementsByTagName('dmap.listingitem'); className = 'odd'; table = document.getElementById('songs'); tableBody = removeRows(table); for (i=0; i < items.length; i++) { // Have to check if the tag really was returned from the server if (song = items[i].getElementsByTagName('dmap.itemname').item(0)) { song = song.textContent; } else { song = ''; } time = ''; //items[i].getElementsByTagName('daap.songtime').item(0).textContent; if (artist = items[i].getElementsByTagName('daap.songartist').item(0)) { artist = artist.textContent; } else { artist = ''; } if (album = items[i].getElementsByTagName('daap.songalbum').item(0)) { album = album.textContent; } else { album = ''; } if (genre = items[i].getElementsByTagName('daap.songgenre').item(0)) { genre = genre.textContent; } else { genre = ''; } if ('odd' == className) { className = 'even'; } else { className = 'odd'; } addRow(tableBody,className,song,time,artist,album,genre); } }