// ==UserScript==
// @name MusicBrainz: Import from iTunes
// @description Import releases from iTunes
// @version 2020.04.25.0
// @author -
// @namespace http://github.com/dufferzafar/Userscripts
//
// @include *://itunes.apple.com/*
// @include *://music.apple.com/*
// @run-at document-idle
// @grant GM_xmlhttpRequest
// @connect itunes.apple.com
//
// ==/UserScript==
//**************************************************************************//
/* global waitForKeyElements */
var myform = document.createElement("form");
var artist = '', album = '', year = 0, month = 0, day = 0, country = 'XW', type = 'album', discs = 0;
var m;
var left;
var product, buttons;
waitForKeyElements(".product-info", run);
function run() {
if (m = /^https?:\/\/(itunes|music).apple.com\/(?:([a-z]{2})\/)?album\/(?:[^\/]+\/)?(id)?([0-9]+)/.exec(document.location.href)) {
var lookup_url = 'itunes.apple.com';
country = m[2];
var id = m[4];
var url = document.location.protocol + "//" + lookup_url + "/lookup?id=" + id + "&entity=song&limit=200";
if (country) url = url + "&country=" + country;
GM.xmlHttpRequest ( {
method: 'GET',
url: url,
onload: callbackFunction
} );
}
}
function callbackFunction(responseDetails) {
myform.innerHTML = '';
let intervalId;
var r = JSON.parse(responseDetails.responseText);
for (var i = 0; i < r.results.length; i++) {
if (r.results[i].wrapperType === "collection") {
artist = r.results[i].artistName;
album = r.results[i].collectionName;
if (m = /(.*?) - (Single|EP)/.exec(r.results[i].collectionName)) {
album = m[1];
type = m[2];
}
if (m = /^([0-9]{4})-([0-9]{2})-([0-9]{2})/.exec(r.results[i].releaseDate)) {
year = m[1];
month = m[2];
day = m[3];
}
} else if (r.results[i].wrapperType === "track") {
var discno = r.results[i].discNumber - 1;
var trackno = r.results[i].trackNumber - 1;
discs = r.results[i].discCount;
var trackname = r.results[i].trackName;
if (r.results[i].trackCensoredName && trackname !== r.results[i].trackCensoredName) {
var str1 = r.results[i].trackCensoredName.substr(0, trackname.length);
var str2 = r.results[i].trackCensoredName.substr(trackname.length);
if (trackname === str1 && str2.match(/^ \(.*\)$/)) {
trackname = r.results[i].trackCensoredName;
}
}
// Fixing "trackname" and "trackCensoredName" differences
if (r.results[i].trackCensoredName && trackname !== r.results[i].trackCensoredName) {
trackname += r.results[i].trackCensoredName.substr(trackname.length);
}
add_field("mediums." + discno + ".track." + trackno + ".name", trackname);
add_field("mediums." + discno + ".track." + trackno + ".length", r.results[i].trackTimeMillis);
var artists = r.results[i].artistName.split(/[,&]/);
for (var j = 0; j < artists.length; j++) {
add_field("mediums." + discno + ".track." + trackno + ".artist_credit.names." + j + ".name", artists[j].trim());
var join_phrase = (j !== artists.length - 1) ? (j === artists.length - 2) ? " & " : ", " : "";
if (j !== artists.length - 1) {
add_field("mediums." + discno + ".track." + trackno + ".artist_credit.names." + j + ".join_phrase", join_phrase);
}
}
}
}
for (i = 0; i < discs; i++) {
add_field("mediums." + i + ".format", 'Digital Media');
}
add_field("name", album);
add_field("artist_credit.names.0.artist.name", artist);
add_field("packaging", 'None');
add_field("date.year", year);
add_field("date.month", month);
add_field("date.day", day);
add_field("country", country);
add_field("status", "official");
add_field("type", type);
add_field("edit_note", "Imported from: "+ document.location.href +
" using https://github.com/dufferzafar/Userscripts/blob/master/MB-Import-From-iTunes.user.js");
add_field("urls.0.link_type", "980");
add_field("urls.0.url", document.location.href);
// label
var copyright = document.getElementsByClassName('bottom-metadata')[0].getElementsByClassName('song-copyright')[0].innerText,
labels = copyright.replace(/℗\s*\d{4}/g, '').split(/\s*(?:\/)\s*/);
labels.forEach((label, x) => {
add_field("labels." + x + ".name", label.trim());
});
left = document.getElementById('web-navigation-container');
product = document.getElementsByClassName('product-info')[0];
buttons = document.createElement("div");
buttons.classList.add("button-content");
document.getElementsByClassName('bottom-metadata')[0].appendChild(buttons);
// Stylize our button
var btnsCSS = document.createElement("style");
btnsCSS.type = "text/css";
btnsCSS.innerHTML = '.artLink, .mbForm { display: inline-block; margin-top: 10px; } .mbForm { margin-inline-end: 8px; }';
document.body.appendChild(btnsCSS);
addArtworkLink();
addImportButton();
clearInterval(intervalId);
}
//////////////////////////////////////////////////////////////////////////////
function add_field (name, value) {
var field = document.createElement("input");
field.type = "hidden";
field.name = name;
field.value = value;
myform.appendChild(field);
}
function addArtworkLink() {
// Removing existing links
var elsArt = document.getElementsByClassName('artLink');
for (var i = 0 ; i < elsArt.length ; i++) {
elsArt[i].remove();
}
// Add a link to download artwork
var linkCSS = document.createElement("style");
linkCSS.type = "text/css";
linkCSS.innerHTML = ".artLink {float: right; margin-top: 10px;} .artLink button, .artLink a, .artLink button span.btn-text, .artLink a span.btn-text { -webkit-margin-end: 0 !important; margin-inline-end: 0 !important; }";
document.body.appendChild(linkCSS);
var divArtwork = product.getElementsByClassName('media-artwork-v2')[0],
imagePicture = divArtwork.getElementsByTagName('source')[1],
srcset = imagePicture.getAttribute('srcset');
var src = srcset.split(',')[0].slice(0, -3).replace(/(.*jpg) .*$/, '$1').replace(/(\/)(\d+x\d+).*(bb(\-\d+)?\.jpg)$/, '$19999x9999$3');
var artLinkP = document.createElement("div");
var artLink = document.createElement("a");
var artLinkSpan = document.createElement("span");
artLinkSpan.textContent = "Link to HD Artwork";
artLinkSpan.classList.add('btn-text');
artLink.setAttribute("href", src);
artLink.setAttribute("target", "_blank");
artLink.classList.add('web-add-to-library');
artLink.classList.add('add-to-library');
artLink.classList.add('not-in-library');
artLink.classList.add('round-button');
artLink.classList.add('typography-label');
artLink.classList.add('is-pill');
artLink.classList.add('typ-label');
artLink.addEventListener("click", function (event) { event.stopPropagation(); });
artLinkP.classList.add("artLink");
artLink.appendChild(artLinkSpan);
artLinkP.appendChild(artLink);
buttons.appendChild(artLinkP);
}
function addImportButton() {
myform.method="post";
myform.target = "blank";
myform.action = document.location.protocol + "//musicbrainz.org/release/add";
myform.acceptCharset = "UTF-8";
// Stylize our button
var btnCSS = document.createElement("style");
btnCSS.type = "text/css";
document.body.appendChild(btnCSS);
var mysubmit = document.createElement("input");
mysubmit.type = "submit";
mysubmit.value = "Add to MusicBrainz";
mysubmit.classList.add("mbBtn");
mysubmit.classList.add("play-button");
mysubmit.classList.add("action-button");
mysubmit.classList.add("typography-label-emphasized");
myform.appendChild(mysubmit);
var div = document.createElement("div");
div.classList.add("mbForm");
div.appendChild(myform);
buttons.appendChild(div);
}