// ==UserScript== // @name GM Last.fm Scrobbler for Bandcamp // @namespace Rimantas Galvonas // @description Last.fm scrobbler for Bandcamp, based on GM Scrobbler for Pakartot.lt script // @include *.bandcamp.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js // @require https://greasyfork.org/scripts/130-portable-md5-function/code/Portable%20MD5%20Function.js?version=10066 // @version 1.17 // @grant none // @downloadURL https://update.greasyfork.icu/scripts/12935/GM%20Lastfm%20Scrobbler%20for%20Bandcamp.user.js // @updateURL https://update.greasyfork.icu/scripts/12935/GM%20Lastfm%20Scrobbler%20for%20Bandcamp.meta.js // ==/UserScript== jQuery("#propOpenWrapper").append("
"); started = false; playingflag = false; scrobbledflag = false; scrobblingenabled = ''; elapsed = 0; startedplaying = ''; checkScrobblingCookie(); tick(); function getUrlParameter(sParam) { var sPageURL = window.location.search.substring(1); var sURLVariables = sPageURL.split('&'); for (var i = 0; i < sURLVariables.length; i++) { var sParameterName = sURLVariables[i].split('='); if (sParameterName[0] == sParam) { return sParameterName[1]; } } } function authentication() { if (!$.cookie('bandcampscrobblerlastfmkey') && !$.cookie('gettingsessionkey')) { $.cookie('gettingsessionkey', 'true'); window.location.replace("http://www.last.fm/api/auth/?api_key=208364636e71f518eac93a4580f7ca29&cb=" + window.location.href); } if (!$.cookie('bandcampscrobblerlastfmkey') && $.cookie('gettingsessionkey')) { token = getUrlParameter('token'); signing = hex_md5('api_key208364636e71f518eac93a4580f7ca29methodauth.getSessiontoken' + token + '995a6768f1c7d5d5a1242cc11c6ea8ce') + ''; $.get("https://ws.audioscrobbler.com/2.0/?method=auth.getSession&token=" + token + "&api_key=208364636e71f518eac93a4580f7ca29&api_sig=" + signing, function(data) { $xml = $(data) key = $xml.find('key').text(); $.cookie('bandcampscrobblerlastfmkey', key, { expires: 10000, path: '/', domain: '.bandcamp.com' }); $.removeCookie('gettingsessionkey'); }); } } jQuery("#togglescrobbling").click(function() { if (scrobblingenabled == 1) { toggleScrobbling(0); } else { toggleScrobbling(1); } }); jQuery(".jp-pause").click(function() { playingflag = false; }); function startthething() { info = gettrackdata(); console.log(info["artist"]); console.log(info["track"]); console.log(info["duration"]); updatenowplaying(); startedplaying = Math.round(+new Date() / 1000); } function toggleScrobbling(bool) { if (bool == 1) { jQuery("#togglescrobbling").css('background-color', 'rgb(43, 177, 43)'); } else { jQuery("#togglescrobbling").css('background-color', 'rgb(180, 180, 180)'); } scrobblingenabled = bool; $.cookie('bandcampscrobblerenabled', bool, { expires: 10000, path: '/', domain: '.bandcamp.com' }); } function checkScrobblingCookie() { if (!$.cookie('bandcampscrobblerenabled')) { $.cookie('bandcampscrobblerenabled', 1, { expires: 10000, path: '/', domain: '.bandcamp.com' }); toggleScrobbling(1); return 1; } else { toggleScrobbling($.cookie('bandcampscrobblerenabled')); return $.cookie('bandcampscrobblerenabled'); } } function gettrackdata() { track = jQuery('.track_info').find('span .title').text().trim(); if (track.length < 1) { track = jQuery('h2.trackTitle').first().text().trim(); } artist = jQuery('span[itemprop="byArtist"]').text().trim(); if (artist == '') { artist = jQuery('#name-section h3 span:last-of-type a').text().trim() } duration = jQuery('.time_total').text(); tt = duration.split(":"); sec = tt[0] * 60 + tt[1] * 1; result = []; result["track"] = track; result["artist"] = artist; result["duration"] = sec; return result; } function updatenowplaying() { signing = hex_md5('api_key208364636e71f518eac93a4580f7ca29artist' + info["artist"] + 'methodtrack.updateNowPlayingsk' + $.cookie('bandcampscrobblerlastfmkey') + 'track' + info["track"] + '995a6768f1c7d5d5a1242cc11c6ea8ce') + ''; $.ajax({ type: 'POST', url: 'https://ws.audioscrobbler.com/2.0/', data: 'method=track.updateNowPlaying' + '&artist=' + info["artist"] + '&track=' + info["track"] + '&api_key=208364636e71f518eac93a4580f7ca29' + '&sk=' + $.cookie('bandcampscrobblerlastfmkey') + '&api_sig=' + signing, success: function(data) { //console.log("Now playing updated."); }, error: function(code, message) { console.log("Now playing update failed."); //console.log(code); xmlDoc = jQuery.parseXML(code['responseText']); $xml = $(xmlDoc); errorcode = $xml.find('error').attr('code'); console.log(errorcode); if (errorcode == 9) { $.removeCookie('bandcampscrobblerlastfmkey', { path: '/', domain: '.bandcamp.com' }); authentication(); } } }); } function scrobble() { signing = hex_md5('api_key208364636e71f518eac93a4580f7ca29artist' + info["artist"] + 'methodtrack.scrobblesk' + $.cookie('bandcampscrobblerlastfmkey') + 'timestamp' + startedplaying + 'track' + info["track"] + '995a6768f1c7d5d5a1242cc11c6ea8ce') + ''; $.ajax({ type: 'POST', url: 'https://ws.audioscrobbler.com/2.0/', data: 'method=track.scrobble' + '&artist=' + info["artist"] + '&track=' + info["track"] + '×tamp=' + startedplaying + '&api_key=208364636e71f518eac93a4580f7ca29' + '&sk=' + $.cookie('bandcampscrobblerlastfmkey') + '&api_sig=' + signing, success: function(data) { console.log("Scrobbled."); jQuery('#togglescrobbling').html('✔').attr('title', 'Scrobbled'); }, error: function(code, message) { console.log("Scrobbling failed."); jQuery('#togglescrobbling').html('✗').attr('title', 'Scrobbling failed'); } }); } function tick() { window.setInterval(function() { if (started == false && jQuery('.playbutton').hasClass('playing')) { startthething(); started = true; } if (jQuery('.playbutton').hasClass('playing')) { playingflag = true; } else { playingflag = false; } if (playingflag == true) { elapsed++; } if (info["duration"] > 30 && (elapsed > (info['duration'] / 2) || elapsed > 240) && scrobbledflag == false && scrobblingenabled == 1) { scrobble(); scrobbledflag = true; } info_last = gettrackdata(); if (info_last["track"] != info["track"] || info_last["artist"] != info["artist"] || info_last["duration"] != info["duration"]) { info = info_last; scrobbledflag = false; jQuery('#togglescrobbling').html('').removeAttr('title'); elapsed = 0; updatenowplaying(); startedplaying = Math.round(+new Date() / 1000); } }, 1000); }