// ==UserScript==
// @id dic-yadg
// @name DIC YADG
// @description This script provides integration with online description generator YADG (http://yadg.cc)
// @license https://github.com/gbmf/yadg-pth-userscript/blob/master/license
// @version 1.0.3
// @namespace yadg
// @grant GM_xmlhttpRequest
// @grant GM.xmlHttpRequest
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.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*://*notwhat.cd/upload.php*
// @include http*://*notwhat.cd/requests.php*
// @include http*://*notwhat.cd/torrents.php*
// @include http*://*dicmusic.club/upload.php*
// @include http*://*dicmusic.club/requests.php*
// @include http*://*dicmusic.club/torrents.php*
// @include http*://*waffles.ch/upload.php*
// @include http*://*waffles.ch/requests.php*
// @downloadURL https://update.greasyfork.icu/scripts/385596/DIC%20YADG.user.js
// @updateURL https://update.greasyfork.icu/scripts/385596/DIC%20YADG.meta.js
// ==/UserScript==
// --------- USER SETTINGS START ---------
/* 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' */
var JSandbox = (function () {
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()
}
sandbox[$worker] = new Worker(Sandbox.url);
sandbox[$requests] = {};
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;
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] = {};
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
});
/*
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;
let autoPreview;
let descriptionTarget; // eslint-disable-line no-unused-vars
// --------- USER SETTINGS END ---------
function fetchImage(target, callback) {
const dontReplaceCover = document.getElementsByName('image')[0].value;
if (/imgur|ptpimg/g.test(dontReplaceCover)) {
return;
}
const imgElement = document.querySelector('#image');
if (imgElement && imgElement.getAttribute('disabled') === 'disabled') {
return;
}
let link;
if (target === null) {
link = unsafeWindow.$('#yadg_input').val();
} else {
link = 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;
if (typeof callback === 'function') {
callback(
JSON.parse(
container
.querySelectorAll(
'div.image_gallery.image_gallery_large'
)[0]
.getAttribute('data-images')
)[0].full
);
}
}
}
});
break;
case /music.apple/.test(link): {
const regex = /apple\.com\/(?:([a-z]{2,3})\/)?.*\/(?:(\d+)|id(\d*))/;
const res = regex.exec(link);
const id = res[2] | res[3];
let country = 'us';
if (res[1]) {
[, country] = res;
}
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);
let hires;
const settingCover = factory.getCoverSize().value;
if (settingCover === 'large') {
hires = data.results[0].artworkUrl100.replace(
'100x100bb',
'100000x100000-999'
);
} else {
hires = data.results[0].artworkUrl100.replace(
'100x100bb',
'700x700bb'
);
}
if (typeof callback === 'function') {
callback(hires);
}
}
}
});
break;
}
case /bandcamp/.test(link):
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 [imgElem] = container.querySelectorAll(
'#tralbumArt > a > img'
);
if (!imgElem) {
if (typeof callback === 'function') {
callback(false);
}
return false;
}
let originalImg;
const scaledImg = imgElem.src;
const settingCover = factory.getCoverSize().value;
if (settingCover === 'large') {
originalImg = scaledImg.replace(/_16/, '_0');
} else {
originalImg = scaledImg.replace(/_16/, '_10');
}
const tempImg = new Image();
tempImg.src = originalImg;
tempImg.addEventListener('load', function () {
if (this.width === this.height) {
img = originalImg;
} else {
img = 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);
let cover;
const settingCover = factory.getCoverSize().value;
if (settingCover === 'large') {
cover = data.cover_xl.replace(
'1000x1000-000000-80-0-0.jpg',
'1400x1400-000000-100-0-0.jpg'
);
} else {
cover = data.cover_xl;
}
if (typeof callback === 'function') {
callback(cover);
}
}
}
});
break;
}
default:
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',
'
Album Art Preview: '
);
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',
''
);
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',
'Album Art Preview: '
);
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(applicationPrefix) {
'use strict';
if (applicationPrefix === 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 applicationPrefix === 'string' ?
applicationPrefix :
JSON.stringify(applicationPrefix);
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) {
const that = this;
try {
const checkedKey = makeChecks(key);
const combinedKey = that.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) {
const that = this;
let result;
try {
const checkedKey = makeChecks(key);
const combinedKey = that.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) {
const that = this;
let result = false;
try {
const checkedKey = makeChecks(key);
const combinedKey = that.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 () {
const that = this;
try {
const allKeys = that.getAllKeys();
for (let i = 0; i < allKeys.length; ++i) {
const checkedKey = makeChecks(allKeys[i]);
const combinedKey = that.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
document.body.removeChild(script); // 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) {
if (cond) {
input.value = value;
} else {
input.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(err) {
error(err);
}
});
},
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: '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: 'nwcd_upload',
regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/upload\.php.*/i
},
{
name: 'nwcd_edit',
regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/torrents\.php\?action=editgroup&groupid=.*/i
},
{
name: 'nwcd_request',
regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/requests\.php\?action=new/i
},
{
name: 'nwcd_request_edit',
regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/requests\.php\?action=edit&id=.*/i
},
{
name: 'nwcd_torrent_overview',
regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/torrents\.php\?id=.*/i
},
{
name: 'dic_upload',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/upload\.php.*/i
},
{
name: 'dic_edit',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/torrents\.php\?action=editgroup&groupid=.*/i
},
{
name: 'dic_request',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/requests\.php\?action=new/i
},
{
name: 'dic_request_edit',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/requests\.php\?action=edit&id=.*/i
},
{
name: 'dic_torrent_overview',
regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/torrents\.php\?id=.*/i
},
{
name: 'waffles_upload',
regex: /http(s)?:\/\/(.*\.)?waffles\.ch\/upload\.php.*/i
},
{
name: 'waffles_request',
regex: /http(s)?:\/\/(.*\.)?waffles\.ch\/requests\.php\?do=add/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',
e => {
e.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', e => {
e.preventDefault();
const optionsDiv = document.querySelector('#yadg_options');
const {display} = optionsDiv.style;
if (display === 'none' || display === '') {
optionsDiv.style.display = 'block';
} else {
optionsDiv.style.display = '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;
if (display === 'none' || display === '') {
optionsCoverSize.style.display = 'block';
} else {
optionsCoverSize.style.display = '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 for the target select
// var targetSelect = this.getTargetSelect();
// if (targetSelect !== null) {
// targetSelect.addEventListener('change', function (e) {
// var target = this.value;
// });
// }
// add the action to the save settings link
const saveSettingsLink = document.querySelector('#yadg_save_settings');
if (saveSettingsLink !== null) {
saveSettingsLink.addEventListener('click', e => {
e.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', e => {
e.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 ||
new Date().getTime() - 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)) {
[
'artists[]',
'importance[]',
'title',
'releasetype',
'genre_tags',
'tags'
].forEach(i => {
document.getElementsByName(i).forEach(i => {
i.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',
'pth_request',
'ops_upload',
'ops_request',
'nwcd_upload',
'nwcd_request',
'dic_upload',
'dic_request',
'waffles_upload',
'waffles_upload_new',
'waffles_request'
];
for (let i = 0; i < locations.length; i++) {
const loc = locations[i];
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);
autoRehost = yadgUtil.settings.getItem(factory.KEY_AUTO_REHOST);
autoPreview = yadgUtil.settings.getItem(factory.KEY_AUTO_PREVIEW);
descriptionTarget = yadgUtil.settings.getItem(factory.KEY_AUTO_PREVIEW);
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 && window.location.href.match(/\/upload\.php/)) {
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';
}
}
},
// eslint-disable-next-line complexity
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;
if (autoRehostCheckbox) {
autoRehost = autoRehostCheckbox.checked;
}
if (window.location.href.match(/\/upload\.php/)) {
autoPreview = autoPreviewCheckbox.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 if (!autoPreview && window.location.href.match(/\/upload\.php/)) {
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 replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
let replaceDesc = false;
if (replaceDescCheckbox !== null) {
replaceDesc = replaceDescCheckbox.checked;
}
if (descBox !== null && !Array.isArray(descBox)) {
if (descBox.getAttribute('disabled') === 'disabled') {
return;
}
if (!replaceDesc && /\S/.test(descBox.value)) {
// Check if the current description contains more than whitespace
descBox.value += '\n\n' + value;
} else {
descBox.value = value;
}
if (
factory.currentLocation !== 'pth_torrent_overview' ||
'ops_torrent_overview'
) {
if (descBox.parentNode.nextSibling.nextSibling) {
const previewBtn =
descBox.parentNode.nextSibling.nextSibling.firstChild.nextSibling;
if (
previewBtn &&
previewBtn.value === 'Preview' &&
factory.getAutoPreviewCheckbox().checked
) {
previewBtn.click();
}
}
}
} else if (Array.isArray(descBox)) {
for (let i = 0; i < descBox.length; i++) {
if (descBox[i].getAttribute('disabled') === 'disabled') {
continue;
}
descBox[i].value = value;
const previewBtn =
descBox[i].parentNode.nextSibling.nextSibling.firstChild.nextSibling;
if (
previewBtn &&
previewBtn.value === 'Preview' &&
factory.getAutoPreviewCheckbox().checked
) {
previewBtn.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) {
case 'waffles_upload':
case 'waffles_upload_new':
case 'waffles_request':
formatSelect.selectedIndex = formatOffsets[defaultWafflesFormat];
break;
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);
if (defaultTarget !== null && defaultTarget in targetOffsets) {
targetSelect.selectedIndex = targetOffsets[defaultTarget];
} else {
targetSelect.selectedIndex = 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 (let i = 0; i < templates.length; i++) {
if (factory.UPDATE_PROGRESS > 0) {
if (templates[i].name === 'What') {
templates[i].name = 'RED';
templates[i].nameFormatted = 'RED';
} else if (templates[i].name === 'What (Tracks only)') {
templates[i].name = 'RED (Tracks only)';
templates[i].nameFormatted = 'RED (Tracks only)';
}
yadgTemplates.addTemplate(templates[i]);
saveTemplates.push({
id: templates[i].id,
url: templates[i].url,
name: templates[i].name,
nameFormatted: templates[i].nameFormatted,
owner: templates[i].owner,
default: templates[i].default,
isUtility: templates[i].isUtility
});
} else {
if (templates[i].name === 'What') {
templates[i].name = 'PTH';
templates[i].nameFormatted = 'PTH';
} else if (templates[i].name === 'What (Tracks only)') {
templates[i].name = 'PTH (Tracks only)';
templates[i].nameFormatted = 'PTH (Tracks only)';
}
yadgTemplates.addTemplateUrl(templates[i].id, templates[i].url);
}
if (!templates[i].isUtility) {
nonUtility.push(templates[i]);
}
}
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 (let i = 0; i < data.length; i++) {
// 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');
if ('nameFormatted' in data[i]) {
o.text = data[i].nameFormatted;
} else {
o.text = data[i].name;
}
o.value = data[i].value || data[i].id;
o.selected = data[i].default;
select.options[i] = o;
if (data[i].default) {
select.selectedIndex = i;
}
if (data[i].url) {
o.setAttribute('data-url', data[i].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 }'
);
// Location specific styles will go here
switch (this.currentLocation) {
case 'waffles_upload':
yadgUtil.addCSS(
'div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'
);
break;
case 'waffles_request':
yadgUtil.addCSS(
'div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'
);
break;
default:
break;
}
},
// eslint-disable-next-line complexity
getInputElements() {
const buttonHTML = ' ';
const scraperSelectHTML =
' ';
let optionsHTML =
'Template:
Edition: Original Other
Description: Album Release Both
Replace descriptions on this page
Auto fetch Album Art (Allmusic, Bandcamp, Beatport, Deezer, Discogs, iTunes, Junodownload, Metal-Archives, MusicBrainz)
';
optionsHTML +=
'
Cover size: Large Medium
';
if (document.querySelectorAll('.rehost_it_cover')[0]) {
optionsHTML +=
'
';
}
if (window.location.href.match(/\/upload\.php/)) {
optionsHTML +=
'
Auto preview description
';
}
optionsHTML +=
'
Auto select the correct scraper when pasting the URL
';
optionsHTML +=
'
';
const inputHTML =
' ';
const responseDivHTML = '
';
const toggleOptionsLinkHTML =
'Toggle options ';
const scraperInfoLink =
'[?] ';
switch (this.currentLocation) {
case 'nwcd_upload':
case 'ops_upload':
case 'dic_upload':
case 'pth_upload': {
const tr = document.createElement('tr');
tr.className = 'yadg_tr';
tr.innerHTML =
'YADG: ' +
inputHTML +
scraperSelectHTML +
scraperInfoLink +
buttonHTML +
toggleOptionsLinkHTML +
optionsHTML +
responseDivHTML +
' ';
return tr;
}
case 'nwcd_edit':
case 'ops_edit':
case 'dic_edit':
case 'pth_edit': {
const div = document.createElement('div');
div.className = 'yadg_div';
div.innerHTML =
'YADG: \n' +
inputHTML +
'\n' +
scraperSelectHTML +
'\n' +
scraperInfoLink +
'\n' +
buttonHTML +
'\n' +
toggleOptionsLinkHTML +
'\n' +
optionsHTML +
'\n' +
responseDivHTML;
return div;
}
case 'nwcd_torrent_overview':
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 =
'YADG
\n