=== modified file 'grooveshark.user.js' --- grooveshark.user.js 2012-09-18 18:39:04 +0000 +++ grooveshark.user.js 2013-03-07 17:54:19 +0000 @@ -1,12 +1,13 @@ // ==UserScript== -// @include http://grooveshark.com/#!/* +// @include http://grooveshark.com/* // @require utils.js // ==/UserScript== window.Unity = external.getUnityObject(1); + function isCorrectPage() { - var i, ids = ['player_play_pause', 'player_next']; + var i, ids = ['play-pause', 'play-next']; for (i = 0; i < ids.length; i++) { if (!document.getElementById(ids[i])) { @@ -17,16 +18,60 @@ return true; } +function timeStringToSeconds(timeString) { + var values = timeString.split(':'); + var seconds = 0; + + if (values.length <= 3) { + for (i = 0; i < values.length; i++) { + seconds = seconds * 60 + parseInt(values[i]); + } + } + + return seconds; +} + +function getProgress() { + var elapsed = 0; + var total = 1; + try { + elapsed = document.getElementById('time-elapsed').innerHTML; + total = document.getElementById('time-total').innerHTML; + } catch (x) {} + + return timeStringToSeconds(elapsed) / timeStringToSeconds(total); +} + function getTrackInfo() { var artist = null; - var title = document.title; + var title = null; var artLocation = null; var album = null; - try { - artist = document.evaluate('//*[@id="playerDetails_current_song"]/a[@class="artist"]', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.title; - title = document.getElementsByClassName('currentSongLink song')[0].title; - album = document.evaluate('//*[@id="playerDetails_current_song"]/a[@class="album"]', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.title; - artLocation = document.evaluate('//*[@class="queue-item queue-item-active"]/div/div/div/img', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.src; + + var meta = null; + var songId = null; + /* translations */ + var by = 'by'; + var on = 'on'; + try { + meta = document.getElementById('now-playing-metadata'); + artist = meta.getElementsByClassName('now-playing-link artist')[0].title; + album = meta.getElementsByClassName('now-playing-link album')[0].title; + title = meta.getElementsByClassName('now-playing-link song')[0].title; + songId = meta.getElementsByClassName('now-playing-link song')[0].getAttribute('data-song-id'); + artLocation = document.getElementById('now-playing-image').src; + } catch (x) {} + try { + var i; + var translations = meta.getElementsByTagName('span'); + for (i = 0; i < translations.length; i ++) { + var tr = translations[i].getAttribute('data-translate-text'); + if (tr == 'BY') { + by = translations[i].innerHTML; + } else if (tr == 'ON') { + on = translations[i].innerHTML; + } + } } catch (x) {} if (!artLocation) { @@ -37,46 +82,142 @@ title: title, album: album, artist: artist, - artLocation: artLocation + artLocation: artLocation, + custom: {songId: songId, by: by, on: on} }; } +function getRemainingQueued() { + try { + var queueList = document.getElementById('queue-list'); + var queueLength = 0; + var n = queueList.getElementsByClassName('queue-item queue-item-active')[0]; + if (n === null) + return 0; + for (n = n.nextSibling; n !== null; n = n.nextSibling) { + if (n.style.display == 'none') + break; + queueLength ++; + } + return queueLength; + } catch (x) {} + return 0; +} + +function getSections() { + var sections = new Array(); + /* TODO potentially expensive */ + var nodes = document.getElementsByClassName('can-play'); + + for (var i = 0; i < nodes.length; i++) { + var title = nodes[i].getElementsByClassName('section-title')[0].getElementsByTagName('span')[0].innerHTML; + var button = nodes[i].getElementsByClassName('play-section')[0]; + sections[i] = { + "title": title, + "clickFunc": function() { wrapCallback(launchClickEvent(button)); } + }; + } + + return sections; +} + +function checkNotifications(previouslyNotified) { + var container = document.getElementById('notifications'); + if (container.hasChildNodes()) { + var notifications = container.getElementsByClassName('notification'); + for (var i = 0; i < notifications.length; i++) { + if (!previouslyNotified[notifications[i].id]) { + var title = notifications[i].getElementsByClassName('title')[0].innerHTML; + var description = notifications[i].getElementsByClassName('description')[0].innerHTML; + var icon = 'http://grooveshark.com/webincludes/images/Grooveshark_Logo_Vertical_100.png'; + if (title.length == 0) { + title = "Grooveshark"; + } else { + title = "Grooveshark: " + title; + } + Unity.Notification.showNotification(title, description, icon); + previouslyNotified[notifications[i].id] = 1; + } + } + } +} + function musicPlayerSetup() { + var previouslyNotified = {}; + var lastSongId = 0; + Unity.MediaPlayer.init("Grooveshark"); - + + Unity.Launcher.clearCount(); + Unity.Launcher.clearProgress(); + setInterval(wrapCallback(function retry() { var trackInfo = getTrackInfo(); + var progress = getProgress(); + var queued = getRemainingQueued(); + var sections = getSections(); + checkNotifications(previouslyNotified); + + if (sections.length > 0) { + for (var i = 0; i < sections.length; i++) { + Unity.Launcher.addAction(sections[i].title, sections[i].clickFunc); + } + } else { + Unity.Launcher.removeActions() + } if (!trackInfo) { return; } - var notpaused = document.getElementById('player_play_pause').className.match(/pause$/); - if (null !== notpaused) { + if (lastSongId != trackInfo.custom.songId) { + var text = trackInfo.custom.by + " " + trackInfo.artist + "\n" + + trackInfo.custom.on + " " + trackInfo.album; + Unity.Notification.showNotification(trackInfo.title, text, trackInfo.artLocation); + lastSongId = trackInfo.custom.songId; + } + delete trackInfo.custom; + + var notpaused = document.getElementById('play-pause').className.match(/paused$/); + if (notpaused == null) { Unity.MediaPlayer.setPlaybackState(Unity.MediaPlayer.PlaybackState.PLAYING); } else { Unity.MediaPlayer.setPlaybackState(Unity.MediaPlayer.PlaybackState.PAUSED); } + Unity.MediaPlayer.setTrack(trackInfo); + + if (progress > 0) { + Unity.Launcher.setProgress(getProgress()); + } else { + Unity.Launcher.clearProgress(); + } + + if (queued > 0) { + Unity.Launcher.setCount(queued); + } else { + Unity.Launcher.clearCount(); + } + }), 1000); Unity.MediaPlayer.onPlayPause(wrapCallback(function () { - launchClickEvent(document.getElementById('player_play_pause')); + launchClickEvent(document.getElementById('play-pause')); })); Unity.MediaPlayer.onNext(wrapCallback(function () { - launchClickEvent(document.getElementById('player_next')); + launchClickEvent(document.getElementById('play-next')); })); Unity.MediaPlayer.onPrevious(wrapCallback(function () { - launchClickEvent(document.getElementById('player_previous')); + launchClickEvent(document.getElementById('play-prev')); })); } if (isCorrectPage()) { Unity.init({ name: "Grooveshark", - domain: 'grooveshark.com', - homepage: 'http://grooveshark.com', + domain: 'grooveshark.com', + homepage: 'http://grooveshark.com', iconUrl: "icon://unity-webapps-grooveshark", onInit: wrapCallback(musicPlayerSetup) }); } === modified file 'manifest.json' --- manifest.json 2012-09-18 18:39:04 +0000 +++ manifest.json 2013-03-07 17:32:00 +0000 @@ -1,1 +1,1 @@ -{"includes":["http://grooveshark.com/#!/*"],"requires":["utils.js"],"name":"grooveshark","scripts":["grooveshark.user.js"],"maintainer":"Webapps Team ","manifest-version":"1.0","integration-version":"2.2","package-name":"grooveshark","icons":{"128":"128/unity-webapps-grooveshark.png","48":"48/unity-webapps-grooveshark.png","52":"52/unity-webapps-grooveshark.png","64":"64/unity-webapps-grooveshark.png"},"domain":"grooveshark.com","homepage":"http://grooveshark.com","license":"GPL-3"} \ No newline at end of file +{"includes":["http://grooveshark.com/*"],"requires":["utils.js"],"name":"grooveshark","scripts":["grooveshark.user.js"],"maintainer":"Webapps Team ","manifest-version":"1.0","integration-version":"2.2","package-name":"grooveshark","icons":{"128":"128/unity-webapps-grooveshark.png","48":"48/unity-webapps-grooveshark.png","52":"52/unity-webapps-grooveshark.png","64":"64/unity-webapps-grooveshark.png"},"domain":"grooveshark.com","homepage":"http://grooveshark.com","license":"GPL-3"}