Skip to content

Instantly share code, notes, and snippets.

@Faldrian
Last active January 2, 2016 14:48
Show Gist options
  • Save Faldrian/a7054d60675d06f4089f to your computer and use it in GitHub Desktop.
Save Faldrian/a7054d60675d06f4089f to your computer and use it in GitHub Desktop.
Greasemonkey-Script to display all CC albums of all pages for the currently displayed tag
// ==UserScript==
// @name Bandcamp CC Tag-Overview
// @namespace faldrian
// @description Loads all pages inline and hides albums licensed as "all rights reserved"
// @include http://bandcamp.com/tag/*
// @include https://bandcamp.com/tag/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @grant GM_xmlhttpRequest
// @version 1.1
// ==/UserScript==
// holds all pending requests
var stack = [];
// push pages to load on the stack...
function addPageRequest(urlParam) {
var url = urlParam;
stack.push(function() {
return new Promise(function(resolve, reject) {
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function (data) {
try {
// get all items and insert them to the page
var content = data.responseText.match(/<ul class="item_list">(.|[\r\n])*?<\/ul>/mgi)[0];
var itemList = $(content);
$('div.results').append(itemList);
// add licenses to all children
$(itemList).find('li.item').each(function(index, newElement) {
addItemRequest(newElement);
});
resolve();
} catch (e) {
resolve();
}
},
onerror: function() {
console.error("Error!");
resolve();
},
ontimeout: function() {
console.error("Timeout, adding again!");
addPageRequest(url);
resolve();
}
});
});
});
}
// push items to load on the stack...
function addItemRequest(elementParam) {
var element = elementParam;
stack.push(function() {
return new Promise(function(resolve, reject) {
// beautifix: remove "end"-CSS-Class, it destroys our layout.
// also: Add loading-state for visual indication
$(element).removeClass('end').addClass('state_loading');
GM_xmlhttpRequest({
method: "GET",
url: $(element).find('a').attr('href'),
onload: function(data) {
// Get the license from the loaded album page
try {
// check if page was "offline"
if (data.responseText.indexOf("We're offline briefly for maintenance") !== -1) {
// just try again, they can't be offline, they are just badly managed.
addItemRequest(element);
resolve();
return;
}
var licenseStr = data.responseText.match(/<div id="license"(.|[\r\n])*?<\/div>/mgi)[0];
if (licenseStr.indexOf('all rights reserved') !== -1) {
// remove the item, it is not CC!
$(element).remove();
} else {
// add license
licenseStr = licenseStr.replace('id="license"', "");
$(element).find('a').append(licenseStr);
// sanatize background-image
var artContainer = $(element).find('.tralbum-art-container');
var onclickaction = artContainer.attr('onclick');
artContainer.css('background-image', onclickaction.substring(8, onclickaction.length - 1));
// remove loading info
$(element).removeClass('state_loading');
}
resolve();
} catch (e) {
console.error("Error fetching license: ", e, data.responseText);
resolve();
}
},
onerror: function() {
console.error("Error!");
resolve();
},
ontimeout: function() {
console.error("Timeout, adding again!");
addItemRequest(element);
resolve();
}
});
});
});
}
function processQueueItem() {
var item = stack.pop();
if (item) {
item().then(function(data) {
// update status
$('.status_floater').html("Remaining: " + stack.length);
// and process the next
processQueueItem();
});
} else {
$('.status_floater').remove();
}
}
function crawlPages() {
// Add status item
$('body').append('<div class="status_floater">Loading...</div>');
// crawl all pages
$('.pagelist a').each(function(index, element) {
addPageRequest($(element).attr('href'));
});
// hide initial items if not CC
$('li.item').each(function(index, element) {
addItemRequest(element);
});
// Start Execution (5 Worker)
for(var i = 0; i<5; i++) {
processQueueItem();
}
}
// Start this!
$(function() {
// Insert Style-Mods
var style = 'a:visited {color: #aaa !important;}' +
' .results .item:nth-child(5n) {margin-right: 0px !important;}' +
' .tags.one_tag .results_area .item {height: auto !important;}' +
' .state_loading {background-color: #FEE1AD;}' +
' .state_loading.state_retry {background-color: #FEBEAD}' +
' .status_floater {position: fixed; top: 0px; left: 0px; z-index: 1000; background-color: white; padding: 0.5em 1em;}';
var styleElement = document.createElement('style');
styleElement.appendChild(document.createTextNode(style));
(document.body || document.head || document.documentElement).appendChild(styleElement);
if(window.confirm("Bandcamp detected! Start crawling?")) {
crawlPages();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment