This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/444988/1268106/music-helper.js
// ==UserScript==
// @name music-helper
// @contributor Slack06/SavageCore/tomorrow505
// @description This script provides integration with online description generator YADG (http://yadg.cc)
// @license https://github.com/SavageCore/yadg-pth-userscript/blob/master/LICENSE
// @version v1.3
// @namespace yadg
// @grant GM_xmlhttpRequest
// @require https://code.jquery.com/jquery-1.12.4.js
// @include http*://*redacted.ch/upload.php*
// @include http*://*redacted.ch/requests.php*
// @include http*://*redacted.ch/torrents.php*
// @include http*://*orpheus.network/upload.php*
// @include http*://*orpheus.network/requests.php*
// @include http*://*orpheus.network/torrents.php*
// @include http*://*dicmusic.com/upload.php*
// @include http*://*dicmusic.com/requests.php*
// @include http*://*dicmusic.com/torrents.php*
// @match https://*open.cd/plugin_upload.php*
// @match https://*.open.cd/plugin_upload.php*
// ==/UserScript==
let worker_ok = location.href.split('#seperator#')[0].match(/lemonhd|redacted|orpheus|notwhat|dicmusic|waffles|d3si/i) ? true: false;
var JSandbox = (function(self) {
var undef_type = "undefined",
doc = self.document,
Worker = self.Worker;
if (typeof Worker === undef_type) {
return;
}
var $eval = "eval",
$exec = "exec",
$load = "load",
$requests = "requests",
$input = "input",
$terminate = "terminate",
$data = "data",
$callback = "callback",
$onerror = "onerror",
$worker = "worker",
$onresponse = "onresponse",
$prototype = "prototype",
$call = "call",
str_type = "string",
fun_type = "function",
Sandbox = function() {
var sandbox = this;
if (! (sandbox instanceof Sandbox)) {
return new Sandbox()
}
if (worker_ok) sandbox[$worker] = new Worker(Sandbox.url);
sandbox[$requests] = {};
if (worker_ok) {
sandbox[$worker].onmessage = function(event) {
var data = event[$data],
request;
if (typeof data !== "object") {
return
}
request = sandbox[$requests][data.id];
if (request) {
if (data.error) {
if (typeof sandbox[$onerror] === fun_type) {
sandbox[$onerror](data, request)
}
if (typeof request[$onerror] === fun_type) {
request[$onerror][$call](sandbox, data.error)
}
} else {
if (typeof sandbox[$onresponse] === fun_type) {
sandbox[$onresponse](data, request)
}
if (typeof request[$callback] === fun_type) {
request[$callback][$call](sandbox, data.results)
}
}
delete sandbox[$requests][data.id]
}
}
}
},
proto = Sandbox[$prototype],
createRequestMethod = function(method) {
proto[method] = function(options, callback, input, onerror) {
if (typeof options === str_type || Object[$prototype].toString[$call](options) === "[object Array]" || arguments.length > 1) {
options = {
data: options,
input: input,
callback: callback,
onerror: onerror
}
}
if (method === $load && typeof options[$data] === str_type) {
options[$data] = [options[$data]]
}
var data = options[$data],
id = this.createRequestID();
input = options[$input];
delete options[$data];
delete options[$input];
this[$requests][id] = options;
if (worker_ok) {
this[$worker].postMessage({
id: id,
method: method,
data: data,
input: input
});
}
return id
};
Sandbox[method] = function() {
var sandbox = new Sandbox();
sandbox[$onresponse] = sandbox[$onerror] = function() {
sandbox[$terminate]();
sandbox = null
};
Sandbox[$prototype][method].apply(sandbox, Array[$prototype].slice[$call](arguments));
return Sandbox
}
},
methods = [$eval, $load, $exec],
i = 3;
while (i--) {
createRequestMethod(methods[i])
}
proto[$terminate] = function() {
this[$requests] = {};
if (worker_ok) {
this[$worker].onmessage = null;
this[$worker][$terminate]()
}
};
proto.abort = function(id) {
delete this[$requests][id]
};
proto.createRequestID = function() {
var id = Math.random().toString();
if (id in this[$requests]) {
return this.createRequestID()
}
return id
};
if (typeof doc !== undef_type) {
var linkElems = doc.getElementsByTagName("link");
i = linkElems.length;
while (i--) {
if (linkElems[i].getAttribute("rel") === "jsandbox") {
Sandbox.url = linkElems[i].getAttribute("href");
break
}
}
}
return Sandbox
} (self)),
Sandbox = JSandbox;
/* global window unsafeWindow document GM JSandbox formatName AddArtistField RemoveArtistField Blob alert Image */
/* eslint max-depth: 'off', block-scoped-var: 'off', no-loop-func: 'off', no-alert: 'off', unicorn/prefer-module: 'off', no-bitwise: 'off' */
/*
Here you can set site specific default templates.
You can find a list of available templates at: https://yadg.cc/api/v2/templates/
*/
const defaultPTHFormat = 5;
const defaultWafflesFormat = 9;
const defaultPTHTarget = 'other';
const defaultPTHDescriptionTarget = 'album';
let yadg; // eslint-disable-line prefer-const
let factory; // eslint-disable-line prefer-const
let yadgRenderer; // eslint-disable-line prefer-const
let yadgTemplates; // eslint-disable-line prefer-const
let autoRehost;
// --------- USER SETTINGS END ---------
function fetchImage(target, callback) {
const input = document.querySelector('[name="cover"]');
if (input === null) {
return;
}
if (/imgur|ptpimg/g.test(input.value)) {
return;
}
const link = target === null ? $('#yadg_input').val() : target;
switch (true) {
case /discogs/.test(link):
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
const script = container.querySelector('#release_schema');
try {
const data = JSON.parse(script.textContent);
callback(data.image);
} catch {
callback(false);
}
}
},
});
break;
case /music.apple/.test(link): {
const regex = /apple\.com\/(?:([a-z]{2,3})\/)?.*\/(?:(\d+)|id(\d*))/;
const result = regex.exec(link);
const id = result[2] | result[3];
let country = 'us';
if (result[1]) {
[, country] = result;
}
GM_xmlhttpRequest({
method: 'GET',
url: 'https://itunes.apple.com/lookup?id=' + id + '&country=' + country,
onload(response) {
if (response.status === 200) {
const data = JSON.parse(response.responseText);
const settingCover = factory.getCoverSize().value;
const hires = settingCover === 'large' ? data.results[0].artworkUrl100.replace(
'100x100bb',
'100000x100000-999',
) : data.results[0].artworkUrl100.replace(
'100x100bb',
'700x700bb',
);
if (typeof callback === 'function') {
callback(hires);
}
}
},
});
break;
}
case factory.getScraperSelect().value === 'bandcamp': {
let img;
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
const [imgElement_] = container.querySelectorAll(
'#tralbumArt > a > img',
);
if (!imgElement_) {
if (typeof callback === 'function') {
callback(false);
}
return false;
}
const scaledImg = imgElement_.src;
const settingCover = factory.getCoverSize().value;
const originalImg = settingCover === 'large' ? scaledImg.replace(/_16/, '_0') : scaledImg.replace(/_16/, '_10');
const temporaryImg = new Image();
temporaryImg.src = originalImg;
temporaryImg.addEventListener('load', function () {
img = this.width === this.height ? originalImg : scaledImg;
if (typeof callback === 'function') {
callback(img);
}
});
}
},
});
break;
}
case /beatport/.test(link):
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
if (typeof callback === 'function') {
callback(
container.querySelectorAll(
'div.interior-release-chart-artwork-parent > img',
)[0].src,
);
}
}
},
});
break;
case /musicbrainz/.test(link): {
const regex = /release\/(.*)/;
const {1: id} = regex.exec(link);
GM_xmlhttpRequest({
headers: {
'User-Agent': 'YADG/1.4.41 (yadg.cc)',
},
method: 'GET',
url: 'http://coverartarchive.org/release/' + id + '/',
onload(response) {
if (response.status === 200) {
const data = JSON.parse(response.responseText);
if (typeof callback === 'function') {
callback(data.images[0].image);
}
}
},
});
break;
}
case /junodownload/.test(link):
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
if (typeof callback === 'function') {
callback(container.querySelector('.img-fluid-fill').src);
}
}
},
});
break;
case /metal-archives/.test(link):
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
const parser = document.createElement('a');
parser.href = container.querySelectorAll('#cover > img')[0].src;
const imgLink
= parser.protocol + '//' + parser.hostname + parser.pathname;
if (typeof callback === 'function') {
callback(imgLink);
}
}
},
});
break;
case /allmusic/.test(link):
GM_xmlhttpRequest({
method: 'GET',
url: link,
onload(response) {
if (response.status === 200) {
const container = document.implementation.createHTMLDocument()
.documentElement;
container.innerHTML = response.responseText;
const data = container.querySelector('[data-largeurl]');
// No image available https://www.allmusic.com/album/release/beatles-mr0003843619
if (data !== null) {
const cover = data.getAttribute('data-largeurl');
if (typeof callback === 'function') {
callback(cover);
}
}
}
},
});
break;
case /deezer/.test(link): {
const regex = /\.com\/(\w+\/)?(album)\/(\d+)/g;
const helper = regex.exec(link);
const id = helper[3];
GM_xmlhttpRequest({
method: 'GET',
url: 'https://api.deezer.com/album/' + id,
onload(response) {
if (response.status === 200) {
const data = JSON.parse(response.responseText);
const settingCover = factory.getCoverSize().value;
const cover = settingCover === 'large' ? data.cover_xl.replace(
'1000x1000-000000-80-0-0.jpg',
'1400x1400-000000-100-0-0.jpg',
) : data.cover_xl;
if (typeof callback === 'function') {
callback(cover);
}
}
},
});
break;
}
}
}
function pthImgIt() {
const [pthImgIt] = document.querySelectorAll('.rehost_it_cover');
let imgElement;
switch (window.location.href) {
case (window.location.href.match(/\/upload\.php/) || {}).input: {
imgElement = document.querySelector('#image').value;
break;
}
case (window.location.href.match(/torrents\.php\?action=editgroup/) || {})
.input: {
imgElement = document.querySelectorAll(
'#content > div > div:nth-child(2) > form > div > input[type="text"]:nth-child(5)',
)[0].value;
break;
}
default:
break;
}
if (pthImgIt && imgElement) {
pthImgIt.click();
}
}
function insertImage(img, callback) {
switch (window.location.href) {
case (window.location.href.match(/\/upload\.php/) || {}).input: {
const input = document.querySelector('#image');
input.value = img;
if (input.getAttribute('autorehost') === 'true') {
const evt = document.createEvent('HTMLEvents');
evt.initEvent('keyup', false, true);
input.dispatchEvent(evt);
}
input.parentNode.parentNode.insertAdjacentHTML(
'beforebegin',
'<tr id="yadg_image_preview_tr"><td class="label">Album Art Preview:</td><td><img id="yadg_image_preview" src="'
+ img
+ '" width="300px" /></tr></td>',
);
callback();
break;
}
case (window.location.href.match(/torrents\.php\?action=editgroup/) || {})
.input: {
const [imageInputElement] = document.querySelectorAll(
'#content > div > div:nth-child(2) > form > div > input[type="text"]:nth-child(5)',
);
imageInputElement.value = img;
imageInputElement.parentNode.insertAdjacentHTML(
'beforebegin',
'<div id="yadg_image_preview_div"><img id="yadg_image_preview" src="'
+ img
+ '" width="300px" /></div>',
);
callback();
break;
}
case (window.location.href.match(/requests\.php\?/) || {}).input: {
const [imageInputElement] = document.querySelectorAll(
'#image_tr > td:nth-child(2) > input[type="text"]:nth-child(1)',
);
imageInputElement.value = img;
imageInputElement.parentNode.parentNode.insertAdjacentHTML(
'beforebegin',
'<tr id="yadg_image_preview_tr"><td class="label">Album Art Preview:</td><td><img id="yadg_image_preview" src="'
+ img
+ '" width="300px" /></tr></td>',
);
callback();
break;
}
default:
break;
}
}
// --------- THIRD PARTY CODE AREA START ---------
// Creates an object which gives some helper methods to
// Save/Load/Remove data to/from the localStorage
// Source from: https://github.com/gergob/localstoragewrapper
function LocalStorageWrapper(appPrefix) {
'use strict';
if (appPrefix === undefined) {
throw new Error('applicationPrefix parameter should be defined');
}
const delimiter = '_';
// If the passed in value for prefix is not string, it should be converted
const keyPrefix
= typeof appPrefix === 'string'
? appPrefix
: JSON.stringify(appPrefix);
const localStorage = window.localStorage || unsafeWindow.localStorage;
const isLocalStorageAvailable = function () {
return typeof localStorage !== 'undefined';
};
const getKeyPrefix = function () {
return keyPrefix;
};
//
// validates if there is a prefix defined for the keys
// and checks if the localStorage functionality is available or not
//
const makeChecks = function (key) {
const prefix = getKeyPrefix();
if (prefix === undefined) {
throw new Error('No prefix was defined, data cannot be saved');
}
if (!isLocalStorageAvailable()) {
throw new Error(
'LocalStorage is not supported by your browser, data cannot be saved',
);
}
// Keys are always strings
const checkedKey = typeof key === 'string' ? key : JSON.stringify(key);
return checkedKey;
};
//
// saves the value associated to the key into the localStorage
//
const addItem = function (key, value) {
try {
const checkedKey = makeChecks(key);
const combinedKey = this.getKeyPrefix() + delimiter + checkedKey;
localStorage.setItem(combinedKey, JSON.stringify(value));
} catch (error) {
console.log(error);
throw error;
}
};
//
// gets the value of the object saved to the key passed as parameter
//
const getItem = function (key) {
let result;
try {
const checkedKey = makeChecks(key);
const combinedKey = this.getKeyPrefix() + delimiter + checkedKey;
const resultAsJSON = localStorage.getItem(combinedKey);
result = JSON.parse(resultAsJSON);
} catch (error) {
console.log(error);
throw error;
}
return result;
};
//
// returns all the keys from the localStorage
//
const getAllKeys = function () {
const prefix = getKeyPrefix();
const results = [];
if (prefix === undefined) {
throw new Error('No prefix was defined, data cannot be saved');
}
if (!isLocalStorageAvailable()) {
throw new Error(
'LocalStorage is not supported by your browser, data cannot be saved',
);
}
for (const key in localStorage) {
if (key.indexOf(prefix) === 0) {
const keyParts = key.split(delimiter);
results.push(keyParts[1]);
}
}
return results;
};
//
// removes the value associated to the key from the localStorage
//
const removeItem = function (key) {
let result = false;
try {
const checkedKey = makeChecks(key);
const combinedKey = this.getKeyPrefix() + delimiter + checkedKey;
localStorage.removeItem(combinedKey);
result = true;
} catch (error) {
console.log(error);
throw error;
}
return result;
};
//
// removes all the values from the localStorage
//
const removeAll = function () {
try {
const allKeys = this.getAllKeys();
for (const key of allKeys) {
const checkedKey = makeChecks(key);
const combinedKey = this.getKeyPrefix() + delimiter + checkedKey;
localStorage.removeItem(combinedKey);
}
} catch (error) {
console.log(error);
throw error;
}
};
// Make some of the functionalities public
return {
isLocalStorageAvailable,
getKeyPrefix,
addItem,
getItem,
getAllKeys,
removeItem,
removeAll,
};
}
// --------- THIRD PARTY CODE AREA END ---------
const yadgUtil = {
exec(fn) {
const script = document.createElement('script');
script.setAttribute('type', 'application/javascript');
script.textContent = '(' + fn + ')();';
document.body.append(script); // Run the script
script.remove(); // Clean up
},
// Handle for updating page css, taken from one of hateradio's scripts
addCSS(style) {
if (!this.style) {
this.style = document.createElement('style');
this.style.type = 'text/css';
(document.head || document.querySelectorAll('head')[0]).append(
this.style,
);
}
this.style.append(document.createTextNode(style + '\n'));
},
setValueIfSet(value, input, cond) {
input.value = cond ? value : '';
},
// Negative count will remove, positive count will add given number of artist boxes
addRemoveArtistBoxes(count) {
if (count !== 0) {
if (count < 0) {
for (let i = 0; i < -count; i++) {
yadgUtil.exec(() => {
RemoveArtistField(); // eslint-disable-line new-cap
});
}
} else {
for (let i = 0; i < count; i++) {
yadgUtil.exec(() => {
AddArtistField(); // eslint-disable-line new-cap
});
}
}
}
},
getOptionOffsets(select) {
const optionOffsets = {};
for (let j = 0; j < select.options.length; j++) {
optionOffsets[select.options[j].value] = select.options[j].index;
}
return optionOffsets;
},
storage: new LocalStorageWrapper('yadg'),
settings: new LocalStorageWrapper('yadgSettings'),
};
// Very simple wrapper for XmlHttpRequest
// eslint-disable-next-line max-params
function Requester(url, method, callback, data, errorCallback) {
this.data = data;
this.url = url;
this.method = method;
if (!errorCallback) {
errorCallback = yadg.failedCallback;
}
this.send = function () {
const details = {
url: this.url,
method: this.method,
onload(response) {
if (response.status === 200) {
callback(JSON.parse(response.responseText));
} else if (response.status === 401) {
yadg.failedAuthenticationCallback();
} else {
errorCallback();
}
},
onerror: errorCallback,
};
if (method === 'POST') {
details.data = JSON.stringify(this.data);
}
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json',
};
if (yadgUtil.settings.getItem(factory.KEY_API_TOKEN)) {
headers.Authorization
= 'Token ' + yadgUtil.settings.getItem(factory.KEY_API_TOKEN);
}
details.headers = headers;
GM_xmlhttpRequest(details);
};
}
const yadgSandbox = {
KEY_LAST_WARNING: 'templateLastWarning',
init(callback) {
GM_xmlhttpRequest({
method: 'GET',
url: yadg.yadgHost + '/static/js/jsandbox-worker.js',
onload(response) {
let script;
let dataURL = null;
if (response.status === 200) {
script = response.responseText;
const blob = new Blob([script], {type: 'application/javascript'});
const URL = window.URL || window.webkitURL;
if (!URL || !URL.createObjectURL) {
throw new Error(
'No no valid implementation of window.URL.createObjectURL found.',
);
}
dataURL = URL.createObjectURL(blob);
yadgSandbox.initCallback(dataURL);
yadgSandbox.loadSwig(callback);
} else {
yadgSandbox.initCallbackError();
}
},
onerror() {
yadgSandbox.initCallbackError();
},
});
},
loadSwig(callback) {
// ImportScripts for the web worker will not work in Firefox with cross-domain requests
// see: https://bugzilla.mozilla.org/show_bug.cgi?id=756589
// so download the Swig files manually with GM_xmlhttpRequest
GM_xmlhttpRequest({
method: 'GET',
url: yadg.yadgHost + '/static/js/swig.min.js',
onload(response) {
if (response.status === 200) {
yadgSandbox.swigScript = response.responseText;
GM_xmlhttpRequest({
method: 'GET',
url: yadg.yadgHost + '/static/js/swig.custom.js',
onload(response) {
if (response.status === 200) {
yadgSandbox.swigCustomScript = response.responseText;
callback();
}
},
});
}
},
});
},
initializeSwig(dependencies) {
if (!(this.swigScript && this.swigCustomScript)) {
yadg.failedCallback();
return;
}
yadgSandbox.exec({data: this.swigScript, onerror: yadg.failedCallback});
yadgSandbox.exec({
data: this.swigCustomScript,
onerror: yadg.failedCallback,
});
yadgSandbox.exec({
data:
'var myswig = new swig.Swig({ loader: swig.loaders.memory(input.templates), autoescape: false }), i=0; yadg_filters.register_filters(myswig);',
input: {templates: dependencies},
});
},
renderTemplate(template, data, callback, error) {
const evalString
= 'myswig.render(input.template, { locals: input.data, filename: \'scratchpad\' + (i++) })';
this.eval({
data: evalString,
callback(out) {
callback(out);
},
input: {template, data},
onerror(error_) {
error(error_);
},
});
},
initCallback(dataUrl) {
JSandbox.url = dataUrl;
this.jsandbox = new JSandbox();
this.initError = false;
},
resetSandbox() {
this.jsandbox.terminate();
this.jsandbox = new JSandbox();
},
load(options) {
this.jsandbox.load(options);
},
exec(options) {
this.jsandbox.exec(options);
},
eval(options) {
this.jsandbox.eval(options);
},
initCallbackError() {
this.initError = true;
const lastWarning = yadgUtil.storage.getItem(this.KEY_LAST_WARNING);
const now = new Date();
if (
lastWarning === null
|| now.getTime() - new Date(lastWarning).getTime() > factory.CACHE_TIMEOUT
) {
console.log(
'Could not load the necessary script files for executing YADG. If this error persists you might need to update the user script. You will only get this message once a day.',
);
yadgUtil.storage.addItem(this.KEY_LAST_WARNING, now);
}
},
};
factory = {
// Storage keys for cache
KEY_LAST_CHECKED: 'lastChecked',
KEY_SCRAPER_LIST: 'scraperList',
KEY_FORMAT_LIST: 'formatList',
// Storage keys for settings
KEY_API_TOKEN: 'apiToken',
KEY_DEFAULT_TEMPLATE: 'defaultTemplate',
KEY_DEFAULT_TARGET: 'defaultTarget',
KEY_DESCRIPTION_TARGET: 'descriptionTarget',
KEY_DEFAULT_SCRAPER: 'defaultScraper',
KEY_REPLACE_DESCRIPTION: 'replaceDescriptionOn',
KEY_SETTINGS_INIT_VER: 'settingsInitializedVer',
KEY_FETCH_IMAGE: 'fetchImage',
KEY_AUTO_PREVIEW: 'autoPreview',
KEY_AUTO_REHOST: 'autoRehost',
KEY_AUTO_SELECT_SCRAPER: 'autoSelectScraper',
KEY_COVER_SIZE: 'coverSize',
CACHE_TIMEOUT: 1000 * 60 * 60 * 24, // 24 hours
UPDATE_PROGRESS: 0,
locations: [
{
name: 'pth_upload',
regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/upload\.php.*/i,
},
{
name: 'pth_edit',
regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/torrents\.php\?action=editgroup&groupid=.*/i,
},
{
name: 'pth_request',
regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/requests\.php\?action=new/i,
},
{
name: 'pth_request_edit',
regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/requests\.php\?action=edit&id=.*/i,
},
{
name: 'pth_torrent_overview',
regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/torrents\.php\?id=.*/i,
},
{
name: 'lemonhd_upload',
regex: /https:\/\/lemonhd.org\/upload_music.php*/i,
},
{
name: 'opencd_upload',
regex: /https:\/\/.*open.cd\/plugin_upload.php*/i,
},
{
name: 'ops_upload',
regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/upload\.php.*/i,
},
{
name: 'ops_edit',
regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/torrents\.php\?action=editgroup&groupid=.*/i,
},
{
name: 'ops_request',
regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/requests\.php\?action=new/i,
},
{
name: 'ops_request_edit',
regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/requests\.php\?action=edit&id=.*/i,
},
{
name: 'ops_torrent_overview',
regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/torrents\.php\?id=.*/i,
},
{
name: 'dic_upload',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.com\/upload\.php.*/i,
},
{
name: 'dic_edit',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.com\/torrents\.php\?action=editgroup&groupid=.*/i,
},
{
name: 'dic_request',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.com\/requests\.php\?action=new/i,
},
{
name: 'dic_request_edit',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.com\/requests\.php\?action=edit&id=.*/i,
},
{
name: 'dic_torrent_overview',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.com\/torrents\.php\?id=.*/i,
},
],
determineLocation(uri) {
for (let i = 0; i < this.locations.length; i++) {
if (this.locations[i].regex.test(uri)) {
return this.locations[i].name;
}
}
return null;
},
init() {
this.currentLocation = this.determineLocation(document.URL);
// Only continue with the initialization if we found a valid location
if (this.currentLocation === null) {
return false;
}
if (this.currentLocation === 'pth_request') {
this.inputsOff(document.URL);
}
this.insertIntoPage(this.getInputElements());
// Set the necessary styles
this.setStyles();
// Make sure we initialize the settings to the most recent version
this.initializeSettings();
// Populate settings inputs
this.populateSettings();
// Add the appropriate action for the input textbox
const input = document.querySelector('#yadg_input');
input.addEventListener('input', () => {
if (factory.getAutoSelectScraperCheckbox().checked) {
const inputValue = input.value;
const yadgScraper = document.querySelector('#yadg_scraper');
if (/discogs/.test(inputValue)) {
yadgScraper.value = 'discogs';
} else if (/music.apple/.test(inputValue)) {
yadgScraper.value = 'itunes';
} else if (/bandcamp/.test(inputValue)) {
yadgScraper.value = 'bandcamp';
} else if (/beatport/.test(inputValue)) {
yadgScraper.value = 'beatport';
} else if (/musicbrainz/.test(inputValue)) {
yadgScraper.value = 'musicbrainz';
} else if (/junodownload/.test(inputValue)) {
yadgScraper.value = 'junodownload';
} else if (/metal-archives/.test(inputValue)) {
yadgScraper.value = 'metalarchives';
} else if (/deezer/.test(inputValue)) {
yadgScraper.value = 'deezer';
} else if (/allmusic/.test(inputValue)) {
yadgScraper.value = 'allmusic';
}
}
});
// Add the appropriate action for the button
const button = document.querySelector('#yadg_submit');
button.addEventListener(
'click',
event => {
event.preventDefault();
yadg.makeRequest();
if (factory.getFetchImageCheckbox().checked) {
fetchImage(null, data => {
if (data) {
insertImage(data, () => {
if (
factory.getAutoRehostCheckbox()
&& factory.getAutoRehostCheckbox().checked
) {
pthImgIt();
}
});
}
});
}
},
false,
);
// Add the action for the options toggle
const toggleLink = document.querySelector('#yadg_toggle_options');
if (toggleLink !== null) {
toggleLink.addEventListener('click', event => {
event.preventDefault();
const optionsDiv = document.querySelector('#yadg_options');
const {display} = optionsDiv.style;
optionsDiv.style.display = display === 'none' || display === '' ? 'block' : 'none';
});
}
// Add the action for the cover size select
const coverSizeSetting = document.querySelector('#yadg_options_image');
if (coverSizeSetting !== null) {
coverSizeSetting.addEventListener('click', () => {
const optionsCoverSize = document.querySelector(
'#yadg_options_coversize',
);
const {display} = optionsCoverSize.style;
optionsCoverSize.style.display = display === 'none' || display === '' ? 'block' : 'none';
});
}
// Add the action for the template select
const formatSelect = this.getFormatSelect();
if (formatSelect !== null) {
formatSelect.addEventListener('change', function () {
if (yadgRenderer.hasCached()) {
yadgRenderer.renderCached(
this.value,
factory.setDescriptionBoxValue,
factory.setDescriptionBoxValue,
);
}
});
}
// add the action to the save settings link
const saveSettingsLink = document.querySelector('#yadg_save_settings');
if (saveSettingsLink !== null) {
saveSettingsLink.addEventListener('click', event => {
event.preventDefault();
factory.saveSettings();
alert('Settings saved successfully.');
});
}
// Add the action to the clear cache link
const clearCacheLink = document.querySelector('#yadg_clear_cache');
if (clearCacheLink !== null) {
clearCacheLink.addEventListener('click', event => {
event.preventDefault();
yadgUtil.storage.removeAll();
alert('Cache cleared. Please reload the page for this to take effect.');
});
}
const lastChecked = yadgUtil.storage.getItem(factory.KEY_LAST_CHECKED);
if (
lastChecked === null
|| Date.now() - new Date(lastChecked).getTime()
> factory.CACHE_TIMEOUT
) {
// Update the scraper and formats list
factory.UPDATE_PROGRESS = 1;
yadg.getScraperList(factory.setScraperSelect);
yadg.getFormatsList(factory.setFormatSelect);
} else {
factory.setScraperSelect(
yadgUtil.storage.getItem(factory.KEY_SCRAPER_LIST),
);
factory.setFormatSelect(
yadgUtil.storage.getItem(factory.KEY_FORMAT_LIST),
);
}
return true;
},
getApiTokenInput() {
return document.querySelector('#yadg_api_token');
},
getReplaceDescriptionCheckbox() {
return document.querySelector('#yadg_options_replace');
},
getFetchImageCheckbox() {
return document.querySelector('#yadg_options_image');
},
getAutoRehostCheckbox() {
return document.querySelector('#yadg_options_rehost');
},
getAutoPreviewCheckbox() {
return document.querySelector('#yadg_options_preview');
},
getAutoSelectScraperCheckbox() {
return document.querySelector('#yadg_options_auto_select_scraper');
},
getReplaceDescriptionSettingKey() {
return this.makeReplaceDescriptionSettingsKey(this.currentLocation);
},
makeReplaceDescriptionSettingsKey(subKey) {
return this.KEY_REPLACE_DESCRIPTION + subKey.replace(/_/g, '');
},
// Disable fields when groupid set
inputsOff(url) {
if (/groupid=\d+/.test(url)) {
for (const i of [
'artists[]',
'importance[]',
'title',
'releasetype',
'genre_tags',
'tags',
]) {
for (const element of document.getElementsByName(i)) {
element.readOnly = true;
}
}
}
},
initializeSettings() {
let settingsVer = yadgUtil.settings.getItem(factory.KEY_SETTINGS_INIT_VER);
const currentVer = 1;
if (!settingsVer) {
settingsVer = 0;
}
if (settingsVer < currentVer) {
// Replace descriptions on upload and new request pages
const locations = [
'pth_upload',
'lemonhd_upload',
'opencd_upload',
'pth_request',
'ops_upload',
'ops_request',
'dic_upload',
'dic_request',
];
for (const loc of locations) {
const replaceDescSettingKey = factory.makeReplaceDescriptionSettingsKey(
loc,
);
yadgUtil.settings.addItem(replaceDescSettingKey, true);
}
}
yadgUtil.settings.addItem(factory.KEY_SETTINGS_INIT_VER, currentVer);
},
populateSettings() {
const apiToken = yadgUtil.settings.getItem(factory.KEY_API_TOKEN);
const replaceDesc = yadgUtil.settings.getItem(
factory.getReplaceDescriptionSettingKey(),
);
const fetchImage = yadgUtil.settings.getItem(factory.KEY_FETCH_IMAGE);
const autoPreview = yadgUtil.settings.getItem(factory.KEY_AUTO_PREVIEW);
autoRehost = yadgUtil.settings.getItem(factory.KEY_AUTO_REHOST);
const autoSelectScraper = yadgUtil.settings.getItem(
factory.KEY_AUTO_SELECT_SCRAPER,
);
const coverSize = yadgUtil.settings.getItem(factory.KEY_COVER_SIZE);
if (apiToken) {
const apiTokenInput = factory.getApiTokenInput();
apiTokenInput.value = apiToken;
}
if (replaceDesc) {
const replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
replaceDescCheckbox.checked = true;
}
if (fetchImage) {
const fetchImageCheckbox = factory.getFetchImageCheckbox();
fetchImageCheckbox.checked = true;
}
if (autoRehost) {
const autoRehostCheckbox = factory.getAutoRehostCheckbox();
if (autoRehostCheckbox) {
autoRehostCheckbox.checked = true;
}
}
if (autoPreview) {
const autoPreviewCheckbox = factory.getAutoPreviewCheckbox();
autoPreviewCheckbox.checked = true;
}
if (autoSelectScraper) {
const autoSelectScraperCheckbox = factory.getAutoSelectScraperCheckbox();
autoSelectScraperCheckbox.checked = true;
}
if (coverSize) {
const coverSizeOption = factory.getCoverSize();
coverSizeOption.value = coverSize;
if (factory.getFetchImageCheckbox().checked) {
const optionsCoverSize = document.querySelector(
'#yadg_options_coversize',
);
optionsCoverSize.style.display = 'block';
}
}
},
saveSettings() {
const scraperSelect = factory.getScraperSelect();
const templateSelect = factory.getFormatSelect();
const targetSelect = factory.getTargetSelect();
const descriptionTargetSelect = factory.getDescriptionTargetSelect();
const apiTokenInput = factory.getApiTokenInput();
const replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
const fetchImageCheckbox = factory.getFetchImageCheckbox();
const autoRehostCheckbox = factory.getAutoRehostCheckbox();
const autoPreviewCheckbox = factory.getAutoPreviewCheckbox();
const autoSelectScraperCheckbox = factory.getAutoSelectScraperCheckbox();
const coverSize = factory.getCoverSize();
let currentScraper = null;
let currentTemplate = null;
let currentTarget = null;
let currentDescriptionTarget = null;
let currentCoverSize = null;
const apiToken = apiTokenInput.value.trim();
const replaceDescription = replaceDescCheckbox.checked;
const fetchImage = fetchImageCheckbox.checked;
const autoSelectScraper = autoSelectScraperCheckbox.checked;
const autoPreview = autoPreviewCheckbox.checked;
if (autoRehostCheckbox) {
autoRehost = autoRehostCheckbox.checked;
}
if (scraperSelect.options.length > 0) {
currentScraper = scraperSelect.options[scraperSelect.selectedIndex].value;
}
if (templateSelect.options.length > 0) {
currentTemplate
= templateSelect.options[templateSelect.selectedIndex].value;
}
if (targetSelect.options.length > 0) {
currentTarget = targetSelect.options[targetSelect.selectedIndex].value;
}
if (descriptionTargetSelect.options.length > 0) {
currentDescriptionTarget
= descriptionTargetSelect.options[descriptionTargetSelect.selectedIndex]
.value;
}
if (coverSize.options.length > 0) {
currentCoverSize = coverSize.options[coverSize.selectedIndex].value;
}
if (currentScraper !== null) {
yadgUtil.settings.addItem(factory.KEY_DEFAULT_SCRAPER, currentScraper);
}
if (currentTemplate !== null) {
yadgUtil.settings.addItem(factory.KEY_DEFAULT_TEMPLATE, currentTemplate);
}
if (currentTarget !== null) {
yadgUtil.settings.addItem(factory.KEY_DEFAULT_TARGET, currentTarget);
}
if (currentDescriptionTarget !== null) {
yadgUtil.settings.addItem(
factory.KEY_DESCRIPTION_TARGET,
currentDescriptionTarget,
);
}
if (currentCoverSize !== null) {
yadgUtil.settings.addItem(factory.KEY_COVER_SIZE, currentCoverSize);
}
if (apiToken === '') {
yadgUtil.settings.removeItem(factory.KEY_API_TOKEN);
} else {
yadgUtil.settings.addItem(factory.KEY_API_TOKEN, apiToken);
}
const replaceDescSettingKey = factory.getReplaceDescriptionSettingKey();
if (replaceDescription) {
yadgUtil.settings.addItem(replaceDescSettingKey, true);
} else {
yadgUtil.settings.removeItem(replaceDescSettingKey);
}
if (fetchImage) {
yadgUtil.settings.addItem(factory.KEY_FETCH_IMAGE, true);
} else {
yadgUtil.settings.removeItem(factory.KEY_FETCH_IMAGE);
}
if (autoRehost) {
yadgUtil.settings.addItem(factory.KEY_AUTO_REHOST, true);
} else if (!autoRehost && autoRehostCheckbox) {
yadgUtil.settings.removeItem(factory.KEY_AUTO_REHOST);
}
if (autoPreview) {
yadgUtil.settings.addItem(factory.KEY_AUTO_PREVIEW, true);
} else {
yadgUtil.settings.removeItem(factory.KEY_AUTO_PREVIEW);
}
if (autoSelectScraper) {
yadgUtil.settings.addItem(factory.KEY_AUTO_SELECT_SCRAPER, true);
} else {
yadgUtil.settings.removeItem(factory.KEY_AUTO_SELECT_SCRAPER);
}
},
setDescriptionBoxValue(value) {
const descBox = factory.getDescriptionBox();
const replaceDesc = factory.getReplaceDescriptionCheckbox().checked;
const skipAutoPreview = ['pth_torrent_overview',
'ops_torrent_overview',
'dic_torrent_overview'].includes(factory.currentLocation);
const boxes = Array.isArray(descBox) ? descBox : [descBox];
for (const box of boxes) {
const disabled = box.getAttribute('disabled');
if (disabled === 'disabled') {
continue;
}
if (replaceDesc) {
box.value = value;
} else {
const blankline = /\S/.test(box.value) ? '\n\n' : '';
box.value += blankline + value;
}
if (skipAutoPreview) {
continue;
}
const div = box.parentNode.nextSibling.nextSibling;
const button = div.firstChild.nextSibling;
const autoPreviewChecked = factory.getAutoPreviewCheckbox().checked;
if (button && autoPreviewChecked) {
button.click();
}
}
},
getFormatSelect() {
return document.querySelector('#yadg_format');
},
setDefaultFormat() {
const formatSelect = factory.getFormatSelect();
const formatOffsets = yadgUtil.getOptionOffsets(formatSelect);
const defaultFormat = yadgUtil.settings.getItem(
factory.KEY_DEFAULT_TEMPLATE,
);
if (defaultFormat !== null && defaultFormat in formatOffsets) {
formatSelect.selectedIndex = formatOffsets[defaultFormat];
} else {
// We have no settings so fall back to the hard coded defaults
switch (this.currentLocation) {
default:
formatSelect.selectedIndex = formatOffsets[defaultPTHFormat];
break;
}
}
},
getCoverSize() {
return document.querySelector('#yadg_coversize');
},
getTargetSelect() {
return document.querySelector('#yadg_target');
},
getDescriptionTargetSelect() {
return document.querySelector('#yadg_description_target');
},
setDefaultTarget() {
const targetSelect = factory.getTargetSelect();
const targetOffsets = yadgUtil.getOptionOffsets(targetSelect);
const defaultTarget = yadgUtil.settings.getItem(factory.KEY_DEFAULT_TARGET);
targetSelect.selectedIndex = defaultTarget !== null && defaultTarget in targetOffsets ? targetOffsets[defaultTarget] : targetOffsets[defaultPTHTarget];
},
setDefaultDescriptionTarget() {
const targetDescriptionSelect = factory.getDescriptionTargetSelect();
const targetDescriptionOffsets = yadgUtil.getOptionOffsets(
targetDescriptionSelect,
);
const defaultDescriptionTarget = yadgUtil.settings.getItem(
factory.KEY_DESCRIPTION_TARGET,
);
if (
defaultDescriptionTarget !== null
&& defaultDescriptionTarget in targetDescriptionOffsets
) {
targetDescriptionSelect.selectedIndex
= targetDescriptionOffsets[defaultDescriptionTarget];
} else {
targetDescriptionSelect.selectedIndex
= targetDescriptionOffsets[defaultPTHDescriptionTarget];
}
},
getScraperSelect() {
return document.querySelector('#yadg_scraper');
},
setDefaultScraper() {
const defaultScraper = yadgUtil.settings.getItem(
factory.KEY_DEFAULT_SCRAPER,
);
if (defaultScraper !== null) {
const scraperSelect = factory.getScraperSelect();
const scraperOffsets = yadgUtil.getOptionOffsets(scraperSelect);
if (defaultScraper in scraperOffsets) {
scraperSelect.selectedIndex = scraperOffsets[defaultScraper];
}
}
},
setScraperSelect(scrapers) {
const scraperSelect = factory.getScraperSelect();
factory.setSelect(scraperSelect, scrapers);
factory.setDefaultScraper();
if (factory.UPDATE_PROGRESS > 0) {
yadgUtil.storage.addItem(factory.KEY_SCRAPER_LIST, scrapers);
factory.UPDATE_PROGRESS |= 1 << 1;
if (factory.UPDATE_PROGRESS === 7) {
yadgUtil.storage.addItem(factory.KEY_LAST_CHECKED, new Date());
}
}
},
setFormatSelect(templates) {
const formatSelect = factory.getFormatSelect();
const nonUtility = [];
const saveTemplates = [];
for (const element of templates) {
if (factory.UPDATE_PROGRESS > 0) {
if (element.name === 'What') {
element.name = 'RED';
element.nameFormatted = 'RED';
} else if (element.name === 'What (Tracks only)') {
element.name = 'RED (Tracks only)';
element.nameFormatted = 'RED (Tracks only)';
}
yadgTemplates.addTemplate(element);
saveTemplates.push({
id: element.id,
url: element.url,
name: element.name,
nameFormatted: element.nameFormatted,
owner: element.owner,
default: element.default,
isUtility: element.isUtility,
});
} else {
if (element.name === 'What') {
element.name = 'PTH';
element.nameFormatted = 'PTH';
} else if (element.name === 'What (Tracks only)') {
element.name = 'PTH (Tracks only)';
element.nameFormatted = 'PTH (Tracks only)';
}
yadgTemplates.addTemplateUrl(element.id, element.url);
}
if (!element.isUtility) {
nonUtility.push(element);
}
}
factory.setSelect(formatSelect, nonUtility);
factory.setDefaultFormat();
factory.setDefaultTarget();
factory.setDefaultDescriptionTarget();
if (factory.UPDATE_PROGRESS > 0) {
yadgUtil.storage.addItem(factory.KEY_FORMAT_LIST, saveTemplates);
factory.UPDATE_PROGRESS |= 1 << 2;
if (factory.UPDATE_PROGRESS === 7) {
yadgUtil.storage.addItem(factory.KEY_LAST_CHECKED, new Date());
}
}
},
setSelect(select, data) {
select.options.length = data.length;
for (const [i, element] of data.entries()) {
// We are not using the javascript constructor to create an Option instance because this will create an
// incompatibility with jQuery in Chrome which will make it impossible to add a new artist field on redacted.ch
const o = document.createElement('option');
o.text = 'nameFormatted' in element ? element.nameFormatted : element.name;
o.value = element.value || element.id;
o.selected = element.default;
select.options[i] = o;
if (element.default) {
select.selectedIndex = i;
}
if (element.url) {
o.dataset.url = element.url;
}
}
},
setStyles() {
// General styles
yadgUtil.addCSS(
'div#yadg_options{ display:none; margin-top:3px; } input#yadg_input,input#yadg_submit,label#yadg_format_label,a#yadg_scraper_info { margin-right: 5px } div#yadg_response { margin-top:3px; } select#yadg_scraper { margin-right: 2px } #yadg_options_template,#yadg_options_api_token,#yadg_options_replace_div { margin-bottom: 3px; } .add_form[name="yadg"] input,.add_form[name="yadg"] select { width: 90%; margin: 2px 0 !important; } input#yadg_submit { position: inherit !important} div#yadg_options_coversize { display:none; padding-left: 16px }',
);
},
// eslint-disable-next-line complexity
getInputElements() {
const buttonHTML = '<input type="submit" value="Fetch" id="yadg_submit"/>';
const scraperSelectHTML
= '<select name="yadg_scraper" id="yadg_scraper"></select>';
let optionsHTML
= '<div id="yadg_options"><div id="yadg_options_template"><label for="yadg_format" id="yadg_format_label">Template:</label><select name="yadg_format" id="yadg_format"></select></div><div id="yadg_options_target"><label for="yadg_target" id="yadg_target_label">Edition:</label><select name="yadg_target" id="yadg_target"><option value="original">Original</option><option value="other">Other</option></select></div><div id="yadg_options_description_target"><label for="yadg_description_target" id="yadg_description_target_label">Description:</label><select name="yadg_description_target" id="yadg_description_target"><option value="album">Album</option><option value="release">Release</option><option value="both">Both</option></select></div><div id="yadg_options_api_token"><label for="yadg_api_token" id="yadg_api_token_label">API token (<a href="https://yadg.cc/api/token" target="_blank">Get one here</a>):</label> <input type="text" name="yadg_api_token" id="yadg_api_token" size="50" /></div><div id="yadg_options_replace_div"><input type="checkbox" name="yadg_options_replace" id="yadg_options_replace" /> <label for="yadg_options_replace" id="yadg_options_replace_label">Replace descriptions on this page</label></div><div id="yadg_options_image_div"><input type="checkbox" name="yadg_options_image" id="yadg_options_image" /> <label for="yadg_options_image" id="yadg_options_image_label">Auto fetch Album Art (Allmusic, Bandcamp, Beatport, Deezer, Discogs, iTunes, Junodownload, Metal-Archives, MusicBrainz)</label></div>';
optionsHTML
+= '<div id="yadg_options_coversize"><label for="yadg_coversize" id="yadg_coversize_label">Cover size: </label><select name="yadg_coversize" id="yadg_coversize"><option value="large">Large</option><option value="medium">Medium</option></select></div>';
if (document.querySelectorAll('.rehost_it_cover')[0]) {
optionsHTML
+= '<div id="yadg_options_rehost_div"><input type="checkbox" name="yadg_options_rehost" id="yadg_options_rehost" /> <label for="yadg_options_rehost" id="yadg_options_rehost_label">Auto rehost with <a href="https://redacted.ch/forums.php?action=viewthread&threadid=1992">[User Script] PTPIMG URL uploader</a></label></div>';
}
optionsHTML += '<div id="yadg_options_preview_div"><input type="checkbox" name="yadg_options_preview" id="yadg_options_preview" /> <label for="yadg_options_preview" id="yadg_options_preview_label">Auto preview description</label></div>';
optionsHTML += '<div id="yadg_options_auto_select_scraper_div"><input type="checkbox" name="yadg_options_auto_select_scraper" id="yadg_options_auto_select_scraper"/><label for="yadg_options_auto_select_scraper" id="yadg_options_auto_select_scraper_label">Auto select the correct scraper when pasting the URL</label></div> ';
optionsHTML += '<div id="yadg_options_links"><a id="yadg_save_settings" href="#" title="Save the currently selected scraper and template as default for this site and save the given API token.">Save settings</a> <span class="yadg_separator">|</span> <a id="yadg_clear_cache" href="#">Clear cache</a></div></div>';
const inputHTML = '<input type="text" name="yadg_input" id="yadg_input" size="60" />';
const responseDivHTML = '<div id="yadg_response"></div>';
const toggleOptionsLinkHTML
= '<a id="yadg_toggle_options" href="#">Toggle options</a>';
const scraperInfoLink
= '<a id="yadg_scraper_info" href="https://yadg.cc/available-scrapers" target="_blank" title="Get additional information on the available scrapers">[?]</a>';
switch (this.currentLocation) {
case 'ops_upload':
case 'dic_upload':
case 'pth_upload': {
const tr = document.createElement('tr');
tr.className = 'yadg_tr';
tr.innerHTML
= '<td class="label">YADG:</td><td>'
+ inputHTML
+ scraperSelectHTML
+ scraperInfoLink
+ buttonHTML
+ toggleOptionsLinkHTML
+ optionsHTML
+ responseDivHTML
+ '</td>';
return tr;
}
case 'lemonhd_upload': {
const tr = document.createElement('tr');
tr.className = 'yadg_tr';
tr.innerHTML
= '<td class="label rowhead nowrap" align="right">YADG:</td><td class="rowfollow">'
+ inputHTML
+ scraperSelectHTML
+ scraperInfoLink
+ buttonHTML
+ toggleOptionsLinkHTML
+ optionsHTML
+ responseDivHTML
+ '</td>';
return tr;
}
case 'opencd_upload': {
const tr = document.createElement('tr');
tr.className = 'yadg_tr';
tr.innerHTML
= '<td class="label" align="right"><b>YADG:</b></td><td colspan="5" class="embedded" style="margin-right:5px; margin-left:5px">'
+ '<table style="width:99%; margin-left:0.5%"><tbody><tr><td class="embedded" align="left">'
+ '<input type="text" name="yadg_input" id="yadg_input" size="60" /></td><td>'
+ scraperSelectHTML + '</td><td>'
+ scraperInfoLink + '</td><td>'
+ buttonHTML + '</td><td>'
+ toggleOptionsLinkHTML + '</td></tr><tr><td colspan="5">'
+ optionsHTML
+ responseDivHTML + ' '
+ '</td><tr></tbody></table>'
+ '</td>';
return tr;
}
case 'ops_edit':
case 'dic_edit':
case 'pth_edit': {
const div = document.createElement('div');
div.className = 'yadg_div';
div.innerHTML
= '<h3 class="label">YADG:</h3>\n'
+ inputHTML
+ '\n'
+ scraperSelectHTML
+ '\n'
+ scraperInfoLink
+ '\n'
+ buttonHTML
+ '\n'
+ toggleOptionsLinkHTML
+ '\n'
+ optionsHTML
+ '\n'
+ responseDivHTML;
return div;
}
case 'ops_torrent_overview':
case 'dic_torrent_overview':
case 'pth_torrent_overview': {
const div = document.createElement('div');
div.id = 'yadg_div';
div.className = 'box';
div.innerHTML
= '<div class="head"><strong>YADG</strong></div>\n<div class="body">\n<form class="add_form" name="yadg" method="post">\n<input type="text" name="yadg_input" id="yadg_input" />\n'
+ scraperSelectHTML
+ '\n'
+ scraperInfoLink
+ '\n'
+ buttonHTML
+ '\n'
+ toggleOptionsLinkHTML
+ '\n'
+ optionsHTML
+ '\n'
+ responseDivHTML;
return div;
}
case 'ops_request':
case 'ops_request_edit':
case 'dic_request':
case 'dic_request_edit':
case 'pth_request':
case 'pth_request_edit': {
const tr = document.createElement('tr');
tr.className = 'yadg_tr';
tr.innerHTML
= '<td class="label">YADG:</td><td>'
+ inputHTML
+ scraperSelectHTML
+ scraperInfoLink
+ buttonHTML
+ toggleOptionsLinkHTML
+ optionsHTML
+ responseDivHTML
+ '</td>';
return tr;
}
default:
// This should actually never happen
return document.createElement('div');
}
},
// eslint-disable-next-line complexity
insertIntoPage(element) {
// alert(this.currentLocation)
switch (this.currentLocation) {
case 'ops_upload':
case 'dic_upload':
case 'pth_upload': {
const yearTr = document.querySelector('#year_tr');
yearTr.parentNode.insertBefore(element, yearTr);
break;
}
case 'lemonhd_upload':
const tr = document.querySelector("#compose > table > tbody > tr:nth-child(3)");
tr.parentNode.insertBefore(element, tr);
break;
case 'opencd_upload':
const trd = document.querySelector("#compose > table > tbody > tr:nth-child(5)");
trd.parentNode.insertBefore(element, trd);
break;
case 'ops_edit':
case 'dic_edit':
case 'pth_edit': {
const [summaryInput] = document.getElementsByName('summary');
summaryInput.parentNode.insertBefore(
element,
summaryInput.nextSibling.nextSibling,
);
break;
}
case 'ops_torrent_overview':
case 'dic_torrent_overview':
case 'pth_torrent_overview': {
const [addArtistsBox] = document.querySelectorAll('.box_addartists');
addArtistsBox.parentNode.insertBefore(
element,
addArtistsBox.nextSibling.nextSibling,
);
break;
}
case 'ops_request':
case 'ops_request_edit':
case 'dic_request':
case 'dic_request_edit':
case 'pth_request':
case 'pth_request_edit': {
const artistTr = document.querySelector('#artist_tr');
artistTr.parentNode.insertBefore(element, artistTr);
break;
}
default:
break;
}
},
// eslint-disable-next-line complexity
getDescriptionBox() {
switch (this.currentLocation) {
case 'ops_upload':
case 'dic_upload':
case 'pth_upload':
if (factory.getDescriptionTargetSelect().value === 'album') {
return document.querySelector('#album_desc');
}
if (factory.getDescriptionTargetSelect().value === 'release') {
return document.querySelector('#release_desc');
}
if (factory.getDescriptionTargetSelect().value === 'both') {
return [
document.querySelector('#album_desc'),
document.querySelector('#release_desc'),
];
}
break;
case 'lemonhd_upload':
if (factory.getDescriptionTargetSelect().value === 'album') {
return document.querySelector('#descr');
}
if (factory.getDescriptionTargetSelect().value === 'release') {
return document.querySelector('#descr');
}
if (factory.getDescriptionTargetSelect().value === 'both') {
return [
document.querySelector('#descr'),
document.querySelector('#descr'),
];
}
break;
case 'opencd_upload':
if (factory.getDescriptionTargetSelect().value === 'album') {
return document.querySelector('#descr');
}
if (factory.getDescriptionTargetSelect().value === 'release') {
return document.querySelector('#descr');
}
if (factory.getDescriptionTargetSelect().value === 'both') {
return [
document.querySelector('#descr'),
document.querySelector('#descr'),
];
}
break;
case 'ops_edit':
case 'dic_edit':
case 'pth_edit':
return document.getElementsByName('body')[0];
case 'ops_torrent_overview':
case 'dic_torrent_overview':
case 'pth_torrent_overview':
if (!Object.prototype.hasOwnProperty.call(this, 'dummybox')) {
this.dummybox = document.createElement('div');
}
return this.dummybox;
case 'ops_request':
case 'ops_request_edit':
case 'dic_request':
case 'dic_request_edit':
case 'pth_request':
case 'pth_request_edit':
return document.getElementsByName('description')[0];
default:
// That should actually never happen
return document.createElement('div');
}
},
// eslint-disable-next-line complexity
getFormFillFunction() {
const currentTarget = factory.getTargetSelect().value;
var type_dict = {
"electronic": "电子(Electronic)",
"blues": "蓝调(Blues)",
"blues": "蓝调(Blues)", "rhythm.and.blues": "蓝调(Blues)",
"classical": "古典(Classical)",
"country": "乡村(Country)",
"folk": "民间(Folk)",
"drum.and.bass": "贝斯(Drum Bass)",
"jazz": "爵士(Jazz)",
"new.age": "新世纪(NewAge)",
"soul": "天籁(Soul)",
"modern.classical": "古典(Classical)",
"garage.house": "汽车(garage)", "garage.rock": "汽车(garage)",
"reggae": "雷鬼(Reggae)",
"hip.hop": "嘻哈(Hip Hop)",
"instrumental": "器乐(Instrumental)",
"indie": "独立(Indie)",
"japanese": "日韩", "korean": "日韩",
"chinese": "大陆", "thai": "其他地区",
"dance": "舞曲(Dance)","english": "欧美"
};
var info = {
"大陆": "1","欧美": "2","港台": "3","日韩": "4","其它地区": "5","流行(Pop)": "6",
"发烧(HiFi)": "7","汽车(garage)": "8","古典(Classical)": "9","民族(National)": "10",
"摇滚(rock)": "11","原声(OST)": "12","民间(Folk)": "13","乡村(Country)": "14",
"天籁(Soul)": "15","新世纪(NewAge)": "16","蓝调(Blues)": "17","爵士(Jazz)": "18",
"金属(Metal)": "19","朋克(Punk)": "20","电子(Electronic)": "21","儿童(Children's)": "22",
"宗教(Religion)": "23","雷鬼(Reggae)": "24","贝斯(Drum Bass)": "25","说唱(Rap)": "26","音乐剧(musical)": "27"
};
function getDescr(rawData) {
var descr = `[size=4][b]Album Info[/b][/size]\n`;
if (rawData.title) { descr += `[b]Music title[/b]: ${rawData.title}\n`; }
if (rawData.artists.length) { descr += `[b]Music artists[/b]: ${rawData.artists[0].name}\n`; }
if (rawData.format) { descr += `[b]Music format[/b]: ${rawData.format}\n`; }
if (rawData.styles.length) { descr += `[b]Music style[/b]: ${rawData.styles.join(', ')}\n`; }
if (rawData.genres.length) { descr += `[b]Music Genres[/b]: ${rawData.genres.join(' | ')}\n`; }
if (rawData.releaseEvents.length) { descr += `[b]Music release[/b]: ${rawData.releaseEvents[0].country}-${rawData.releaseEvents[0].date}\n`; }
if (rawData.labelIds.length) {
descr += '[b]Music labelIds[/b]: ';
rawData.labelIds.map((item, index)=>{
if (index == 0) {
descr += `${item.label}(${item.catalogueNrs[0]}); `;
} else {
descr += `${item.label}(${item.catalogueNrs[0]});`;
}
})
}
if (rawData.url) {
descr += '\n\n' + `More information: [url]${rawData.url}[/url]`;
}
return descr;
}
function getMinute(i) {
var hour = parseInt(i/3600);
if (hour > 0) {
i = i % 3600;
}
var minutes = parseInt(i/60);
var seconds = i % 60;
var timeStr = `(${minutes}:${seconds})`;
if (hour) {
timeStr = `(${hour}:${minutes}:${seconds})`;
}
return timeStr;
}
switch (this.currentLocation) {
case 'lemonhd_upload': {
const f = function (rawData) {
console.log(rawData)
let albumTitleInput;
let yearInput;
let labelInput;
let catalogInput;
albumTitleInput = document.querySelector('[name=title]');
yearInput = document.querySelector('[name=remaster_year]');
labelInput = document.querySelector('[name=remaster_record_label]');
catalogInput = document.querySelector('[name=remaster_catalogue_number]');
if (/music.apple/.test(rawData.url)) {
switch (true) {
case /.+ - Single$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - Single$/, '');
$('select[name=music_category]').val(3);
break;
case /.+ - EP$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - EP$/, '');
$('select[name=music_category]').val(4);
}
}
var descr = getDescr(rawData);
$('#descr').val(descr + $('#descr').val());
let artistInputs = document.getElementsByName('artists[]');
const releaseTypeInput = document.querySelector('[name=music_category]');
const data = yadg.prepareRawResponse(rawData);
console.log(data)
let nullArtistCount = 0;
if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('artists[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
if (artistKey === 'null') {
nullArtistCount++;
continue;
}
const artistTypes = data.artists[artistKey];
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
if (nullArtistCount > 0) {
yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
}
}
}
if (yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
if (labelInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.label,
labelInput,
data.label !== false,
);
}
if (catalogInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
}
// tags
var music_type = [];
data.tags.map((item)=>{
item = item.toLowerCase();
if (item.match(/pop/) && music_type.indexOf("流行(Pop)") < 0) {
music_type.push("流行(Pop)");
}
if (item.match(/rock/) && music_type.indexOf("摇滚(rock)") < 0) {
music_type.push("摇滚(rock)");
}
if (item.match(/punk/) && music_type.indexOf("朋克(Punk)") < 0) {
music_type.push("朋克(Punk)");
}
if (item.match(/Metal/i) && music_type.indexOf("金属(Metal)") < 0) {
music_type.push("金属(Metal)");
}
if (type_dict.hasOwnProperty(item) && music_type.indexOf(type_dict[item]) < 0) {
music_type.push(type_dict[item]);
}
if (item.match(/alternative/) && music_type.indexOf("另类(Alternative)") < 0) {
music_type.push("另类(Alternative)");
}
if (item.match(/world.music/) && music_type.indexOf("世界音乐(World)") < 0) {
music_type.push("世界音乐(World)");
}
});
music_type.map((item)=>{
if (info.hasOwnProperty(item)) {
addTag(info[item]);
}
});
var releasetype_dict = {
1:1, 3:9, 5:4, 6:6, 7:5, 9:3, 11:2, 13: 13, 14: 14, 15: 15, 16:16, 17: 17, 18:18, 19:19, 21:21
}
data.releaseType = releasetype_dict[data.releaseType];
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.releaseType,
releaseTypeInput,
data.releaseType !== false,
);
}
};
return f;
}
case 'opencd_upload': {
// eslint-disable-next-line complexity
const f = function (rawData) {
console.log(rawData)
let albumTitleInput;
let yearInput;
albumTitleInput = document.querySelector('[name=resource_name]');
yearInput = document.querySelector('[name=year]');
let artistInputs = document.getElementsByName('artist');
if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
if (rawData.artists.length) {
artistInputs[0].value = rawData.artists[0].name;
}
}
console.log(rawData);
var descr = getDescr(rawData);
if ($('#yadg2descr').length == 1) {
$('#yadg2descr').remove();
$('#descr').parent().append(`<a style="text-decoration:none;" href="#" id="yadg2descr"><font color="red">从yadg导入</font></a>`);
} else {
$('#descr').parent().append(`<br><a style="text-decoration:none;" href="#" id="yadg2descr"><font color="red">从yadg导入</font></a>`);
}
$('#yadg2descr').click((e)=>{
e.preventDefault();
var originDescr = $('#descr').val();
$('#descr').val(descr + '\n\n' + originDescr);
});
const data = yadg.prepareRawResponse(rawData);
if (yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
var tracklist = ``;
if (rawData.discs.length) {
rawData.discs.map(disc=>{
var total_time = 0;
disc.tracks.map(item=>{
console.log(item.length);
tracklist += `${item.number} – ${item.title}${item['length'] ? getMinute(item['length']): ''}\n`;
total_time += item['length'] ? item['length'] : 0;
});
tracklist += total_time? `\n[b]Total length:[/b] ${getMinute(total_time)}\n\n` : '\n\n';
})
}
if ($('#yadg2dtracklit').length == 0) {
$('textarea[name=track_list]').parent().append(`<br><a style="text-decoration:none;" href="#" id="yadg2dtracklit"><font color="red">从yadg导入</font></a>`);
}
$('#yadg2dtracklit').click((e)=>{
e.preventDefault();
$('textarea[name=track_list]').val(tracklist);
});
// tags
var music_type = [];
if (data.tags) {
data.tags.map((item)=>{
item = item.toLowerCase();
if (item.match(/pop/) && music_type.indexOf("流行(Pop)") < 0) {
music_type.push("流行(Pop)");
}
if (item.match(/rock/) && music_type.indexOf("摇滚(rock)") < 0) {
music_type.push("摇滚(rock)");
}
if (item.match(/punk/) && music_type.indexOf("朋克(Punk)") < 0) {
music_type.push("朋克(Punk)");
}
if (item.match(/Metal/i) && music_type.indexOf("金属(Metal)") < 0) {
music_type.push("金属(Metal)");
}
if (type_dict.hasOwnProperty(item) && music_type.indexOf(type_dict[item]) < 0) {
music_type.push(type_dict[item]);
}
if (item.match(/alternative/) && music_type.indexOf("另类(Alternative)") < 0) {
music_type.push("另类(Alternative)");
}
if (item.match(/world.music/) && music_type.indexOf("世界音乐(World)") < 0) {
music_type.push("世界音乐(World)");
}
});
}
setTimeout(function(){
var source_selected = false;
music_type.map(item=>{
console.log(item)
var source = $(`a.tag:contains("${item}")`);
if (item == "贝斯(Drum Bass)") { source = $(`a.tag[value="25"]`); }
if (source.lenth) {
addTag(source);
}
if (!source_selected) {
if (item == '摇滚(rock)') {
item = '摇滚(Rock)';
}
if ($(`#source>option:contains(${item})`).length) {
$(`#source>option:contains(${item})`).attr('selected', true);
source_selected = true;
}
}
})
}, 500);
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
document.getElementById('audio_mode').dispatchEvent(evt);
};
return f;
}
case 'pth_upload': {
// eslint-disable-next-line complexity
const f = function (rawData) {
let albumTitleInput;
let yearInput;
let labelInput;
let catalogInput;
if (currentTarget === 'other') {
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#remaster_year');
labelInput = document.querySelector('#remaster_record_label');
catalogInput = document.querySelector('#remaster_catalogue_number');
unsafeWindow.CheckYear(); // eslint-disable-line new-cap
} else {
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#year');
labelInput = document.querySelector('#remaster_record_label');
catalogInput = document.querySelector('#remaster_catalogue_number');
}
if (/music.apple/.test(rawData.url)) {
const releaseTypeInput = document.querySelector('#releasetype');
switch (true) {
case /.+ - Single$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - Single$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 9;
}
break;
case /.+ - EP$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - EP$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 5;
}
break;
default:
break;
}
}
let artistInputs = document.getElementsByName('artists[]');
const tagsInput = document.querySelector('#tags');
const mediaInput = document.querySelector('#media');
const releaseTypeInput = document.querySelector('#releasetype');
const data = yadg.prepareRawResponse(rawData);
let nullArtistCount = 0;
if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('artists[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
if (artistKey === 'null') {
nullArtistCount++;
continue;
}
const artistTypes = data.artists[artistKey];
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
if (nullArtistCount > 0) {
yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
}
}
}
if (tagsInput.getAttribute('disabled') !== 'disabled') {
if (data.tags === false) {
tagsInput.value = '';
} else {
const tagsArray = data.tag_string.split(', ');
const tagsUnique = tagsArray.filter((element, index, self) => index === self.indexOf(element));
tagsInput.value = tagsUnique.join(',').toLowerCase();
}
}
if (yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
if (labelInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.label,
labelInput,
data.label !== false,
);
}
if (catalogInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
}
if (mediaInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.format,
mediaInput,
data.format !== false,
);
}
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.releaseType,
releaseTypeInput,
data.releaseType !== false,
);
}
};
return f;
}
case 'ops_upload': {
// eslint-disable-next-line complexity
const f = function (rawData) {
let albumTitleInput;
let yearInput;
let labelInput;
let catalogInput;
if (currentTarget === 'other') {
const remaster = document.querySelector('#remaster');
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#remaster_year');
labelInput = document.querySelector('#remaster_record_label');
catalogInput = document.querySelector('#remaster_catalogue_number');
remaster.checked = 'checked';
unsafeWindow.Remaster(); // eslint-disable-line new-cap
unsafeWindow.CheckYear(); // eslint-disable-line new-cap
} else {
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#year');
labelInput = document.querySelector('#record_label');
catalogInput = document.querySelector('#catalogue_number');
}
if (/itunes/.test(rawData.url)) {
const releaseTypeInput = document.querySelector('#releasetype');
switch (true) {
case /.+ - Single$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - Single$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 9;
}
break;
case /.+ - EP$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - EP$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 5;
}
break;
default:
break;
}
}
let artistInputs = document.getElementsByName('artists[]');
const tagsInput = document.querySelector('#tags');
const data = yadg.prepareRawResponse(rawData);
let nullArtistCount = 0;
if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('artists[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
if (artistKey === 'null') {
nullArtistCount++;
continue;
}
const artistTypes = data.artists[artistKey];
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
if (nullArtistCount > 0) {
yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
}
}
}
if (tagsInput.getAttribute('disabled') !== 'disabled') {
if (data.tags === false) {
tagsInput.value = '';
} else {
const tagsArray = data.tag_string.split(', ');
const tagsUnique = tagsArray.filter((element, index, self) => index === self.indexOf(element));
tagsInput.value = tagsUnique.join(',').toLowerCase();
}
}
if (yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
if (labelInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.label,
labelInput,
data.label !== false,
);
}
if (catalogInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
}
};
return f;
}
case 'dic_upload': {
// eslint-disable-next-line complexity
const f = function (rawData) {
let albumTitleInput;
let yearInput;
let labelInput;
let catalogInput;
if (currentTarget === 'other') {
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#remaster_year');
labelInput = document.querySelector('#remaster_record_label');
catalogInput = document.querySelector('#remaster_catalogue_number');
unsafeWindow.CheckYear(); // eslint-disable-line new-cap
} else {
const unknownCheckbox = document.querySelector('#unknown');
albumTitleInput = document.querySelector('#title');
yearInput = document.querySelector('#year');
unknownCheckbox.checked = 'checked';
unsafeWindow.ToggleUnknown(); // eslint-disable-line new-cap
}
const releaseTypeInput = document.querySelector('#releasetype');
if (/itunes/.test(rawData.url)) {
switch (true) {
case /.+ - Single$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - Single$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 9;
}
break;
case /.+ - EP$/.test(rawData.title):
rawData.title = rawData.title.replace(/ - EP$/, '');
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
releaseTypeInput.value = 5;
}
break;
default:
break;
}
}
let artistInputs = document.getElementsByName('artists[]');
const tagsInput = document.querySelector('#tags');
const data = yadg.prepareRawResponse(rawData);
let nullArtistCount = 0;
if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('artists[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
if (artistKey === 'null') {
nullArtistCount++;
continue;
}
const artistTypes = data.artists[artistKey];
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
if (nullArtistCount > 0) {
yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
}
}
}
if (tagsInput.getAttribute('disabled') !== 'disabled') {
if (data.tags === false) {
tagsInput.value = '';
} else {
const tagsArray = data.tag_string.split(', ');
const tagsUnique = tagsArray.filter((element, index, self) => index === self.indexOf(element));
tagsInput.value = tagsUnique.join(',').toLowerCase();
}
}
if (yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
if (labelInput && labelInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.label,
labelInput,
data.label !== false,
);
}
if (catalogInput && catalogInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
}
if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(
data.releaseType,
releaseTypeInput,
data.releaseType !== false,
);
}
};
return f;
}
case 'ops_edit':
case 'dic_edit':
case 'pth_edit': {
const f = function (rawData) {
const [summaryInput] = document.getElementsByName('summary');
const [yearInput] = document.getElementsByName('year');
const [labelInput] = document.getElementsByName('record_label');
const [catalogInput] = document.getElementsByName('catalogue_number');
const data = yadg.prepareRawResponse(rawData);
summaryInput.value = 'YADG Update';
if (yearInput && yearInput.getAttribute('disabled') !== 'disabled') {
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
}
if (
labelInput
&& labelInput.getAttribute('disabled') !== 'disabled'
) {
yadgUtil.setValueIfSet(
data.label,
labelInput,
data.label !== false,
);
}
if (
catalogInput
&& catalogInput.getAttribute('disabled') !== 'disabled'
) {
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
}
};
return f;
}
case 'ops_torrent_overview':
case 'dic_torrent_overview':
case 'pth_torrent_overview': {
const f = function (rawData) {
let artistInputs = document.getElementsByName('aliasname[]');
const data = yadg.prepareRawResponse(rawData);
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('aliasname[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
const artistTypes = data.artists[artistKey];
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
}
};
return f;
}
case 'ops_request':
case 'ops_request_edit':
case 'dic_request':
case 'dic_request_edit':
case 'pth_request':
case 'pth_request_edit': {
const f = function (rawData) {
let artistInputs = document.getElementsByName('artists[]');
const [albumTitleInput] = document.getElementsByName('title');
const [yearInput] = document.getElementsByName('year');
const [labelInput] = document.getElementsByName('recordlabel');
const [catalogInput] = document.getElementsByName('cataloguenumber');
const tagsInput = document.querySelector('#tags');
const data = yadg.prepareRawResponse(rawData);
let nullArtistCount = 0;
if (!/groupid=\d+/.test(document.location.search)) {
if (data.artists === false) {
for (const element of artistInputs) {
element.value = '';
}
} else {
let inputIdx = 0;
yadgUtil.addRemoveArtistBoxes(
data.effective_artist_count - artistInputs.length,
);
artistInputs = document.getElementsByName('artists[]');
for (let i = 0; i < data.artist_keys.length; i++) {
const artistKey = data.artist_keys[i];
const artistTypes = data.artists[artistKey];
if (artistKey === 'null') {
nullArtistCount++;
continue;
}
for (const artistType of artistTypes) {
const artistInput = artistInputs[inputIdx];
let typeSelect = artistInput.nextSibling;
while (typeSelect.tagName !== 'SELECT') {
typeSelect = typeSelect.nextSibling;
}
artistInput.value = artistKey;
const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
switch (artistType) {
case 'main': {
typeSelect.selectedIndex = optionOffsets[1];
break;
}
case 'guest': {
typeSelect.selectedIndex = optionOffsets[2];
break;
}
case 'remixer': {
typeSelect.selectedIndex = optionOffsets[3];
break;
}
default: {
// We don't know this artist type, default to "main"
typeSelect.selectedIndex = optionOffsets[1];
}
}
// Next artist input
inputIdx += 1;
}
}
if (nullArtistCount > 0) {
yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
}
}
tagsInput.value = data.tags === false ? '' : data.tag_string.toLowerCase();
yadgUtil.setValueIfSet(
data.title,
albumTitleInput,
data.title !== false,
);
}
yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
yadgUtil.setValueIfSet(data.label, labelInput, data.label !== false);
yadgUtil.setValueIfSet(
data.catalog,
catalogInput,
data.catalog !== false,
);
};
return f;
}
default:
// That should actually never happen
return function () {};
}
},
};
yadgTemplates = {
_templates: {},
_templateUrls: {},
getTemplate(id, callback) {
if (id in this._templates) {
callback(this._templates[id]);
} else if (id in this._templateUrls) {
const request = new Requester(
this._templateUrls[id],
'GET',
template => {
yadgTemplates.addTemplate(template);
callback(template);
},
null,
yadgTemplates.errorTemplate,
);
request.send();
} else {
this.errorTemplate();
}
},
addTemplate(template) {
this._templates[template.id] = template;
},
addTemplateUrl(id, url) {
this._templateUrls[id] = url;
},
errorTemplate() {
yadg.printError('Could not get template. Please choose another one.', true);
},
};
yadgRenderer = {
_lastData: null,
_lastTemplateId: null,
render(templateId, data, callback, errorCallback) {
this._lastData = data;
const newTemplate = this._lastTemplateId !== templateId;
this._lastTemplateId = templateId;
yadgTemplates.getTemplate(templateId, template => {
// The new template might have different dependencies, so initialize Swig with those
if (newTemplate) {
yadgSandbox.resetSandbox();
yadgSandbox.initializeSwig(template.dependencies);
}
template.code = template.code.replace(
'https://what.cd',
'https://' + window.location.hostname,
);
yadgSandbox.renderTemplate(template.code, data, callback, errorCallback);
});
},
renderCached(templateId, callback, errorCallback) {
if (this.hasCached()) {
this.render(templateId, this._lastData, callback, errorCallback);
}
},
hasCached() {
return this._lastData !== null;
},
clearCached() {
this._lastData = null;
},
};
yadg = {
yadgHost: 'https://yadg.cc',
baseURI: '/api/v2/',
standardError:
'Sorry, an error occured. Please try again. If this error persists check on <a href="https://yadg.cc">yadg.cc</a> before reporting an error with the userscript.',
authenticationError:
'Your API token is invalid. Please provide a valid API token or remove the current one.',
lastStateError: false,
isBusy: false,
init() {
this.scraperSelect = document.querySelector('#yadg_scraper');
this.formatSelect = document.querySelector('#yadg_format');
this.input = document.querySelector('#yadg_input');
this.targetSelect = document.querySelector('#yadg_target');
this.targetDescriptionSelect = document.querySelector(
'#yadg_description_target',
);
this.responseDiv = document.querySelector('#yadg_response');
this.button = document.querySelector('#yadg_submit');
},
getBaseURL() {
return this.yadgHost + this.baseURI;
},
getScraperList(callback) {
const url = this.getBaseURL() + 'scrapers/';
const request = new Requester(url, 'GET', callback);
request.send();
},
getFormatsList(callback) {
const url = this.getBaseURL() + 'templates/';
this.getTemplates(url, [], callback);
},
getTemplates(url, templates, callback) {
const request = new Requester(url, 'GET', data => {
for (let i = 0; i < data.results.length; i++) {
templates.push(data.results[i]);
}
if (data.next === null) {
callback(templates);
} else {
yadg.getTemplates(data.next, templates, callback);
}
});
request.send();
},
makeRequest(parameters) {
if (this.isBusy) {
return;
}
let data;
if (parameters) {
data = parameters;
} else {
// If beta.musicbrainz.org link strip query params and remove beta
if (this.input.value.includes('beta.musicbrainz.org')) {
this.input.value = this.input.value.replace(/beta./, '');
this.input.value = this.input.value.replace(/\?.*$/, '');
}
data = {
scraper: this.scraperSelect.options[this.scraperSelect.selectedIndex]
.value,
input: this.input.value,
};
}
const url = this.getBaseURL() + 'query/';
if (data.input !== '') {
const request = new Requester(
url,
'POST',
result => {
yadg.getResult(result.url);
},
data,
);
this.busyStart();
request.send();
}
},
getResult(resultUrl) {
const request = new Requester(resultUrl, 'GET', response => {
if (response.status === 'done') {
switch (response.data.type) {
case 'ReleaseResult': {
const templateId
= yadg.formatSelect.options[yadg.formatSelect.selectedIndex].value;
yadgRenderer.render(
templateId,
response,
factory.setDescriptionBoxValue,
factory.setDescriptionBoxValue,
);
if (yadg.lastStateError === true) {
yadg.responseDiv.innerHTML = '';
yadg.lastStateError = false;
}
const fillFunc = factory.getFormFillFunction();
fillFunc(response.data);
break;
}
case 'ListResult': {
const ul = document.createElement('ul');
ul.id = 'yadg_release_list';
const releaseList = response.data.items;
for (const element of releaseList) {
const {name, info, queryParams} = element;
const releaseUrl = element.url;
if (name.match(/ううううううう/)) {
continue;
}
const li = document.createElement('li');
const a = document.createElement('a');
a.textContent = name;
a.params = queryParams;
a.href = releaseUrl;
a.addEventListener(
'click',
function (event) {
event.preventDefault();
yadg.makeRequest(this.params);
if (factory.getFetchImageCheckbox().checked) {
fetchImage(this.href, data => {
insertImage(data, () => {
if (
factory.getAutoRehostCheckbox()
&& factory.getAutoRehostCheckbox().checked
) {
pthImgIt();
}
});
});
}
},
false,
);
li.append(a);
li.append(document.createElement('br'));
if (info) {
li.append(document.createTextNode(info));
}
ul.append(li);
}
if (ul.childNodes.length === 0) {
yadg.printError('Sorry, there were no matches.');
} else {
yadg.responseDiv.innerHTML = '';
yadg.responseDiv.append(ul);
yadg.lastStateError = false;
// We got a ListResult so clear the last ReleaseResult from the render cache
yadgRenderer.clearCached();
}
break;
}
case 'NotFoundResult': {
yadg.printError(
'I could not find the release with the given ID. You may want to try again with another one.',
);
break;
}
default: {
yadg.printError('Something weird happened. Please try again');
}
}
yadg.busyStop();
} else if (response.status === 'failed') {
yadg.failedCallback();
} else {
const delay = function () {
yadg.getResult(response.url);
};
window.setTimeout(delay, 1000);
}
});
request.send();
},
printError(message, templateError) {
this.responseDiv.innerHTML = message;
if (!templateError) {
this.lastStateError = true;
// There was a non template related error, so for consistencies sake clear the last ReleaseResult from the
// render cache
yadgRenderer.clearCached();
}
},
failedCallback() {
yadg.printError(yadg.standardError);
yadg.busyStop();
},
failedAuthenticationCallback() {
yadg.printError(yadg.authenticationError);
yadg.busyStop();
},
busyStart() {
this.isBusy = true;
this.button.setAttribute('disabled', true);
this.button.value = 'Please wait...';
this.input.setAttribute('disabled', true);
this.scraperSelect.setAttribute('disabled', true);
this.formatSelect.setAttribute('disabled', true);
this.targetSelect.setAttribute('disabled', true);
},
busyStop() {
this.button.removeAttribute('disabled');
this.button.value = 'Fetch';
this.input.removeAttribute('disabled');
this.scraperSelect.removeAttribute('disabled');
this.formatSelect.removeAttribute('disabled');
this.targetSelect.removeAttribute('disabled');
this.isBusy = false;
},
// eslint-disable-next-line complexity
prepareRawResponse(rawData) {
const result = {};
result.artists = false;
result.year = false;
result.title = false;
result.label = false;
result.catalog = false;
result.genre = false;
result.style = false;
result.tags = false;
result.is_various = false; // eslint-disable-line camelcase
result.flat_artistString = false; // eslint-disable-line camelcase
result.format = false;
result.releaseType = false;
if (rawData.artists.length > 0) {
result.artists = {};
for (let i = 0; i < rawData.artists.length; i++) {
const artist = rawData.artists[i];
if (artist.isVarious) {
result.is_various = true; // eslint-disable-line camelcase
} else {
result.artists[artist.name] = artist.types;
}
}
}
if (rawData.discs.length > 0) {
for (let k = 0; k < rawData.discs.length; k++) {
const disc = rawData.discs[k];
for (let l = 0; l < disc.tracks.length; l++) {
const track = disc.tracks[l];
for (let m = 0; m < track.artists.length; m++) {
const {name} = track.artists[m];
const type = track.artists[m].types;
let newTypes = null;
if (name in result.artists) {
newTypes = result.artists[name].concat(type);
// Deduplicate new types array
for (let i = 0; i < newTypes.length; ++i) {
for (let j = i + 1; j < newTypes.length; ++j) {
if (newTypes[i] === newTypes[j]) {
newTypes.splice(j--, 1);
}
}
}
} else {
newTypes = type;
}
result.artists[name] = newTypes;
}
}
}
}
for (let i = 0; i < rawData.releaseEvents.length; i++) {
const event = rawData.releaseEvents[i];
if (event.date) {
[result.year] = event.date.match(/\d{4}/);
if (result.year.length === 4) {
break;
} else {
result.year = false;
}
}
}
if (rawData.title) {
result.title = rawData.title;
}
if (rawData.labelIds.length > 0) {
const [labelId] = rawData.labelIds;
if (labelId.label) {
result.label = labelId.label;
}
if (labelId.catalogueNrs.length > 0) {
[result.catalog] = labelId.catalogueNrs;
}
}
if (rawData.genres.length > 0) {
result.genre = rawData.genres;
}
if (rawData.styles.length > 0) {
result.style = rawData.styles;
}
if (result.genre !== false && result.style !== false) {
result.tags = rawData.genres.concat(rawData.styles);
} else if (result.genre !== false) {
result.tags = rawData.genres;
} else if (result.style !== false) {
result.tags = rawData.styles;
}
if (result.tags !== false) {
result.tag_string = ''; // eslint-disable-line camelcase
result.tag_string_nodots = ''; // eslint-disable-line camelcase
for (let i = 0; i < result.tags.length; i++) {
switch (result.tags[i]) {
case 'Techno (Peak Time / Driving)':
result.tags[i] = 'Techno';
break;
case 'Techno (Raw / Deep / Hypnotic)':
result.tags[i] = 'Dub Techno';
break;
case 'Minimal / Deep Tech':
result.tags[i] = 'Tech House';
break;
default:
break;
}
result.tag_string += result.tags[i].replace(/\s+/g, '.').replace(/\bn\b|&/, 'and'); // eslint-disable-line camelcase
result.tag_string_nodots += result.tags[i].replace(/\s+/g, ' '); // eslint-disable-line camelcase
if (i !== result.tags.length - 1) {
result.tag_string += ', '; // eslint-disable-line camelcase
result.tag_string_nodots += ', '; // eslint-disable-line camelcase
}
}
}
if (result.artists !== false) {
// Count the artists
result.artists_length = 0; // eslint-disable-line camelcase
result.artist_keys = []; // eslint-disable-line camelcase
result.effective_artist_count = 0; // eslint-disable-line camelcase
for (const i in result.artists) {
if (Object.prototype.hasOwnProperty.call(result.artists, i)) {
result.artists_length++;
result.artist_keys.push(i);
result.effective_artist_count += result.artists[i].length; // eslint-disable-line camelcase
}
}
}
if (result.artists_length === 0) {
result.artists = false;
} else {
// Create a flat string of all the main artists
let artistString = '';
for (let i = 0; i < result.artists_length; i++) {
if (result.artists[result.artist_keys[i]].includes('main')) {
if (artistString !== '' && i < result.artists_length - 2) {
artistString += ', ';
} else if (artistString !== '' && i < result.artists_length - 1) {
artistString += ' & ';
}
artistString += result.artist_keys[i];
}
}
result.flat_artistString = artistString; // eslint-disable-line camelcase
}
if (rawData.format) {
const format = rawData.format.toLowerCase();
if (format.includes('vinyl')) {
result.format = 'Vinyl';
} else if (format.includes('cd')) {
result.format = 'CD';
} else if (format.includes('dvd') || format.includes('dvd-video')) {
result.format = 'DVD';
} else if (format.includes('sacd')) {
result.format = 'SACD';
} else if (format.includes('cassettes')) {
result.format = 'Cassette';
} else if (format.includes('Blu-ray')) {
result.format = 'Blu-Ray';
} else if (format.includes('file')) {
result.format = 'WEB';
}
}
if (rawData.format) {
const format = rawData.format.toLowerCase();
if (format.includes('album') || rawData.styles.includes('Album')) {
result.releaseType = 1;
} else if (format.includes('soundtrack') || rawData.styles.includes('Soundtrack')) {
result.releaseType = 3;
} else if (format.includes('ep') || rawData.styles.includes('EP')) {
result.releaseType = 5;
} else if (format.includes('anthology') || rawData.styles.includes('Anthology')) {
result.releaseType = 6;
} else if (format.includes('compilation') || rawData.styles.includes('Compilation')) {
result.releaseType = 7;
} else if (format.includes('single') || rawData.styles.includes('Single')) {
result.releaseType = 9;
}
}
return result;
},
};
yadgSandbox.init(() => {
if (factory.init()) {
// Returns true if we run on a valid location
yadg.init();
}
});