By snyde
Has 9 other scripts.
// ==UserScript==
// @name Last.fm - Highlight Same Artists - May 2008 beta2
// @namespace
// @description Highlights artists that you listen to on other users' profiles.
// @include http://www.last.fm/user/*/charts*
// @include http://www.lastfm.*/user/*/charts*
// @include http://www.last.fm/group/*/charts*
// @include http://www.lastfm.*/group/*/charts*
// @include http://www.last.fm/music/+charts/*
// @include http://www.last.fm/music/*/+similar
// ==/UserScript==
// splitD[x] is location of start of the range highlighted with the appropriate styles[x] element
var splitD = new Array();
var styles = new Array();
var sColour = new Array();
splitD[0] = 1 ; sColour[0] = "magenta"; styles[0] = "color: magenta;"; // "font-weight: bold;"; //
splitD[1] = 11 ; sColour[1] = "red"; styles[1] = "color: red;"; // "font-weight: bold; text-decoration: underline;"; //
splitD[2] = 26 ; sColour[2] = "orange"; styles[2] = "color: orange;"; // "font-style: italic; font-weight: bold;"; //
splitD[3] = 51 ; sColour[3] = "green"; styles[3] = "color: green;"; // "font-style: italic; font-weight: bold; text-decoration: underline;"; //
splitD[4] = 101 ;sColour[4] = "blue"; styles[4] = "color: blue;"; // "font-style: italic;"; //
splitD[5] = 251 ;sColour[5] = "purple"; styles[5] = "color: purple;"; // "font-style: italic; text-decoration: underline;"; //
var nullStyle = "color: #666; font-weight: normal; text-decoration: none; font-style: none;";
var cutoffCountDefault = 1001; // Maximum match count
var miniCount = 1; // Minimum tracks played to use artist
var hideOthers = 0; // Hide artists not on your list (1=yes, 0=no)
var useColours = 2; // use the colour settings (1) or the style settings (2) or both (3)
var wantUpdShwn = 1; // show updates on panel
// chartType: Which chart to use for data. Options: "overall" "3month" "6month" "12month"
var chartType = "3month";
// Don't change variables below here
// ---------------------------------
var chartDescrip = new Object();
chartDescrip["overall"] = "overall";
chartDescrip["12month"] = "1 year";
chartDescrip["6month"] = "6 month";
chartDescrip["3month"] = "3 month";
chartDescrip["weekly"] = "1 week";
var myPan;
var panelHead = "<div class=\"h\"><h2>Highlight Same Artists</h2><a href=\"javascript:;\" class=\"tog collapseTog\" title=\"Collapse Panel\" onclick=\"return collapseBox('hiLightPan', this);\" onfocus=\"blur();\"></a></div><div class=\"c\"><div id=myPanCont>";
var panelTail = "</div></div><div class=\"f\"><div id=myPanTailer></div><span class=\"iesucks\"> </span></div>";
var currentChart;
var username;
var artiststr;
var sepstr = "@!#!@";
var lastHide = 0;
var numStyles, cutoffCount, numArtists;
var staticText, theURL;
var splitE;
/* History */
// snyde1: 27-Apr-2007 Modified for new Last.fm
// snyde1: 03-Apr-2007 Modified Greasemonkey script and TopTrax to create this version
// 09-Apr-2007 Modified to remove hardcoded number of splits
// 06-Jul-2007 Add panel; hide/show toggle support for group charts
// PROBLEM: with special characters, but do we want to escape them?
// 15-Nov-2007 Fix problem with quilts thanks to Kuge and teganblue
// 07-May-2008 joint version; colour and style
// 11-May-2008 modify method of updates for GM after changing chart
/* SCRIPT */
function xpath(query) {
return document.evaluate(query, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}
function toggleHideArtist () {
if (hideOthers == 0) { hideOthers = 1; } else { hideOthers = 0; }
if (! navigator.userAgent.match(/Opera/)) {GM_setValue("hideOthers",hideOthers); }
doTheChart();
}
function fixstring(str) {
str = str.replace(/"/g,'"');
return(str);
}
function initPanel () {
if (location.href.match(/http:\/\/[^\/]*\/user/i)) {
var oldPanel = document.getElementById("shoutboxPanel");
if (!oldPanel) {
oldPanel = document.getElementById("userfriends");
if (!oldPanel) {
oldPanel = document.getElementById("userneighbours");
}
}
} else if (location.href.match(/http:\/\/[^\/]*\/group/i)) {
var oldPanel = document.getElementById("avatarPanel");
} else if (location.href.match(/http:\/\/[^\/]*\/music/i)) {
var oldPanel = document.getElementById("simpanel");
}
if (oldPanel){
var newPanel = document.createElement("div");
newPanel.setAttribute("class", "lastPanel");
newPanel.setAttribute("id", "hiLightPan");
newPanel.setAttribute("style", "width: 100%;");
if (location.href.match(/http:\/\/[^\/]*\/group/i)) {
oldPanel.parentNode.insertBefore(newPanel,oldPanel.nextSibling);
} else {
oldPanel.parentNode.insertBefore(newPanel,oldPanel);
}
myPan = document.getElementById("hiLightPan");
}
if (myPan){
theStuff = panelHead;
theStuff += "Loading information.";
theStuff += panelTail;
myPan.innerHTML = theStuff;
}
}
function updatePanel(thisIsTheText) {
var tempPanelText = document.getElementById("myPanCont");
if (tempPanelText) { tempPanelText.innerHTML = thisIsTheText; }
}
function updateTail(thisIsTheText) {
var tempPanelText = document.getElementById("myPanTailer");
if (tempPanelText) { tempPanelText.innerHTML = thisIsTheText; }
}
function getArt(chartUsed){
chartType = chartUsed;
doGetArt();
}
function doGetArt() {
updateTail("<div align=center>In progress ...</div>");
updatePanel("Loading artists from your "+chartDescrip[chartType]+" chart.");
currentChart = chartType;
cutoffCount = cutoffCountDefault; var newCutoff = -1;
splitE = new Array();
for(var i=0; i<splitD.length; i++) { splitE[i]=splitD[i]; }
var xmlhttp=new XMLHttpRequest();
theURL = "/user/" + username + "/charts/?charttype="+chartType+"&subtype=artist";
xmlhttp.open("GET", theURL, false);
xmlhttp.send(null);
if (xmlhttp.readyState!=4) { return; }
var xmlText = xmlhttp.responseText;
var regexp = /\s&\s/g;
xmlText = xmlText.replace(regexp, "foo");
regexp = /(<td[^>]*class="subject")[^>]*>/g;
xmlText = xmlText.replace(regexp, "$1>");
if (!xmlText) {
return;
}
if (xmlText.match(/class="barChart artistChart"/)) {
xmlText = xmlText.split(/class="barChart artistChart"/)[1];
} else {
xmlText = xmlText.split(/class="barChart chartWithQuilt artistChart"/)[1];
}
var XMLartists = xmlText.split("<tr>");
var regxp = /<A HREF=[^>]*>([^<]*)<\/A>/i;
var cntxp = /<td class="quantifier">[^<]*<div[^<]*<span>([^<]*)<\/span>/i;
artiststr = new Array();
var artists = new Array(); numArtists = XMLartists.length;
if (cutoffCount > numArtists) { cutoffCount = numArtists; }
staticText = "Using "+(cutoffCount-1)+" artists from your "+chartDescrip[chartType]+" chart. (Total number available "+(numArtists-1)+")";
updatePanel(staticText);
for(var kount=1; kount < splitE.length; kount++) {
if (splitE[kount] > cutoffCount) { splitE[kount] = cutoffCount; }
}
kount=splitE.length;
splitE[kount] = cutoffCount;
numStyles = styles.length;
for(var kount=0; kount < styles.length; kount++) {
if (splitE[kount] >= cutoffCount) {
numStyles = kount; break;
}
}
for(var kount=0; kount < styles.length; kount++) {
artiststr[kount] = sepstr;
for (i=splitE[kount]; i<splitE[kount+1]; i++) {
var matches = regxp.exec(XMLartists[i]);
var playCount = cntxp.exec(XMLartists[i])[1];
if (playCount < miniCount) {
if (newCutoff < 0) { newCutoff = i; cutoffCount = i; }
}
if ((matches != null) && (newCutoff < 0)) {
artists[i] = fixstring(matches[1]);
artiststr[kount] = artiststr[kount] + artists[i] + sepstr;
}
}
}
doTheChart();
}
function doTheChart() {
updateTail("<div align=center>In progress ...</div>");
var testString = "";
var countRange = new Array();
if (location.href.match(/music\/\+charts\/.*artist/)) {
var artLinks = xpath("//table[@class=\"barChart\"][1]//td[@class='subject']/span/a");
} else {
var quiltTest = xpath("//table[@class=\"barChart chartWithQuilt artistChart\"]");
if (quiltTest.snapshotLength < 1) {
var artLinks = xpath("//table[@class=\"barChart artistChart\"][1]//td[@class='subject']/span/a");
} else {
var artLinks = xpath("//table[@class=\"barChart chartWithQuilt artistChart\"][1]//td[@class='subject']/span/a");
}
}
// var artLinks = xpath("//table[@class=\"barChart artistChart\"][1]//td[@class='subject']/span/a");
for(var kount=0; kount < splitE.length; kount++) { countRange[kount] = 0;}
for (var i = 0; i < artLinks.snapshotLength; i++) {
var thisChange = 0;
var cur = artLinks.snapshotItem(i);
var curArtist = cur.innerHTML;
curArtist = curArtist.replace(/<font color=[^>]*>/ig,"");
curArtist = curArtist.replace(/<\/font>/ig,"");
if (hideOthers == 0) {
if (lastHide == 1) {
cur.parentNode.parentNode.parentNode.setAttribute("style","display:table-row;");
}
cur.setAttribute("style", nullStyle);
cur.innerHTML = curArtist;
}
testString = sepstr + curArtist + sepstr;
for(var kount=0; kount < numStyles; kount++) {
if (artiststr[kount].indexOf(testString) != -1) {
if (hideOthers == 1) {
cur.parentNode.parentNode.parentNode.setAttribute("style","display:table-row;");
}
if ((useColours & 2) != 0) {
cur.setAttribute("style", styles[kount]);
}
if ((useColours & 1) != 0) {
cur.innerHTML = "<font color="+sColour[kount]+">"+curArtist+"</font>";
}
(countRange[kount])++;
thisChange = 1;
break;
}
}
if (thisChange == 1) {
// do updates during scan
if (wantUpdShwn == 1) {
var mytext = staticText+"<br>Current counts: ";
for (var j=0; j<styles.length; j++) {
if (j != 0) {mytext += " / ";}
if ((useColours & 2) != 0) {mytext += "<span style=\""+styles[j]+" font-size: 12;\">";}
if ((useColours & 1) != 0) {mytext += "<font color=\""+sColour[j]+"\">";}
mytext += countRange[j]+"";
if ((useColours & 1) != 0) {mytext += "</font>";}
if ((useColours & 2) != 0) {mytext += "</span>";}
}
updatePanel(mytext);
}
} else {
if (hideOthers == 1) {
cur.parentNode.parentNode.parentNode.setAttribute("style","display:none;");
}
}
}
var textToEnter = "This summary used "+(cutoffCount-1)+" artists from";
if (cutoffCount < numArtists){ textToEnter += " the "+(numArtists-1)+" on "; }
textToEnter += " your <a href="+theURL+">"+chartDescrip[currentChart]+"</a> chart, and "+artLinks.snapshotLength+" artists on this page. ";
if (miniCount > 1) { textToEnter += "(Minimum playcount used for your artists is "+miniCount+".)"; }
if (navigator.userAgent.match(/Opera/)) {
textToEnter += "<br> You can redo the comparison with one of the following charts: <br><div align=center><div align=center> <a name=1wk onclick=\"getArt(\'weekly\')\">week</a> <a name=3mo onclick=\"getArt(\'3month\')\">3 months</a> <a name=6mo onclick=\"getArt(\'6month\')\">6 months</a> <a name=yr1 onclick=\"getArt(\'12month\')\">1 year</a> <a name=overall onclick=\"getArt(\'overall\')\">overall</a></div></p>";
if (hideOthers == 0) {
textToEnter += "<div align=center><a name=ToggleHide onclick=\"toggleHideArtist()\">Hide non-matching artists</a></div><p>";
} else {
textToEnter += "<div align=center><a name=ToggleHide onclick=\"toggleHideArtist()\">Show non-matching artists</a></div><p>";
}
} else {
textToEnter += "<br> See the GreaseMonkey menu for options.<p>";
}
textToEnter += "<hr><p>The styles used and matches counted on this page are as follows:";
textToEnter += "<p><table class=\"barChart artistChart\" width=\"100%\"><tr><td align=left>Artist style</td><td align=right>Count</td></tr>";
var allFound = 0;
for (var i=0; i<styles.length; i++){
allFound = allFound+countRange[i];
var theWord = " next ";
if (i == 0) {theWord = " top ";}
var thePref = ""; var theSuff ="";
if ((useColours & 2) != 0) {
thePref = "<span style=\""+styles[i]+"\">"; theSuff = "</span>";
}
if ((useColours & 1) != 0) {
thePref = thePref + "<font color=\""+sColour[i]+"\">"; theSuff = "</font>"+theSuff;
}
if (splitE[i+1] < cutoffCount) {
textToEnter += "<tr><td align=left>"+thePref+"Your"+theWord+(splitE[i+1]-splitE[i])+theSuff;
textToEnter += "</td><td align=right>"+countRange[i]+"</td></tr>";
} else {
textToEnter += "<tr><td align=left>"+thePref+"Your"+theWord+(cutoffCount-splitE[i])+theSuff;
textToEnter += "</td><td align=right>"+countRange[i]+"</td></tr>";
break;
}
}
var hdnTxt = ""; if (hideOthers == 1) { hdnTxt=" (hidden)"; }
textToEnter += "<tr><td align=left><span style=\""+nullStyle+"\">Not yours"+hdnTxt+"</span></td><td align=right> "+(artLinks.snapshotLength-allFound)+"</td></tr></table><p>";
updatePanel(textToEnter);
if (location.href.match(/http:\/\/[^\/]*\/user/i)) {
var userRegexp = /\/user\/([^\/]*)[$\/]/i;
var thisUser = userRegexp.exec(location.href)[1];
var xmlhttp=new XMLHttpRequest();
var theURL = "/user/" + thisUser + "/tasteomatic/";
xmlhttp.open("GET", theURL, false);
xmlhttp.send(null);
var textName = xmlhttp.responseText;
var tomRegexp = /<div class="Reading">([^<]*)<\/div>/i;
textName = textName.match(tomRegexp)[1];
textToEnter += "<hr><div align=center>Taste-O-Meter rating:<br>\""+textName+"\"</div>";
}
updatePanel(textToEnter);
updateTail("<div align=center>You have "+allFound+" matches.</div>");
lastHide = hideOthers;
}
(function() {
var usernameLink = xpath("//a[@id='profileImage']");
if (usernameLink.snapshotLength > 0) {
username = usernameLink.snapshotItem(0).href;
username = username.match(/user\/([^\/]*)\//)[1];
} else {
return;
}
if (location.href.match(/music\/\+charts\/.*artist/)) {
var links = xpath("//table[@class=\"barChart\"][1]//td[@class='subject']/span/a");
} else {
var quiltTest = xpath("//table[@class=\"barChart chartWithQuilt artistChart\"]");
if (quiltTest.snapshotLength < 1) {
var links = xpath("//table[@class=\"barChart artistChart\"][1]//td[@class='subject']/span/a");
} else {
var links = xpath("//table[@class=\"barChart chartWithQuilt artistChart\"][1]//td[@class='subject']/span/a");
}
}
if (links.snapshotLength < 1) { return; }
// var re2 = new RegExp(username, "i"); // Is it my page or non-artist?
// if (location.href.match(re2)) { return; }
if (location.href.match(/subtype=(?:album|track)/)) { return; }
if (location.href.match(/charttype=recenttracks/)) { return; }
if (!navigator.userAgent.match(/Opera/)) {
chartType = GM_getValue("chartType", chartType);
GM_registerMenuCommand("Highlight Artist: Select chart", promptForChart);
// miniCount = GM_getValue("miniCount", miniCount);
// GM_registerMenuCommand("Highlight Artist: Minimum count", promptForMiniCount);
hideOthers = GM_getValue("hideOthers", hideOthers);
GM_registerMenuCommand("Highlight Artist: Toggle hide", toggleHideArtist);
}
initPanel();
if (!chartType) {chartType= "overall";}
doGetArt();
})();
// Greasemonkey support
function getMiniCount() {
return GM_getValue("miniCount", 1);
}
function promptForMiniCount() {
GM_setValue("miniCount", prompt("What is the minimum number of plays to consider?", getMiniCount()));
document.location.reload();
}
function getForChart() {
return GM_getValue("chartType", "overall");
}
function promptForChart() {
GM_setValue("chartType", prompt("What chart do you want to use? (overall, weekly, 12month, 6month, 3month)", getForChart()));
if (!chartDescrip[GM_getValue("chartType")]){
GM_setValue("chartType", "overall");
chartType = "overall";
}
chartType=GM_getValue("chartType");
doGetArt();
chartType=GM_getValue("chartType");
}