All pastes #2083294 Raw Edit

batchworkadd

public text v1 · immutable
#2083294 ·published 2011-09-27 17:45 UTC
rendered paste body
// ==UserScript==
// @name        MusicBrainz: Batch-add "performance of" relationships
// @version     2011-09-16~1
// @author      bitmap + some code from nikki
// @include     http://musicbrainz.org/artist/*/recordings*
// @include     http://test.musicbrainz.org/artist/*/recordings*
// ==/UserScript==
//**************************************************************************//

var content = document.getElementById("content"),
    forms = document.getElementsByTagName("form"),
    form = forms[forms.length-1], trs = [], rows = [],
    checked = iid = null, current = 0,
    button1 = createButton("Query relationships of checked recordings"),
    button2 = createButton("Go"),
    button3 = createButton("Go"),
    input1 = document.createElement("input"),
    input2 = document.createElement("input"),
    mbid_patt=/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/;

function get_rows() {
    rows = [];
    trs = document.getElementsByTagName("tr");
    for (var i = 0; i < trs.length; i++) {
        var tr = trs[i], attr = tr.getAttribute("xmlns:rec");
        if (!attr) continue;
        var mbid = attr.match(mbid_patt);
        var tds = tr.getElementsByTagName("td"),
            inp = tds[0].getElementsByTagName("input")[0];
        rows.push([mbid, inp, tds[1]]);
    }
}

get_rows();

var table = document.createElement("table");
table.innerHTML = '<tr><td></td><td><label><input type="checkbox"/>&nbsp;remove recordings with performance ARs</label></td></tr><tr><td></td><td></td></tr><tr><td>\
</td><td></td></tr><tr><td colspan="2"><label><input type="checkbox"/>&nbsp;cover</label>\
&nbsp;<label><input type="checkbox"/>&nbsp;live</label></td></tr>';
var trs = table.getElementsByTagName("tr");
trs[0].getElementsByTagName("td")[0].appendChild(button1);
var removeinput = trs[0].getElementsByTagName("td")[1].getElementsByTagName("input")[0];
trs[1].getElementsByTagName("td")[0].textContent = "Relate checked recordings to new work with this title:";
trs[1].getElementsByTagName("td")[1].appendChild(input1);
trs[1].getElementsByTagName("td")[1].appendChild(button2);
trs[2].getElementsByTagName("td")[0].textContent = "Relate checked recordings to existing work (URL/MBID):";
trs[2].getElementsByTagName("td")[1].appendChild(input2);
trs[2].getElementsByTagName("td")[1].appendChild(button3);
var foo = trs[3].getElementsByTagName("input"), coverinput = foo[0], liveinput = foo[1];
content.insertBefore(table, form);

function createButton(text) {
    var button = document.createElement("button");
    button.textContent = text;
    styleButton(button);
    return button;
}

function styleButton(button) {
    button.style.color = "#565656";
    button.style.backgroundColor = "#F0F0F0";
    button.style.border = "1px solid #D0D0D0";
    button.style.borderTop = "1px solid #EAEAEA";
    button.style.borderLeft = "1px solid #EAEAEA";
}

button1.addEventListener("click", start_queries, false);

button2.addEventListener("click", function() {
    if (!input1.value) {
        alert("Please enter a title.");
        return;
    }
    add_work();
}, false);

button3.addEventListener("click", function() {
    var m = input2.value.match(mbid_patt);
    if (!m) {
        alert("Please enter a valid MBID.");
        return;
    }
    relate_to_work(m[0]);
}, false);

function start_queries() {
    checked = get_checked();
    if (checked.length == 0)
        return;
    current = 0;
    iid = window.setInterval(loop, 1000);
    button1.removeEventListener("click", start_queries, false);
    button1.addEventListener("click", cancel_queries, false);
    button1.textContent = "Cancel queries";
};

function cancel_queries() {
    window.clearInterval(iid);
    button1.removeEventListener("click", cancel_queries, false);
    button1.addEventListener("click", start_queries, false);
    button1.textContent = "Query relationships of checked recordings";
    get_rows();
};

function get_checked() {
    var elems = [];
    for (var i = 0; i < rows.length; i++)
        if (rows[i][1].checked) elems.push(rows[i]);
    return elems;
}

function loop() {
    var tr = checked[current];
    query_recording(tr);
    current++;
    if (current == checked.length)
        cancel_queries();
}

function query_recording(row) {
    wsurl = "http://musicbrainz.org/ws/2/recording/"+row[0]+"?inc=work-rels",
    a = row[2].getElementsByTagName("a")[0];
    get_(wsurl, row[2]);
    a.style.color = "purple";
}

function add_work() {
    var data = 'edit-work.name=' + input1.value;
    var w_url = 'http://musicbrainz.org/work/create';
    post(w_url, data, function (doc) {
        var m = doc.match(/\/work\/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/);
        w_mbid = m[1];
        relate_to_work(w_mbid);
    });
}

function relate_to_work(w_mbid) {
    var checked = get_checked();
    for (var i = 0; i < checked.length; i++) {
        var row = checked[i];
        rel_url = 'http://musicbrainz.org/edit/relationship/create?type1=work&entity1='+w_mbid+'&type0=recording&entity0='+row[0],
        data = 'ar.as_auto_editor=1&ar.link_type_id=278&type1=work&entity1='+w_mbid+'&type0=recording&entity0='+row[0];
        console.log(liveinput.checked);
        if (coverinput.checked) data += "ar.attrs.cover=1";
        if (liveinput.checked) data += "&ar.attrs.live=1";
        post(rel_url, data, function(r) {
            return function() {query_recording(r);};
        }(row));
    }
}

function success1(doc, td) {
    var rels = doc.getElementsByTagName("relation"),
        children = td.childNodes;
    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (child.nodeName == "span" && child.className != "comment")
            td.removeChild(child);
    }
    for (var i = 0; i < rels.length; i++) {
        var rel = rels[i];
        if (!rel.attributes[0].value.match(/performance/))
            continue;
        var nodes = rel.childNodes,
            wmbid = wtitle = cover = live = "";
        for (var j = 0; j < nodes.length; j++) {
            var node = nodes[j];
            if (node.nodeName == "target")
                wmbid = node.childNodes[0].nodeValue;
            if (node.nodeName == "work")
                wtitle=node.getElementsByTagName("title")[0].childNodes[0].nodeValue;
            if (node.nodeName == "attribute-list") {
                for (var k = 0; k < node.childNodes.length; k++) {
                    var child = node.childNodes[k], value = child.childNodes[0].nodeValue;
                    if (value == "cover") cover = "cover ";
                    if (value == "live") live = "live ";
                }
            }
        }
        var wurl = "/work/" + wmbid,
            txt = "&bull;&nbsp;"+live+cover+"performance of <a href=\""+wurl+"\">"+wtitle+"</a>",
            span = document.createElement("span");
        span.innerHTML = txt;
        td.innerHTML += "<br/>";
        td.appendChild(span);
    }
}

function success2(doc, td) {
    var rels = doc.getElementsByTagName("relation");
    for (var i = 0; i < rels.length; i++) {
        var rel = rels[i];
        if (rel.attributes[0].value.match(/performance/)) {
            td.parentNode.parentNode.removeChild(td.parentNode);
        }
    }
}

function get_(url, td) {
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200)
            if (!removeinput.checked)
                success1(req.responseXML, td);
            else success2(req.responseXML, td);
    }
    req.send(null);
}

function post(url, data, success) {
    var req = new XMLHttpRequest();
    req.open("POST", url, true);
    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200)
            success(req.responseText);
    }
    req.send(data);
}