您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Sort overall top artists by time played.
// ==UserScript== // @name Last.fm - Opera: Sort by time // @namespace // @description Sort overall top artists by time played. // @include http://www.last.fm/user/* // @include http://www.last.fm/user/*/bytime* // @version 0.0.1.20140511222853 // @namespace https://gf.qytechs.cn/users/835 // ==/UserScript== var artDisp = 50; var statusArea; var myTempWorkArea; var username; var othername; var theURL; var timePlayed = new Array(); var nextPtr = new Array(); var prevPtr = new Array(); var XTime = new Array(); var traxPlayed = new Array(); var totalSongs = new Array(); var artistNames = new Array(); var firstLink = 0; var lastLink = 0; var artLinks; var trackRows = new Array(); var trackCount = 0; var periodViewed = "overall"; var tstABC = new Array(); var artistArray = new Object(); // chartDescrip var chartDescrip = new Object(); chartDescrip["overall"] = "overall"; chartDescrip["year"] = "last 12 months"; chartDescrip["6month"] = "last 6 months"; chartDescrip["3month"] = "last 3 months"; chartDescrip["week"] = "last week"; /* History */ // snyde1: 05/09/2008 First Version // snyde1: 06/09/2008 Move to 404 page, fix CPU problems // added track counting // snyde1: 03.01.2009 fix up tracks, formatting // snyde1: 10.01.2009 fix sorting // snyde1: 31-Jul-2009 fix for Opera 10 /* SCRIPT */ function xpath(query) { return document.evaluate(query, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); } function doArtists() { statusArea.innerHTML="Loading your overall top artists"; theURL = "/user/" + othername + "/charts?rangetype=overall&subtype=artists"; if (1 != getPageURL(theURL)) { statusArea.innerHTML="Error loading data from chart"; return; } var newTable = document.createElement("table"); newTable.setAttribute("class","candyStriped chart"); statusArea.parentNode.insertBefore(newTable,statusArea.nextSibling); artLinks = xpath("//td[@class='subjectCell']/div/a"); if (artLinks.snapshotLength < 0) {statusArea.innerHTML="Error loading data from chart - no artists found."; return;} var realCount = 0; statusArea.innerHTML="<H2 class='heading'>Top overall artists by time</H2>The following are your top artists sorted by time played. Times are in minutes of play, an asterisk (*) shows where times are approximate. The information in parentheses is based on your number of plays for that artist.<P> "; if (artDisp > artLinks.snapshotLength) { artDisp = artLinks.snapshotLength; } for (var i = 0; i < artDisp; i++) { var artistName = artLinks.snapshotItem(i).href.match(/\/([^\/]*)$/)[1]; if (1 != getArtLibrary(artistName)) { statusArea.innerHTML="Error loading data from library for "+artistName; return; } artLinks.snapshotItem(i).href = "/user/" + othername + "/library/music/"+artistName+"?sortOrder=desc&sortBy=plays"; var myTimes = xpath("//td[@class='time border']"); var myPlays = xpath("//td[@class='playcount border']/a"); var totalTime = 0; var trackTime = 0; var badFlag = 0; var ttSec = "sec"; traxPlayed[i] = 0; for(var j=0; j < myTimes.snapshotLength; j++) { myPlays.snapshotItem(j).innerHTML = myPlays.snapshotItem(j).innerHTML.replace(/[, ]/g,""); if (myTimes.snapshotItem(j).innerHTML.match(/:/)) { var trackMin = myTimes.snapshotItem(j).innerHTML.split(/:/)[0]; var trackSec = myTimes.snapshotItem(j).innerHTML.split(/:/)[1]; trackTime = 60*parseInt(trackMin)+parseInt(trackSec); } else { trackTime = 0; badFlag += parseInt(myPlays.snapshotItem(j).innerHTML); } if (isNaN(parseInt(myPlays.snapshotItem(j).innerHTML))) {myPlays.snapshotItem(j).innerHTML = 0; } totalTime += parseInt(myPlays.snapshotItem(j).innerHTML)*trackTime; traxPlayed[i] += parseInt(myPlays.snapshotItem(j).innerHTML); } totalSongs[i] = myTimes.snapshotLength; XTime[i] = 0; if (badFlag > 0) { XTime[i] = badFlag * totalTime / (traxPlayed[i] - badFlag); XTime[i] = parseInt(XTime[i]+.5); totalTime += XTime[i]; ttSec = "sec*"; } if (isNaN(totalTime)) { totalTime = 0; } timePlayed[i] = totalTime; artistNames[i] = artistName; artistArray[artistName] = new Object(); artistArray[artistName].url = artLinks.snapshotItem(i).href; artistArray[artistName].html = artLinks.snapshotItem(i).innerHTML; artistArray[artistName].count = myTimes.snapshotLength; artistArray[artistName].position = i; artistArray[artistName].time = totalTime; tstABC[i] = i; // ll if ((i < 25) || (4 == (i%5))){newTable.innerHTML = makeTable();} } newTable.innerHTML = makeTable(); } function getPageURL(myURL) { var xmlhttp=new XMLHttpRequest(); xmlhttp.open("GET", myURL, false); xmlhttp.send(null); if (xmlhttp.readyState!=4) { return(0); } var xmlText = xmlhttp.responseText; if (! xmlText.match(/<tbody>/i)) { return(0); } xmlText = xmlText.split(/<tbody>/i)[1]; xmlText = xmlText.split(/<\/tbody>/i)[0]; var chartTab = document.createElement("table"); chartTab.setAttribute("style","display:none; visibility:hidden;"); chartTab.innerHTML = xmlText; document.getElementById("content").insertBefore(chartTab,myTempWorkArea); return(1); } function getArtLibrary(artist) { var theURL = "/user/" + othername + "/library/music/"+artist+"?sortOrder=desc&sortBy=plays"; var xmlhttp=new XMLHttpRequest(); xmlhttp.open("GET", theURL, false); xmlhttp.send(null); if (xmlhttp.readyState!=4) { return(0); } var xmlText = xmlhttp.responseText; if (!xmlText) { return(0); } if (xmlText.match(/<tbody>/i)) { xmlText = xmlText.split(/<tbody>/i)[1]; xmlText = xmlText.split(/<\/tbody>/i)[0]; } else { return(0); } myTempWorkArea.innerHTML = "<table id='timeCalcArea'>"+xmlText+"</table>"; return(1); } function makeTable() { var j = firstLink; var textBlock=""; var k=1; maxTime = timePlayed[firstLink]; textBlock = ""; var tstBCA = tstABC.sort(sortMyArr); var maxTime = timePlayed[tstBCA[0]]; for (var q=0;q<tstBCA.length;q++) { var r = tstBCA[q]; var artNam = artistNames[r]; var rowType = ""; if (1 == (q%2)) {rowType=" class=\"odd\"";} var barWid = parseInt(timePlayed[r]*100/maxTime); if (barWid<20) {barWid = 20;} var minuPlay = commatize(parseInt(timePlayed[r]/60)); var playStr = mTimeStr(timePlayed[r]); if (XTime[tstBCA[q]] != 0) {minuPlay += "*";} var rankDelta = q - (artistArray[artNam].position); var rankIn = "(—)"; if (rankDelta > 0) { rankIn = "<font color=red>⇓ "+rankDelta+"</font>";} if (rankDelta < 0) { rankIn = "<font color=green>⇑ "+(0-rankDelta)+"</font>";} textBlock += "<TR"+rowType+"><TD class=\"positionCell\">"+(q+1)+"</TD><TD class=\"positionCell\">"+rankIn+"</TD>"+ "<TD class=\"subjectCell\" title=\""+artistArray[artNam].html+", played "+commatize(traxPlayed[r])+" times, for "+playStr+"\"><A HREF='"+artistArray[artNam].url+"'>"+ artistArray[artNam].html+"</A><span> (#"+(r+1)+" with "+commatize(traxPlayed[r])+" plays)</span></TD>"+ "<TD class=\"chartbarCell\"><DIV Style=\"width:"+barWid+"%\" class=\"chartbar\"><span>"+minuPlay+"</span></TD></TR>\n"; } return(textBlock); } function mTimeStr(newTotTim){ var secTot = newTotTim % 60; newTotTim = (newTotTim - secTot)/60; var minTot = newTotTim % 60; newTotTim = (newTotTim - minTot)/60; var hourTt = newTotTim % 24; var dayTot = (newTotTim - hourTt)/24; if (hourTt < 10) {hourTt = "0"+hourTt;} if (minTot < 10) {minTot = "0"+minTot;} if (secTot < 10) {secTot = "0"+secTot;} var timPlyStr = dayTot +"d,"+hourTt+":"+minTot+":"+secTot; return(timPlyStr); } function commatize(number,comma,deci) { number = number+""; if (!comma) { var comma = ","; } if (!deci) { var deci = "."; } var numNeg = 0; if (number.match(/^-/)) {numNeg = 1; number = number.replace(/^-/,"");} var numdp = number.split("."); if (numdp.length == 2) {var decimal = numdp[1];} var integer = numdp[0]; if (integer.length < 4) { if (numdp.length == 2) {number = integer + deci + decimal;} if (numNeg == 1) { number = "-" + number; } return(number); } var stubFrnt = integer.length % 3; if (stubFrnt == 0) {stubFrnt = 3;} var newnumber = integer.substr(0,stubFrnt); var oldPos = stubFrnt; while(oldPos < integer.length ) { newnumber = newnumber + comma + integer.substr(oldPos, 3); oldPos = oldPos + 3; } if (numdp.length == 2) {newnumber = newnumber + deci + decimal;} if (numNeg == 1) {newnumber = "-" + newnumber;} return(newnumber); } function clearArea(){ var fourohfour = document.getElementById('fourOhFour'); fourohfour.innerHTML=""; statusArea = document.createElement("DIV"); statusArea.innerHTML = "<H2 class='heading'>Sort by time</H2>"; fourohfour.insertBefore(statusArea,fourohfour.firstChild); var pageTitle = xpath("//title"); if ( pageTitle.snapshotLength > 0 ) { if ( location.href.match(/dotype=artists/i)) { var textReplace = "Overall Artists "; } else if (location.href.match(/dotype=tracks/i)) { var textReplace = "Tracks "; } pageTitle.snapshotItem(0).innerHTML = pageTitle.snapshotItem(0).innerHTML.replace(/users at last.fm/i,textReplace+", sorted by time played."); } fourohfour.setAttribute("style","width:80%"); myTempWorkArea = document.createElement("DIV"); myTempWorkArea.setAttribute("id","myTempWorkArea"); myTempWorkArea.setAttribute("style","display: none"); var rightCol = document.getElementById("content"); rightCol.insertBefore(myTempWorkArea, rightCol.lastChild.nextSibling); } function doForm() { var formArea = document.createElement("FORM"); var formText = ""; formArea.setAttribute("METHOD","GET"); formText = "<H2 class='heading'>Selection</H2><P>Use this form to select the type and number of items to check. Note that only the \"overall\" period is valid for artists.</P>"; formText += "Number of entries <INPUT TYPE=\"TEXT\" NAME=\"Number\" Value=\"50\" MAXLENGTH=3>"; formText += "of type <SELECT NAME=\"DoType\"> <OPTION SELECTED VALUE=\"Artists\"> Artists <OPTION VALUE=\"Tracks\"> Tracks </SELECT>"; formText += " for the period <SELECT NAME=\"Time\"> <OPTION SELECTED VALUE=\"overall\"> Overall <OPTION VALUE=\"year\"> 12 Month <OPTION VALUE=\"6month\"> 6 Month <OPTION VALUE=\"3month\"> 3 Month </SELECT>"; formText += " <INPUT TYPE='SUBMIT'>"; formArea.innerHTML = formText; document.getElementById('fourOhFour').insertBefore(formArea, document.getElementById('fourOhFour').lastChild.nextSibling) } (function() { if (!location.href.match(/\/bytime/) ) { // should be on profile if (! location.href.match(/user\/[^\/]*$/) ) { return; } username = location.href.match(/user\/([^\/]*)$/)[1]; var addLink = document.createElement("li"); addLink.innerHTML = "<a href=\"/user/"+username+"/bytime\">Time</a>"; var addLinkHere = xpath('//ul[@class="visible-menu"]').snapshotItem(0); addLinkHere.insertBefore(addLink, addLinkHere.childNodes[5]); return; } username = getLastfmUsername(); if (username == "") { return; } clearArea(); if (location.href.match(/number=/i)) { var numberToGet = location.href.match(/number=([^&$]*)[&$]/i)[1]; if (! isNaN(parseInt(numberToGet))) {artDisp = parseInt(numberToGet);} } if (location.href.match(/time=/i)) { periodViewed = location.href.match(/time=([^&$]*)$/i)[1]; } othername = location.href.match(/\/user\/([^\/]*)\/bytime/)[1]; if ( location.href.match(/dotype=artists/i)) { doArtists(); } else if (location.href.match(/dotype=tracks/i)) { doTracks(); } if (location.href.match(/\/bytime/i)) { doForm(); } return; })(); function getLastfmUsername() { var usernameLink = xpath("//a[contains(@class,'user-badge')]"); if (usernameLink.snapshotLength > 0) { var userNameLoc = usernameLink.snapshotItem(0).innerHTML; userNameLoc = userNameLoc.replace(/<[^<>]*>/g,""); userNameLoc = userNameLoc.replace(/\s/g,""); return(userNameLoc); } else { return(""); } } function doTracks() { var trackArray = new Object(); statusArea.innerHTML="Loading your top tracks"; theURL = "/user/" + othername + "/charts?rangetype="+periodViewed+"&subtype=tracks"; if (1 != getPageURL(theURL)) { statusArea.innerHTML="Error loading data from chart"; return; } var artistNames = new Array(); var trackNames = new Array(); var newTable = document.createElement("table"); newTable.setAttribute("class","candyStriped chart"); statusArea.parentNode.insertBefore(newTable,statusArea.nextSibling); artLinks = xpath("//td[@class='subjectCell']/div/a"); var trkLinks = xpath("//td[@class='chartbarCell']/div/a/span"); if (artLinks.snapshotLength < 0) {statusArea.innerHTML="Error loading data from chart - no artists found."; return;} var realCount = 0; artDisp = 2*artDisp; if (artDisp > artLinks.snapshotLength) { artDisp = artLinks.snapshotLength; } for (var i = 0; i < artDisp; i++) { var artistName = artLinks.snapshotItem(i).innerHTML; i++; var trackName = artLinks.snapshotItem(i).innerHTML; if (!trackArray[artistName]) { trackArray[artistName] = new Object(); trackArray[artistName].url = "url"; trackArray[artistName].tracks = new Object(); trackArray[artistName].tracks[trackName] = new Object(); trackArray[artistName].tracks[trackName].url = artLinks.snapshotItem(i).href; trackArray[artistName].tracks[trackName].count = trkLinks.snapshotItem((i-1)/2).innerHTML.replace(/,/g,""); trackArray[artistName].tracks[trackName].position = (i-1)/2; trackArray[artistName].tracks[trackName].time = 0; } else{ trackArray[artistName].tracks[trackName] = new Object(); trackArray[artistName].tracks[trackName].url = artLinks.snapshotItem(i).href; trackArray[artistName].tracks[trackName].count = trkLinks.snapshotItem((i-1)/2).innerHTML.replace(/,/g,""); trackArray[artistName].tracks[trackName].position = (i-1)/2; trackArray[artistName].tracks[trackName].time = 0; } realCount++; } statusArea.innerHTML = ""; for( var i in trackArray) { statusArea.innerHTML = "Loading artist: <font color='blue'>"+i+"</font>"; getArtLibrary(i); var myTimes = xpath("//td[@class='time border']"); var myPlays = xpath("//td[@class='playcount border']"); var myTrcks = xpath("//td[@class='subject']/span[@class='name']/a"); for (var j in trackArray[i].tracks ) { var k = -1; do { k=k+1; } while ((k<myTrcks.snapshotLength) && (j != myTrcks.snapshotItem(k).innerHTML)) if (k >= myTrcks.snapshotLength) {trackArray[i].tracks[j].time = "0:00";} else {trackArray[i].tracks[j].time = myTimes.snapshotItem(k).innerHTML;} var trackMin = trackArray[i].tracks[j].time.split(/:/)[0]; var trackSec = trackArray[i].tracks[j].time.split(/:/)[1]; trackArray[i].tracks[j].time = 60*parseInt(trackMin)+parseInt(trackSec); if (isNaN(trackArray[i].tracks[j].time)) {trackArray[i].tracks[j].time = 0;} trackArray[i].tracks[j].totaltime = trackArray[i].tracks[j].time * parseInt(trackArray[i].tracks[j].count); trackRows[trackCount] = "<td Class='subjectCell' title=\""+j+", played "+commatize(trackArray[i].tracks[j].count) +" times, for "+mTimeStr(trackArray[i].tracks[j].totaltime)+"\"><A HREF="+trackArray[i].tracks[j].url+">"+i+" - "+j+"</A></td>"; timePlayed[trackCount] = trackArray[i].tracks[j].totaltime; trackCount++; } } statusArea.innerHTML = "<H2 class='heading'>Top tracks by time for "+chartDescrip[periodViewed]+"</H2><table>"; for (var q=0;q<trackCount;q++){ tstABC[q] = q; } var tstBCA = tstABC.sort(sortMyArr); var maxTime = timePlayed[tstBCA[0]]; for (var q=0;q<trackCount;q++) { var rowType = ""; if (1 == (q%2)) {rowType=" class=\"odd\"";} var barWid = parseInt(timePlayed[tstBCA[q]]*100/maxTime); if (barWid<20) {barWid = 20;} var minuPlay = commatize(parseInt(timePlayed[tstBCA[q]]/60)); newTable.innerHTML += "<tr"+rowType+"><td class=\"positionCell\">"+(q+1)+"</td>"+trackRows[tstBCA[q]] + "<TD class=\"chartbarCell\"><DIV Style=\"width:"+barWid+"%\" class=\"chartbar\"><span>"+minuPlay+"</span></TD></TR>\n"; } } function sortMyArr(a, b){ return( timePlayed[b] - timePlayed[a]); }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址