Advertisement
Lebon14

YADG (fixed)

Jul 24th, 2020
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 95.96 KB | None | 0 0
  1. // ==UserScript==
  2. // @id pth-yadg
  3. // @name RED YADG
  4. // @description This script provides integration with online description generator YADG (http://yadg.cc) - Credit to Slack06
  5. // @license https://github.com/SavageCore/yadg-pth-userscript/blob/master/LICENSE
  6. // @version 1.7.3
  7. // @namespace yadg
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM.xmlHttpRequest
  10. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  11. // @require https://yadg.cc/static/js/jsandbox.min.js
  12. // @include http*://*redacted.ch/upload.php*
  13. // @include http*://*redacted.ch/requests.php*
  14. // @include http*://*redacted.ch/torrents.php*
  15. // @include http*://*orpheus.network/upload.php*
  16. // @include http*://*orpheus.network/requests.php*
  17. // @include http*://*orpheus.network/torrents.php*
  18. // @include http*://*notwhat.cd/upload.php*
  19. // @include http*://*notwhat.cd/requests.php*
  20. // @include http*://*notwhat.cd/torrents.php*
  21. // @include http*://*dicmusic.club/upload.php*
  22. // @include http*://*dicmusic.club/requests.php*
  23. // @include http*://*dicmusic.club/torrents.php*
  24. // @include http*://*waffles.ch/upload.php*
  25. // @include http*://*waffles.ch/requests.php*
  26. // @downloadURL https://github.com/SavageCore/yadg-pth-userscript/raw/master/pth_yadg.user.js
  27. // ==/UserScript==
  28.  
  29. // --------- USER SETTINGS START ---------
  30.  
  31. /* global window unsafeWindow document GM JSandbox formatName AddArtistField RemoveArtistField Blob alert Image */
  32. /* eslint max-depth: ['off'], block-scoped-var: 'off', no-loop-func: 'off', no-alert: 'off' */
  33.  
  34. /*
  35. Here you can set site specific default templates.
  36. You can find a list of available templates at: https://yadg.cc/api/v2/templates/
  37. */
  38. const defaultPTHFormat = 5;
  39. const defaultWafflesFormat = 9;
  40. const defaultPTHTarget = 'other';
  41. const defaultPTHDescriptionTarget = 'album';
  42. let yadg; // eslint-disable-line prefer-const
  43. let factory; // eslint-disable-line prefer-const
  44. let yadgRenderer; // eslint-disable-line prefer-const
  45. let yadgTemplates; // eslint-disable-line prefer-const
  46. let autoRehost;
  47. let autoPreview;
  48. let descriptionTarget; // eslint-disable-line no-unused-vars
  49.  
  50. // --------- USER SETTINGS END ---------
  51.  
  52. function fetchImage(target, callback) {
  53. const dontReplaceCover = document.getElementsByName('image')[0].value;
  54. if (/imgur|ptpimg/g.test(dontReplaceCover)) {
  55. return;
  56. }
  57.  
  58. const imgElement = document.querySelector('#image');
  59. if (imgElement && imgElement.getAttribute('disabled') === 'disabled') {
  60. return;
  61. }
  62.  
  63. let link;
  64. if (target === null) {
  65. link = unsafeWindow.$('#yadg_input').val();
  66. } else {
  67. link = target;
  68. }
  69.  
  70. switch (true) {
  71. case /discogs/.test(link):
  72. GM.xmlHttpRequest({
  73. method: 'GET',
  74. url: link,
  75. onload(response) {
  76. if (response.status === 200) {
  77. const container = document.implementation.createHTMLDocument()
  78. .documentElement;
  79. container.innerHTML = response.responseText;
  80. if (typeof callback === 'function') {
  81. callback(
  82. JSON.parse(
  83. container
  84. .querySelectorAll(
  85. 'div.image_gallery.image_gallery_large'
  86. )[0]
  87. .getAttribute('data-images')
  88. )[0].full
  89. );
  90. }
  91. }
  92. }
  93. });
  94. break;
  95. case /music.apple/.test(link): {
  96. const regex = /apple\.com\/(?:([a-z]{2,3})\/)?.*\/(?:(\d+)|id(\d*))/;
  97. const res = regex.exec(link);
  98. const id = res[2] | res[3];
  99. let country = 'us';
  100. if (res[1]) {
  101. [, country] = res;
  102. }
  103.  
  104. GM.xmlHttpRequest({
  105. method: 'GET',
  106. url: 'https://itunes.apple.com/lookup?id=' + id + '&country=' + country,
  107. onload(response) {
  108. if (response.status === 200) {
  109. const data = JSON.parse(response.responseText);
  110. let hires;
  111. const settingCover = factory.getCoverSize().value;
  112. if (settingCover === 'large') {
  113. hires = data.results[0].artworkUrl100.replace(
  114. '100x100bb',
  115. '100000x100000-999'
  116. );
  117. } else {
  118. hires = data.results[0].artworkUrl100.replace(
  119. '100x100bb',
  120. '700x700bb'
  121. );
  122. }
  123.  
  124. if (typeof callback === 'function') {
  125. callback(hires);
  126. }
  127. }
  128. }
  129. });
  130. break;
  131. }
  132.  
  133. case /bandcamp/.test(link):
  134. case factory.getScraperSelect().value === 'bandcamp': {
  135. let img;
  136. GM.xmlHttpRequest({
  137. method: 'GET',
  138. url: link,
  139. onload(response) {
  140. if (response.status === 200) {
  141. const container = document.implementation.createHTMLDocument()
  142. .documentElement;
  143. container.innerHTML = response.responseText;
  144. const [imgElem] = container.querySelectorAll(
  145. '#tralbumArt > a > img'
  146. );
  147. if (!imgElem) {
  148. if (typeof callback === 'function') {
  149. callback(false);
  150. }
  151.  
  152. return false;
  153. }
  154.  
  155. let originalImg;
  156. const scaledImg = imgElem.src;
  157. const settingCover = factory.getCoverSize().value;
  158. if (settingCover === 'large') {
  159. originalImg = scaledImg.replace(/_16/, '_0');
  160. } else {
  161. originalImg = scaledImg.replace(/_16/, '_10');
  162. }
  163.  
  164. const tempImg = new Image();
  165. tempImg.src = originalImg;
  166. tempImg.addEventListener('load', function () {
  167. if (this.width === this.height) {
  168. img = originalImg;
  169. } else {
  170. img = scaledImg;
  171. }
  172.  
  173. if (typeof callback === 'function') {
  174. callback(img);
  175. }
  176. });
  177. }
  178. }
  179. });
  180. break;
  181. }
  182.  
  183. case /beatport/.test(link):
  184. GM.xmlHttpRequest({
  185. method: 'GET',
  186. url: link,
  187. onload(response) {
  188. if (response.status === 200) {
  189. const container = document.implementation.createHTMLDocument()
  190. .documentElement;
  191. container.innerHTML = response.responseText;
  192. if (typeof callback === 'function') {
  193. callback(
  194. container.querySelectorAll(
  195. 'div.interior-release-chart-artwork-parent > img'
  196. )[0].src
  197. );
  198. }
  199. }
  200. }
  201. });
  202. break;
  203. case /musicbrainz/.test(link): {
  204. const regex = /release\/(.*)/;
  205. const {1: id} = regex.exec(link);
  206. GM.xmlHttpRequest({
  207. headers: {
  208. 'User-Agent': 'YADG/1.4.41 (yadg.cc)'
  209. },
  210. method: 'GET',
  211. url: 'http://coverartarchive.org/release/' + id + '/',
  212. onload(response) {
  213. if (response.status === 200) {
  214. const data = JSON.parse(response.responseText);
  215. if (typeof callback === 'function') {
  216. callback(data.images[0].image);
  217. }
  218. }
  219. }
  220. });
  221. break;
  222. }
  223.  
  224. case /junodownload/.test(link):
  225. GM.xmlHttpRequest({
  226. method: 'GET',
  227. url: link,
  228. onload(response) {
  229. if (response.status === 200) {
  230. const container = document.implementation.createHTMLDocument()
  231. .documentElement;
  232. container.innerHTML = response.responseText;
  233. if (typeof callback === 'function') {
  234. callback(container.querySelector('.img-fluid-fill').src);
  235. }
  236. }
  237. }
  238. });
  239. break;
  240. case /metal-archives/.test(link):
  241. GM.xmlHttpRequest({
  242. method: 'GET',
  243. url: link,
  244. onload(response) {
  245. if (response.status === 200) {
  246. const container = document.implementation.createHTMLDocument()
  247. .documentElement;
  248. container.innerHTML = response.responseText;
  249.  
  250. const parser = document.createElement('a');
  251. parser.href = container.querySelectorAll('#cover > img')[0].src;
  252. const imgLink =
  253. parser.protocol + '//' + parser.hostname + parser.pathname;
  254. if (typeof callback === 'function') {
  255. callback(imgLink);
  256. }
  257. }
  258. }
  259. });
  260. break;
  261. case /allmusic/.test(link):
  262. GM.xmlHttpRequest({
  263. method: 'GET',
  264. url: link,
  265. onload(response) {
  266. if (response.status === 200) {
  267. const container = document.implementation.createHTMLDocument()
  268. .documentElement;
  269. container.innerHTML = response.responseText;
  270. const data = container.querySelector('[data-largeurl]');
  271. // No image available https://www.allmusic.com/album/release/beatles-mr0003843619
  272. if (data !== null) {
  273. const cover = data.getAttribute('data-largeurl');
  274. if (typeof callback === 'function') {
  275. callback(cover);
  276. }
  277. }
  278. }
  279. }
  280. });
  281. break;
  282. case /deezer/.test(link): {
  283. const regex = /\.com\/(\w+\/)?(album)\/(\d+)/g;
  284. const helper = regex.exec(link);
  285. const id = helper[3];
  286. GM.xmlHttpRequest({
  287. method: 'GET',
  288. url: 'https://api.deezer.com/album/' + id,
  289. onload(response) {
  290. if (response.status === 200) {
  291. const data = JSON.parse(response.responseText);
  292. let cover;
  293. const settingCover = factory.getCoverSize().value;
  294. if (settingCover === 'large') {
  295. cover = data.cover_xl.replace(
  296. '1000x1000-000000-80-0-0.jpg',
  297. '1400x1400-000000-100-0-0.jpg'
  298. );
  299. } else {
  300. cover = data.cover_xl;
  301. }
  302.  
  303. if (typeof callback === 'function') {
  304. callback(cover);
  305. }
  306. }
  307. }
  308. });
  309. break;
  310. }
  311.  
  312. default:
  313. break;
  314. }
  315. }
  316.  
  317. function pthImgIt() {
  318. const [pthImgIt] = document.querySelectorAll('.rehost_it_cover');
  319. let imgElement;
  320.  
  321. switch (window.location.href) {
  322. case (window.location.href.match(/\/upload\.php/) || {}).input: {
  323. imgElement = document.querySelector('#image').value;
  324. break;
  325. }
  326.  
  327. case (window.location.href.match(/torrents\.php\?action=editgroup/) || {})
  328. .input: {
  329. imgElement = document.querySelectorAll(
  330. '#content > div > div:nth-child(2) > form > div > input[type="text"]:nth-child(5)'
  331. )[0].value;
  332. break;
  333. }
  334.  
  335. default:
  336. break;
  337. }
  338.  
  339. if (pthImgIt && imgElement) {
  340. pthImgIt.click();
  341. }
  342. }
  343.  
  344. function insertImage(img, callback) {
  345. switch (window.location.href) {
  346. case (window.location.href.match(/\/upload\.php/) || {}).input: {
  347. const input = document.querySelector('#image');
  348. input.value = img;
  349. if (input.getAttribute('autorehost') === 'true') {
  350. const evt = document.createEvent('HTMLEvents');
  351. evt.initEvent('keyup', false, true);
  352. input.dispatchEvent(evt);
  353. }
  354.  
  355. input.parentNode.parentNode.insertAdjacentHTML(
  356. 'beforebegin',
  357. '<tr id="yadg_image_preview_tr"><td class="label">Album Art Preview:</td><td><img id="yadg_image_preview" src="' +
  358. img +
  359. '" width="300px" /></tr></td>'
  360. );
  361. callback();
  362. break;
  363. }
  364.  
  365. case (window.location.href.match(/torrents\.php\?action=editgroup/) || {})
  366. .input: {
  367. const [imageInputElement] = document.querySelectorAll(
  368. '#content > div > div:nth-child(2) > form > div > input[type="text"]:nth-child(5)'
  369. );
  370. imageInputElement.value = img;
  371. imageInputElement.parentNode.insertAdjacentHTML(
  372. 'beforebegin',
  373. '<div id="yadg_image_preview_div"><img id="yadg_image_preview" src="' +
  374. img +
  375. '" width="300px" /></div>'
  376. );
  377. callback();
  378. break;
  379. }
  380.  
  381. case (window.location.href.match(/requests\.php\?/) || {}).input: {
  382. const [imageInputElement] = document.querySelectorAll(
  383. '#image_tr > td:nth-child(2) > input[type="text"]:nth-child(1)'
  384. );
  385. imageInputElement.value = img;
  386. imageInputElement.parentNode.parentNode.insertAdjacentHTML(
  387. 'beforebegin',
  388. '<tr id="yadg_image_preview_tr"><td class="label">Album Art Preview:</td><td><img id="yadg_image_preview" src="' +
  389. img +
  390. '" width="300px" /></tr></td>'
  391. );
  392. callback();
  393. break;
  394. }
  395.  
  396. default:
  397. break;
  398. }
  399. }
  400.  
  401. // --------- THIRD PARTY CODE AREA START ---------
  402.  
  403. //
  404. // Creates an object which gives some helper methods to
  405. // Save/Load/Remove data to/from the localStorage
  406. //
  407. // Source from: https://github.com/gergob/localstoragewrapper
  408. //
  409. function LocalStorageWrapper(applicationPrefix) {
  410. 'use strict';
  411.  
  412. if (applicationPrefix === undefined) {
  413. throw new Error('applicationPrefix parameter should be defined');
  414. }
  415.  
  416. const delimiter = '_';
  417.  
  418. // If the passed in value for prefix is not string, it should be converted
  419. const keyPrefix =
  420. typeof applicationPrefix === 'string' ?
  421. applicationPrefix :
  422. JSON.stringify(applicationPrefix);
  423.  
  424. const localStorage = window.localStorage || unsafeWindow.localStorage;
  425.  
  426. const isLocalStorageAvailable = function () {
  427. return typeof localStorage !== 'undefined';
  428. };
  429.  
  430. const getKeyPrefix = function () {
  431. return keyPrefix;
  432. };
  433.  
  434. //
  435. // validates if there is a prefix defined for the keys
  436. // and checks if the localStorage functionality is available or not
  437. //
  438. const makeChecks = function (key) {
  439. const prefix = getKeyPrefix();
  440. if (prefix === undefined) {
  441. throw new Error('No prefix was defined, data cannot be saved');
  442. }
  443.  
  444. if (!isLocalStorageAvailable()) {
  445. throw new Error(
  446. 'LocalStorage is not supported by your browser, data cannot be saved'
  447. );
  448. }
  449.  
  450. // Keys are always strings
  451. const checkedKey = typeof key === 'string' ? key : JSON.stringify(key);
  452.  
  453. return checkedKey;
  454. };
  455.  
  456. //
  457. // saves the value associated to the key into the localStorage
  458. //
  459. const addItem = function (key, value) {
  460. const that = this;
  461. try {
  462. const checkedKey = makeChecks(key);
  463. const combinedKey = that.getKeyPrefix() + delimiter + checkedKey;
  464. localStorage.setItem(combinedKey, JSON.stringify(value));
  465. } catch (error) {
  466. console.log(error);
  467. throw error;
  468. }
  469. };
  470.  
  471. //
  472. // gets the value of the object saved to the key passed as parameter
  473. //
  474. const getItem = function (key) {
  475. const that = this;
  476. let result;
  477. try {
  478. const checkedKey = makeChecks(key);
  479. const combinedKey = that.getKeyPrefix() + delimiter + checkedKey;
  480. const resultAsJSON = localStorage.getItem(combinedKey);
  481. result = JSON.parse(resultAsJSON);
  482. } catch (error) {
  483. console.log(error);
  484. throw error;
  485. }
  486.  
  487. return result;
  488. };
  489.  
  490. //
  491. // returns all the keys from the localStorage
  492. //
  493. const getAllKeys = function () {
  494. const prefix = getKeyPrefix();
  495. const results = [];
  496.  
  497. if (prefix === undefined) {
  498. throw new Error('No prefix was defined, data cannot be saved');
  499. }
  500.  
  501. if (!isLocalStorageAvailable()) {
  502. throw new Error(
  503. 'LocalStorage is not supported by your browser, data cannot be saved'
  504. );
  505. }
  506.  
  507. for (const key in localStorage) {
  508. if (key.indexOf(prefix) === 0) {
  509. const keyParts = key.split(delimiter);
  510. results.push(keyParts[1]);
  511. }
  512. }
  513.  
  514. return results;
  515. };
  516.  
  517. //
  518. // removes the value associated to the key from the localStorage
  519. //
  520. const removeItem = function (key) {
  521. const that = this;
  522. let result = false;
  523. try {
  524. const checkedKey = makeChecks(key);
  525. const combinedKey = that.getKeyPrefix() + delimiter + checkedKey;
  526. localStorage.removeItem(combinedKey);
  527. result = true;
  528. } catch (error) {
  529. console.log(error);
  530. throw error;
  531. }
  532.  
  533. return result;
  534. };
  535.  
  536. //
  537. // removes all the values from the localStorage
  538. //
  539. const removeAll = function () {
  540. const that = this;
  541.  
  542. try {
  543. const allKeys = that.getAllKeys();
  544. for (const key of allKeys) {
  545. const checkedKey = makeChecks(key);
  546. const combinedKey = that.getKeyPrefix() + delimiter + checkedKey;
  547. localStorage.removeItem(combinedKey);
  548. }
  549. } catch (error) {
  550. console.log(error);
  551. throw error;
  552. }
  553. };
  554.  
  555. // Make some of the functionalities public
  556. return {
  557. isLocalStorageAvailable,
  558. getKeyPrefix,
  559. addItem,
  560. getItem,
  561. getAllKeys,
  562. removeItem,
  563. removeAll
  564. };
  565. }
  566.  
  567. // --------- THIRD PARTY CODE AREA END ---------
  568.  
  569. const yadgUtil = {
  570. exec(fn) {
  571. const script = document.createElement('script');
  572. script.setAttribute('type', 'application/javascript');
  573. script.textContent = '(' + fn + ')();';
  574. document.body.append(script); // Run the script
  575. document.body.removeChild(script); // Clean up
  576. },
  577.  
  578. // Handle for updating page css, taken from one of hateradio's scripts
  579. addCSS(style) {
  580. if (!this.style) {
  581. this.style = document.createElement('style');
  582. this.style.type = 'text/css';
  583. (document.head || document.querySelectorAll('head')[0]).append(
  584. this.style
  585. );
  586. }
  587.  
  588. this.style.append(document.createTextNode(style + '\n'));
  589. },
  590.  
  591. setValueIfSet(value, input, cond) {
  592. if (cond) {
  593. input.value = value;
  594. } else {
  595. input.value = '';
  596. }
  597. },
  598.  
  599. // Negative count will remove, positive count will add given number of artist boxes
  600. addRemoveArtistBoxes(count) {
  601. if (count !== 0) {
  602. if (count < 0) {
  603. for (let i = 0; i < -count; i++) {
  604. yadgUtil.exec(() => {
  605. RemoveArtistField(); // eslint-disable-line new-cap
  606. });
  607. }
  608. } else {
  609. for (let i = 0; i < count; i++) {
  610. yadgUtil.exec(() => {
  611. AddArtistField(); // eslint-disable-line new-cap
  612. });
  613. }
  614. }
  615. }
  616. },
  617.  
  618. getOptionOffsets(select) {
  619. const optionOffsets = {};
  620. for (let j = 0; j < select.options.length; j++) {
  621. optionOffsets[select.options[j].value] = select.options[j].index;
  622. }
  623.  
  624. return optionOffsets;
  625. },
  626.  
  627. storage: new LocalStorageWrapper('yadg'),
  628.  
  629. settings: new LocalStorageWrapper('yadgSettings')
  630. };
  631.  
  632. // Very simple wrapper for XmlHttpRequest
  633. // eslint-disable-next-line max-params
  634. function Requester(url, method, callback, data, errorCallback) {
  635. this.data = data;
  636. this.url = url;
  637. this.method = method;
  638. if (!errorCallback) {
  639. errorCallback = yadg.failedCallback;
  640. }
  641.  
  642. this.send = function () {
  643. const details = {
  644. url: this.url,
  645. method: this.method,
  646. onload(response) {
  647. if (response.status === 200) {
  648. callback(JSON.parse(response.responseText));
  649. } else if (response.status === 401) {
  650. yadg.failedAuthenticationCallback();
  651. } else {
  652. errorCallback();
  653. }
  654. },
  655. onerror: errorCallback
  656. };
  657. if (method === 'POST') {
  658. details.data = JSON.stringify(this.data);
  659. }
  660.  
  661. const headers = {
  662. Accept: 'application/json',
  663. 'Content-Type': 'application/json'
  664. };
  665.  
  666. if (yadgUtil.settings.getItem(factory.KEY_API_TOKEN)) {
  667. headers.Authorization =
  668. 'Token ' + yadgUtil.settings.getItem(factory.KEY_API_TOKEN);
  669. }
  670.  
  671. details.headers = headers;
  672.  
  673. GM.xmlHttpRequest(details);
  674. };
  675. }
  676.  
  677. const yadgSandbox = {
  678. KEY_LAST_WARNING: 'templateLastWarning',
  679.  
  680. init(callback) {
  681. GM.xmlHttpRequest({
  682. method: 'GET',
  683. url: yadg.yadgHost + '/static/js/jsandbox-worker.js',
  684. onload(response) {
  685. let script;
  686. let dataURL = null;
  687. if (response.status === 200) {
  688. script = response.responseText;
  689. const blob = new Blob([script], {type: 'application/javascript'});
  690. const URL = window.URL || window.webkitURL;
  691. if (!URL || !URL.createObjectURL) {
  692. throw new Error(
  693. 'No no valid implementation of window.URL.createObjectURL found.'
  694. );
  695. }
  696.  
  697. dataURL = URL.createObjectURL(blob);
  698. yadgSandbox.initCallback(dataURL);
  699. yadgSandbox.loadSwig(callback);
  700. } else {
  701. yadgSandbox.initCallbackError();
  702. }
  703. },
  704. onerror() {
  705. yadgSandbox.initCallbackError();
  706. }
  707. });
  708. },
  709.  
  710. loadSwig(callback) {
  711. // ImportScripts for the web worker will not work in Firefox with cross-domain requests
  712. // see: https://bugzilla.mozilla.org/show_bug.cgi?id=756589
  713. // so download the Swig files manually with GM.xmlHttpRequest
  714. GM.xmlHttpRequest({
  715. method: 'GET',
  716. url: yadg.yadgHost + '/static/js/swig.min.js',
  717. onload(response) {
  718. if (response.status === 200) {
  719. yadgSandbox.swigScript = response.responseText;
  720.  
  721. GM.xmlHttpRequest({
  722. method: 'GET',
  723. url: yadg.yadgHost + '/static/js/swig.custom.js',
  724. onload(response) {
  725. if (response.status === 200) {
  726. yadgSandbox.swigCustomScript = response.responseText;
  727. callback();
  728. }
  729. }
  730. });
  731. }
  732. }
  733. });
  734. },
  735.  
  736. initializeSwig(dependencies) {
  737. if (!(this.swigScript && this.swigCustomScript)) {
  738. yadg.failedCallback();
  739. return;
  740. }
  741.  
  742. yadgSandbox.exec({data: this.swigScript, onerror: yadg.failedCallback});
  743. yadgSandbox.exec({
  744. data: this.swigCustomScript,
  745. onerror: yadg.failedCallback
  746. });
  747. yadgSandbox.exec({
  748. data:
  749. 'var myswig = new swig.Swig({ loader: swig.loaders.memory(input.templates), autoescape: false }), i=0; yadg_filters.register_filters(myswig);',
  750. input: {templates: dependencies}
  751. });
  752. },
  753.  
  754. renderTemplate(template, data, callback, error) {
  755. const evalString =
  756. 'myswig.render(input.template, { locals: input.data, filename: \'scratchpad\' + (i++) })';
  757. this.eval({
  758. data: evalString,
  759. callback(out) {
  760. callback(out);
  761. },
  762. input: {template, data},
  763. onerror(err) {
  764. error(err);
  765. }
  766. });
  767. },
  768.  
  769. initCallback(dataUrl) {
  770. JSandbox.url = dataUrl;
  771. this.jsandbox = new JSandbox();
  772. this.initError = false;
  773. },
  774.  
  775. resetSandbox() {
  776. this.jsandbox.terminate();
  777. this.jsandbox = new JSandbox();
  778. },
  779.  
  780. load(options) {
  781. this.jsandbox.load(options);
  782. },
  783.  
  784. exec(options) {
  785. this.jsandbox.exec(options);
  786. },
  787.  
  788. eval(options) {
  789. this.jsandbox.eval(options);
  790. },
  791.  
  792. initCallbackError() {
  793. this.initError = true;
  794.  
  795. const lastWarning = yadgUtil.storage.getItem(this.KEY_LAST_WARNING);
  796. const now = new Date();
  797. if (
  798. lastWarning === null ||
  799. now.getTime() - new Date(lastWarning).getTime() > factory.CACHE_TIMEOUT
  800. ) {
  801. console.log(
  802. '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.'
  803. );
  804. yadgUtil.storage.addItem(this.KEY_LAST_WARNING, now);
  805. }
  806. }
  807. };
  808.  
  809. factory = {
  810. // Storage keys for cache
  811. KEY_LAST_CHECKED: 'lastChecked',
  812. KEY_SCRAPER_LIST: 'scraperList',
  813. KEY_FORMAT_LIST: 'formatList',
  814.  
  815. // Storage keys for settings
  816. KEY_API_TOKEN: 'apiToken',
  817. KEY_DEFAULT_TEMPLATE: 'defaultTemplate',
  818. KEY_DEFAULT_TARGET: 'defaultTarget',
  819. KEY_DESCRIPTION_TARGET: 'descriptionTarget',
  820. KEY_DEFAULT_SCRAPER: 'defaultScraper',
  821. KEY_REPLACE_DESCRIPTION: 'replaceDescriptionOn',
  822. KEY_SETTINGS_INIT_VER: 'settingsInitializedVer',
  823. KEY_FETCH_IMAGE: 'fetchImage',
  824. KEY_AUTO_PREVIEW: 'autoPreview',
  825. KEY_AUTO_REHOST: 'autoRehost',
  826. KEY_AUTO_SELECT_SCRAPER: 'autoSelectScraper',
  827. KEY_COVER_SIZE: 'coverSize',
  828.  
  829. CACHE_TIMEOUT: 1000 * 60 * 60 * 24, // 24 hours
  830.  
  831. UPDATE_PROGRESS: 0,
  832. locations: [
  833. {
  834. name: 'pth_upload',
  835. regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/upload\.php.*/i
  836. },
  837. {
  838. name: 'pth_edit',
  839. regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/torrents\.php\?action=editgroup&groupid=.*/i
  840. },
  841. {
  842. name: 'pth_request',
  843. regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/requests\.php\?action=new/i
  844. },
  845. {
  846. name: 'pth_request_edit',
  847. regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/requests\.php\?action=edit&id=.*/i
  848. },
  849. {
  850. name: 'pth_torrent_overview',
  851. regex: /http(s)?:\/\/(.*\.)?redacted\.ch\/torrents\.php\?id=.*/i
  852. },
  853. {
  854. name: 'ops_upload',
  855. regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/upload\.php.*/i
  856. },
  857. {
  858. name: 'ops_edit',
  859. regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/torrents\.php\?action=editgroup&groupid=.*/i
  860. },
  861. {
  862. name: 'ops_request',
  863. regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/requests\.php\?action=new/i
  864. },
  865. {
  866. name: 'ops_request_edit',
  867. regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/requests\.php\?action=edit&id=.*/i
  868. },
  869. {
  870. name: 'ops_torrent_overview',
  871. regex: /http(s)?:\/\/(.*\.)?orpheus\.network\/torrents\.php\?id=.*/i
  872. },
  873. {
  874. name: 'nwcd_upload',
  875. regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/upload\.php.*/i
  876. },
  877. {
  878. name: 'nwcd_edit',
  879. regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/torrents\.php\?action=editgroup&groupid=.*/i
  880. },
  881. {
  882. name: 'nwcd_request',
  883. regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/requests\.php\?action=new/i
  884. },
  885. {
  886. name: 'nwcd_request_edit',
  887. regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/requests\.php\?action=edit&id=.*/i
  888. },
  889. {
  890. name: 'nwcd_torrent_overview',
  891. regex: /http(s)?:\/\/(.*\.)?notwhat\.cd\/torrents\.php\?id=.*/i
  892. },
  893. {
  894. name: 'dic_upload',
  895. regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/upload\.php.*/i
  896. },
  897. {
  898. name: 'dic_edit',
  899. regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/torrents\.php\?action=editgroup&groupid=.*/i
  900. },
  901. {
  902. name: 'dic_request',
  903. regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/requests\.php\?action=new/i
  904. },
  905. {
  906. name: 'dic_request_edit',
  907. regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/requests\.php\?action=edit&id=.*/i
  908. },
  909. {
  910. name: 'dic_torrent_overview',
  911. regex: /http(s)?:\/\/(.*\.)?dicmusic\.club\/torrents\.php\?id=.*/i
  912. },
  913. {
  914. name: 'waffles_upload',
  915. regex: /http(s)?:\/\/(.*\.)?waffles\.ch\/upload\.php.*/i
  916. },
  917. {
  918. name: 'waffles_request',
  919. regex: /http(s)?:\/\/(.*\.)?waffles\.ch\/requests\.php\?do=add/i
  920. }
  921. ],
  922.  
  923. determineLocation(uri) {
  924. for (let i = 0; i < this.locations.length; i++) {
  925. if (this.locations[i].regex.test(uri)) {
  926. return this.locations[i].name;
  927. }
  928. }
  929.  
  930. return null;
  931. },
  932.  
  933. init() {
  934. this.currentLocation = this.determineLocation(document.URL);
  935. // Only continue with the initialization if we found a valid location
  936. if (this.currentLocation === null) {
  937. return false;
  938. }
  939.  
  940. if (this.currentLocation === 'pth_request') {
  941. this.inputsOff(document.URL);
  942. }
  943.  
  944. this.insertIntoPage(this.getInputElements());
  945.  
  946. // Set the necessary styles
  947. this.setStyles();
  948.  
  949. // Make sure we initialize the settings to the most recent version
  950. this.initializeSettings();
  951.  
  952. // Populate settings inputs
  953. this.populateSettings();
  954.  
  955. // Add the appropriate action for the input textbox
  956. const input = document.querySelector('#yadg_input');
  957. input.addEventListener('input', () => {
  958. if (factory.getAutoSelectScraperCheckbox().checked) {
  959. const inputValue = input.value;
  960. const yadgScraper = document.querySelector('#yadg_scraper');
  961. if (/discogs/.test(inputValue)) {
  962. yadgScraper.value = 'discogs';
  963. } else if (/music.apple/.test(inputValue)) {
  964. yadgScraper.value = 'itunes';
  965. } else if (/bandcamp/.test(inputValue)) {
  966. yadgScraper.value = 'bandcamp';
  967. } else if (/beatport/.test(inputValue)) {
  968. yadgScraper.value = 'beatport';
  969. } else if (/musicbrainz/.test(inputValue)) {
  970. yadgScraper.value = 'musicbrainz';
  971. } else if (/junodownload/.test(inputValue)) {
  972. yadgScraper.value = 'junodownload';
  973. } else if (/metal-archives/.test(inputValue)) {
  974. yadgScraper.value = 'metalarchives';
  975. } else if (/deezer/.test(inputValue)) {
  976. yadgScraper.value = 'deezer';
  977. } else if (/allmusic/.test(inputValue)) {
  978. yadgScraper.value = 'allmusic';
  979. }
  980. }
  981. });
  982.  
  983. // Add the appropriate action for the button
  984. const button = document.querySelector('#yadg_submit');
  985. button.addEventListener(
  986. 'click',
  987. e => {
  988. e.preventDefault();
  989. yadg.makeRequest();
  990. if (factory.getFetchImageCheckbox().checked) {
  991. fetchImage(null, data => {
  992. if (data) {
  993. insertImage(data, () => {
  994. if (
  995. factory.getAutoRehostCheckbox() &&
  996. factory.getAutoRehostCheckbox().checked
  997. ) {
  998. pthImgIt();
  999. }
  1000. });
  1001. }
  1002. });
  1003. }
  1004. },
  1005. false
  1006. );
  1007.  
  1008. // Add the action for the options toggle
  1009. const toggleLink = document.querySelector('#yadg_toggle_options');
  1010. if (toggleLink !== null) {
  1011. toggleLink.addEventListener('click', e => {
  1012. e.preventDefault();
  1013.  
  1014. const optionsDiv = document.querySelector('#yadg_options');
  1015. const {display} = optionsDiv.style;
  1016.  
  1017. if (display === 'none' || display === '') {
  1018. optionsDiv.style.display = 'block';
  1019. } else {
  1020. optionsDiv.style.display = 'none';
  1021. }
  1022. });
  1023. }
  1024.  
  1025. // Add the action for the cover size select
  1026. const coverSizeSetting = document.querySelector('#yadg_options_image');
  1027. if (coverSizeSetting !== null) {
  1028. coverSizeSetting.addEventListener('click', () => {
  1029. const optionsCoverSize = document.querySelector(
  1030. '#yadg_options_coversize'
  1031. );
  1032. const {display} = optionsCoverSize.style;
  1033. if (display === 'none' || display === '') {
  1034. optionsCoverSize.style.display = 'block';
  1035. } else {
  1036. optionsCoverSize.style.display = 'none';
  1037. }
  1038. });
  1039. }
  1040.  
  1041. // Add the action for the template select
  1042. const formatSelect = this.getFormatSelect();
  1043. if (formatSelect !== null) {
  1044. formatSelect.addEventListener('change', function () {
  1045. if (yadgRenderer.hasCached()) {
  1046. yadgRenderer.renderCached(
  1047. this.value,
  1048. factory.setDescriptionBoxValue,
  1049. factory.setDescriptionBoxValue
  1050. );
  1051. }
  1052. });
  1053. }
  1054.  
  1055. // // add the action for the target select
  1056. // var targetSelect = this.getTargetSelect();
  1057. // if (targetSelect !== null) {
  1058. // targetSelect.addEventListener('change', function (e) {
  1059. // var target = this.value;
  1060. // });
  1061. // }
  1062.  
  1063. // add the action to the save settings link
  1064. const saveSettingsLink = document.querySelector('#yadg_save_settings');
  1065. if (saveSettingsLink !== null) {
  1066. saveSettingsLink.addEventListener('click', e => {
  1067. e.preventDefault();
  1068.  
  1069. factory.saveSettings();
  1070.  
  1071. alert('Settings saved successfully.');
  1072. });
  1073. }
  1074.  
  1075. // Add the action to the clear cache link
  1076. const clearCacheLink = document.querySelector('#yadg_clear_cache');
  1077. if (clearCacheLink !== null) {
  1078. clearCacheLink.addEventListener('click', e => {
  1079. e.preventDefault();
  1080.  
  1081. yadgUtil.storage.removeAll();
  1082.  
  1083. alert('Cache cleared. Please reload the page for this to take effect.');
  1084. });
  1085. }
  1086.  
  1087. const lastChecked = yadgUtil.storage.getItem(factory.KEY_LAST_CHECKED);
  1088. if (
  1089. lastChecked === null ||
  1090. new Date().getTime() - new Date(lastChecked).getTime() >
  1091. factory.CACHE_TIMEOUT
  1092. ) {
  1093. // Update the scraper and formats list
  1094. factory.UPDATE_PROGRESS = 1;
  1095. yadg.getScraperList(factory.setScraperSelect);
  1096. yadg.getFormatsList(factory.setFormatSelect);
  1097. } else {
  1098. factory.setScraperSelect(
  1099. yadgUtil.storage.getItem(factory.KEY_SCRAPER_LIST)
  1100. );
  1101. factory.setFormatSelect(
  1102. yadgUtil.storage.getItem(factory.KEY_FORMAT_LIST)
  1103. );
  1104. }
  1105.  
  1106. return true;
  1107. },
  1108.  
  1109. getApiTokenInput() {
  1110. return document.querySelector('#yadg_api_token');
  1111. },
  1112.  
  1113. getReplaceDescriptionCheckbox() {
  1114. return document.querySelector('#yadg_options_replace');
  1115. },
  1116.  
  1117. getFetchImageCheckbox() {
  1118. return document.querySelector('#yadg_options_image');
  1119. },
  1120.  
  1121. getAutoRehostCheckbox() {
  1122. return document.querySelector('#yadg_options_rehost');
  1123. },
  1124.  
  1125. getAutoPreviewCheckbox() {
  1126. return document.querySelector('#yadg_options_preview');
  1127. },
  1128.  
  1129. getAutoSelectScraperCheckbox() {
  1130. return document.querySelector('#yadg_options_auto_select_scraper');
  1131. },
  1132.  
  1133. getReplaceDescriptionSettingKey() {
  1134. return this.makeReplaceDescriptionSettingsKey(this.currentLocation);
  1135. },
  1136.  
  1137. makeReplaceDescriptionSettingsKey(subKey) {
  1138. return this.KEY_REPLACE_DESCRIPTION + subKey.replace(/_/g, '');
  1139. },
  1140.  
  1141. // Disable fields when groupid set
  1142. inputsOff(url) {
  1143. if (/groupid=\d+/.test(url)) {
  1144. [
  1145. 'artists[]',
  1146. 'importance[]',
  1147. 'title',
  1148. 'releasetype',
  1149. 'genre_tags',
  1150. 'tags'
  1151. ].forEach(i => {
  1152. document.getElementsByName(i).forEach(i => {
  1153. i.readOnly = true;
  1154. });
  1155. });
  1156. }
  1157. },
  1158.  
  1159. initializeSettings() {
  1160. let settingsVer = yadgUtil.settings.getItem(factory.KEY_SETTINGS_INIT_VER);
  1161. const currentVer = 1;
  1162.  
  1163. if (!settingsVer) {
  1164. settingsVer = 0;
  1165. }
  1166.  
  1167. if (settingsVer < currentVer) {
  1168. // Replace descriptions on upload and new request pages
  1169. const locations = [
  1170. 'pth_upload',
  1171. 'pth_request',
  1172. 'ops_upload',
  1173. 'ops_request',
  1174. 'nwcd_upload',
  1175. 'nwcd_request',
  1176. 'dic_upload',
  1177. 'dic_request',
  1178. 'waffles_upload',
  1179. 'waffles_upload_new',
  1180. 'waffles_request'
  1181. ];
  1182. for (const loc of locations) {
  1183. const replaceDescSettingKey = factory.makeReplaceDescriptionSettingsKey(
  1184. loc
  1185. );
  1186.  
  1187. yadgUtil.settings.addItem(replaceDescSettingKey, true);
  1188. }
  1189. }
  1190.  
  1191. yadgUtil.settings.addItem(factory.KEY_SETTINGS_INIT_VER, currentVer);
  1192. },
  1193.  
  1194. populateSettings() {
  1195. const apiToken = yadgUtil.settings.getItem(factory.KEY_API_TOKEN);
  1196. const replaceDesc = yadgUtil.settings.getItem(
  1197. factory.getReplaceDescriptionSettingKey()
  1198. );
  1199. const fetchImage = yadgUtil.settings.getItem(factory.KEY_FETCH_IMAGE);
  1200. autoRehost = yadgUtil.settings.getItem(factory.KEY_AUTO_REHOST);
  1201. autoPreview = yadgUtil.settings.getItem(factory.KEY_AUTO_PREVIEW);
  1202. descriptionTarget = yadgUtil.settings.getItem(factory.KEY_AUTO_PREVIEW);
  1203. const autoSelectScraper = yadgUtil.settings.getItem(
  1204. factory.KEY_AUTO_SELECT_SCRAPER
  1205. );
  1206. const coverSize = yadgUtil.settings.getItem(factory.KEY_COVER_SIZE);
  1207.  
  1208. if (apiToken) {
  1209. const apiTokenInput = factory.getApiTokenInput();
  1210. apiTokenInput.value = apiToken;
  1211. }
  1212.  
  1213. if (replaceDesc) {
  1214. const replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
  1215. replaceDescCheckbox.checked = true;
  1216. }
  1217.  
  1218. if (fetchImage) {
  1219. const fetchImageCheckbox = factory.getFetchImageCheckbox();
  1220. fetchImageCheckbox.checked = true;
  1221. }
  1222.  
  1223. if (autoRehost) {
  1224. const autoRehostCheckbox = factory.getAutoRehostCheckbox();
  1225. if (autoRehostCheckbox) {
  1226. autoRehostCheckbox.checked = true;
  1227. }
  1228. }
  1229.  
  1230. if (autoPreview && window.location.href.match(/\/upload\.php/)) {
  1231. const autoPreviewCheckbox = factory.getAutoPreviewCheckbox();
  1232. autoPreviewCheckbox.checked = true;
  1233. }
  1234.  
  1235. if (autoSelectScraper) {
  1236. const autoSelectScraperCheckbox = factory.getAutoSelectScraperCheckbox();
  1237. autoSelectScraperCheckbox.checked = true;
  1238. }
  1239.  
  1240. if (coverSize) {
  1241. const coverSizeOption = factory.getCoverSize();
  1242. coverSizeOption.value = coverSize;
  1243. if (factory.getFetchImageCheckbox().checked) {
  1244. const optionsCoverSize = document.querySelector(
  1245. '#yadg_options_coversize'
  1246. );
  1247. optionsCoverSize.style.display = 'block';
  1248. }
  1249. }
  1250. },
  1251.  
  1252. // eslint-disable-next-line complexity
  1253. saveSettings() {
  1254. const scraperSelect = factory.getScraperSelect();
  1255. const templateSelect = factory.getFormatSelect();
  1256. const targetSelect = factory.getTargetSelect();
  1257. const descriptionTargetSelect = factory.getDescriptionTargetSelect();
  1258. const apiTokenInput = factory.getApiTokenInput();
  1259. const replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
  1260. const fetchImageCheckbox = factory.getFetchImageCheckbox();
  1261. const autoRehostCheckbox = factory.getAutoRehostCheckbox();
  1262. const autoPreviewCheckbox = factory.getAutoPreviewCheckbox();
  1263. const autoSelectScraperCheckbox = factory.getAutoSelectScraperCheckbox();
  1264. const coverSize = factory.getCoverSize();
  1265.  
  1266. let currentScraper = null;
  1267. let currentTemplate = null;
  1268. let currentTarget = null;
  1269. let currentDescriptionTarget = null;
  1270. let currentCoverSize = null;
  1271. const apiToken = apiTokenInput.value.trim();
  1272. const replaceDescription = replaceDescCheckbox.checked;
  1273. const fetchImage = fetchImageCheckbox.checked;
  1274. const autoSelectScraper = autoSelectScraperCheckbox.checked;
  1275. if (autoRehostCheckbox) {
  1276. autoRehost = autoRehostCheckbox.checked;
  1277. }
  1278.  
  1279. if (window.location.href.match(/\/upload\.php/)) {
  1280. autoPreview = autoPreviewCheckbox.checked;
  1281. }
  1282.  
  1283. if (scraperSelect.options.length > 0) {
  1284. currentScraper = scraperSelect.options[scraperSelect.selectedIndex].value;
  1285. }
  1286.  
  1287. if (templateSelect.options.length > 0) {
  1288. currentTemplate =
  1289. templateSelect.options[templateSelect.selectedIndex].value;
  1290. }
  1291.  
  1292. if (targetSelect.options.length > 0) {
  1293. currentTarget = targetSelect.options[targetSelect.selectedIndex].value;
  1294. }
  1295.  
  1296. if (descriptionTargetSelect.options.length > 0) {
  1297. currentDescriptionTarget =
  1298. descriptionTargetSelect.options[descriptionTargetSelect.selectedIndex]
  1299. .value;
  1300. }
  1301.  
  1302. if (coverSize.options.length > 0) {
  1303. currentCoverSize = coverSize.options[coverSize.selectedIndex].value;
  1304. }
  1305.  
  1306. if (currentScraper !== null) {
  1307. yadgUtil.settings.addItem(factory.KEY_DEFAULT_SCRAPER, currentScraper);
  1308. }
  1309.  
  1310. if (currentTemplate !== null) {
  1311. yadgUtil.settings.addItem(factory.KEY_DEFAULT_TEMPLATE, currentTemplate);
  1312. }
  1313.  
  1314. if (currentTarget !== null) {
  1315. yadgUtil.settings.addItem(factory.KEY_DEFAULT_TARGET, currentTarget);
  1316. }
  1317.  
  1318. if (currentDescriptionTarget !== null) {
  1319. yadgUtil.settings.addItem(
  1320. factory.KEY_DESCRIPTION_TARGET,
  1321. currentDescriptionTarget
  1322. );
  1323. }
  1324.  
  1325. if (currentCoverSize !== null) {
  1326. yadgUtil.settings.addItem(factory.KEY_COVER_SIZE, currentCoverSize);
  1327. }
  1328.  
  1329. if (apiToken === '') {
  1330. yadgUtil.settings.removeItem(factory.KEY_API_TOKEN);
  1331. } else {
  1332. yadgUtil.settings.addItem(factory.KEY_API_TOKEN, apiToken);
  1333. }
  1334.  
  1335. const replaceDescSettingKey = factory.getReplaceDescriptionSettingKey();
  1336. if (replaceDescription) {
  1337. yadgUtil.settings.addItem(replaceDescSettingKey, true);
  1338. } else {
  1339. yadgUtil.settings.removeItem(replaceDescSettingKey);
  1340. }
  1341.  
  1342. if (fetchImage) {
  1343. yadgUtil.settings.addItem(factory.KEY_FETCH_IMAGE, true);
  1344. } else {
  1345. yadgUtil.settings.removeItem(factory.KEY_FETCH_IMAGE);
  1346. }
  1347.  
  1348. if (autoRehost) {
  1349. yadgUtil.settings.addItem(factory.KEY_AUTO_REHOST, true);
  1350. } else if (!autoRehost && autoRehostCheckbox) {
  1351. yadgUtil.settings.removeItem(factory.KEY_AUTO_REHOST);
  1352. }
  1353.  
  1354. if (autoPreview) {
  1355. yadgUtil.settings.addItem(factory.KEY_AUTO_PREVIEW, true);
  1356. } else if (!autoPreview && window.location.href.match(/\/upload\.php/)) {
  1357. yadgUtil.settings.removeItem(factory.KEY_AUTO_PREVIEW);
  1358. }
  1359.  
  1360. if (autoSelectScraper) {
  1361. yadgUtil.settings.addItem(factory.KEY_AUTO_SELECT_SCRAPER, true);
  1362. } else {
  1363. yadgUtil.settings.removeItem(factory.KEY_AUTO_SELECT_SCRAPER);
  1364. }
  1365. },
  1366.  
  1367. setDescriptionBoxValue(value) {
  1368. const descBox = factory.getDescriptionBox();
  1369. const replaceDescCheckbox = factory.getReplaceDescriptionCheckbox();
  1370. let replaceDesc = false;
  1371.  
  1372. if (replaceDescCheckbox !== null) {
  1373. replaceDesc = replaceDescCheckbox.checked;
  1374. }
  1375.  
  1376. if (descBox !== null && !Array.isArray(descBox)) {
  1377. if (descBox.getAttribute('disabled') === 'disabled') {
  1378. return;
  1379. }
  1380.  
  1381. if (!replaceDesc && /\S/.test(descBox.value)) {
  1382. // Check if the current description contains more than whitespace
  1383. descBox.value += '\n\n' + value;
  1384. } else {
  1385. descBox.value = value;
  1386. }
  1387.  
  1388. if (
  1389. factory.currentLocation !== 'pth_torrent_overview' || factory.currentLocation !==
  1390. 'ops_torrent_overview'
  1391. ) {
  1392. if (descBox.parentNode.nextSibling.nextSibling) {
  1393. const previewBtn =
  1394. descBox.parentNode.nextSibling.nextSibling.firstChild.nextSibling;
  1395. if (
  1396. previewBtn &&
  1397. previewBtn.value === 'Preview' &&
  1398. factory.getAutoPreviewCheckbox().checked
  1399. ) {
  1400. previewBtn.click();
  1401. }
  1402. }
  1403. }
  1404. } else if (Array.isArray(descBox)) {
  1405. for (const element of descBox) {
  1406. if (element.getAttribute('disabled') === 'disabled') {
  1407. continue;
  1408. }
  1409.  
  1410. element.value = value;
  1411. const previewBtn =
  1412. element.parentNode.nextSibling.nextSibling.firstChild.nextSibling;
  1413. if (
  1414. previewBtn &&
  1415. previewBtn.value === 'Preview' &&
  1416. factory.getAutoPreviewCheckbox().checked
  1417. ) {
  1418. previewBtn.click();
  1419. }
  1420. }
  1421. }
  1422. },
  1423.  
  1424. getFormatSelect() {
  1425. return document.querySelector('#yadg_format');
  1426. },
  1427.  
  1428. setDefaultFormat() {
  1429. const formatSelect = factory.getFormatSelect();
  1430. const formatOffsets = yadgUtil.getOptionOffsets(formatSelect);
  1431.  
  1432. const defaultFormat = yadgUtil.settings.getItem(
  1433. factory.KEY_DEFAULT_TEMPLATE
  1434. );
  1435. if (defaultFormat !== null && defaultFormat in formatOffsets) {
  1436. formatSelect.selectedIndex = formatOffsets[defaultFormat];
  1437. } else {
  1438. // We have no settings so fall back to the hard coded defaults
  1439. switch (this.currentLocation) {
  1440. case 'waffles_upload':
  1441. case 'waffles_upload_new':
  1442. case 'waffles_request':
  1443. formatSelect.selectedIndex = formatOffsets[defaultWafflesFormat];
  1444. break;
  1445.  
  1446. default:
  1447. formatSelect.selectedIndex = formatOffsets[defaultPTHFormat];
  1448. break;
  1449. }
  1450. }
  1451. },
  1452.  
  1453. getCoverSize() {
  1454. return document.querySelector('#yadg_coversize');
  1455. },
  1456.  
  1457. getTargetSelect() {
  1458. return document.querySelector('#yadg_target');
  1459. },
  1460.  
  1461. getDescriptionTargetSelect() {
  1462. return document.querySelector('#yadg_description_target');
  1463. },
  1464.  
  1465. setDefaultTarget() {
  1466. const targetSelect = factory.getTargetSelect();
  1467. const targetOffsets = yadgUtil.getOptionOffsets(targetSelect);
  1468.  
  1469. const defaultTarget = yadgUtil.settings.getItem(factory.KEY_DEFAULT_TARGET);
  1470. if (defaultTarget !== null && defaultTarget in targetOffsets) {
  1471. targetSelect.selectedIndex = targetOffsets[defaultTarget];
  1472. } else {
  1473. targetSelect.selectedIndex = targetOffsets[defaultPTHTarget];
  1474. }
  1475. },
  1476.  
  1477. setDefaultDescriptionTarget() {
  1478. const targetDescriptionSelect = factory.getDescriptionTargetSelect();
  1479. const targetDescriptionOffsets = yadgUtil.getOptionOffsets(
  1480. targetDescriptionSelect
  1481. );
  1482.  
  1483. const defaultDescriptionTarget = yadgUtil.settings.getItem(
  1484. factory.KEY_DESCRIPTION_TARGET
  1485. );
  1486. if (
  1487. defaultDescriptionTarget !== null &&
  1488. defaultDescriptionTarget in targetDescriptionOffsets
  1489. ) {
  1490. targetDescriptionSelect.selectedIndex =
  1491. targetDescriptionOffsets[defaultDescriptionTarget];
  1492. } else {
  1493. targetDescriptionSelect.selectedIndex =
  1494. targetDescriptionOffsets[defaultPTHDescriptionTarget];
  1495. }
  1496. },
  1497.  
  1498. getScraperSelect() {
  1499. return document.querySelector('#yadg_scraper');
  1500. },
  1501.  
  1502. setDefaultScraper() {
  1503. const defaultScraper = yadgUtil.settings.getItem(
  1504. factory.KEY_DEFAULT_SCRAPER
  1505. );
  1506. if (defaultScraper !== null) {
  1507. const scraperSelect = factory.getScraperSelect();
  1508. const scraperOffsets = yadgUtil.getOptionOffsets(scraperSelect);
  1509.  
  1510. if (defaultScraper in scraperOffsets) {
  1511. scraperSelect.selectedIndex = scraperOffsets[defaultScraper];
  1512. }
  1513. }
  1514. },
  1515.  
  1516. setScraperSelect(scrapers) {
  1517. const scraperSelect = factory.getScraperSelect();
  1518.  
  1519. factory.setSelect(scraperSelect, scrapers);
  1520. factory.setDefaultScraper();
  1521.  
  1522. if (factory.UPDATE_PROGRESS > 0) {
  1523. yadgUtil.storage.addItem(factory.KEY_SCRAPER_LIST, scrapers);
  1524. factory.UPDATE_PROGRESS |= 1 << 1;
  1525.  
  1526. if (factory.UPDATE_PROGRESS === 7) {
  1527. yadgUtil.storage.addItem(factory.KEY_LAST_CHECKED, new Date());
  1528. }
  1529. }
  1530. },
  1531.  
  1532. setFormatSelect(templates) {
  1533. const formatSelect = factory.getFormatSelect();
  1534.  
  1535. const nonUtility = [];
  1536. const saveTemplates = [];
  1537. for (const element of templates) {
  1538. if (factory.UPDATE_PROGRESS > 0) {
  1539. if (element.name === 'What') {
  1540. element.name = 'RED';
  1541. element.nameFormatted = 'RED';
  1542. } else if (element.name === 'What (Tracks only)') {
  1543. element.name = 'RED (Tracks only)';
  1544. element.nameFormatted = 'RED (Tracks only)';
  1545. }
  1546.  
  1547. yadgTemplates.addTemplate(element);
  1548.  
  1549. saveTemplates.push({
  1550. id: element.id,
  1551. url: element.url,
  1552. name: element.name,
  1553. nameFormatted: element.nameFormatted,
  1554. owner: element.owner,
  1555. default: element.default,
  1556. isUtility: element.isUtility
  1557. });
  1558. } else {
  1559. if (element.name === 'What') {
  1560. element.name = 'PTH';
  1561. element.nameFormatted = 'PTH';
  1562. } else if (element.name === 'What (Tracks only)') {
  1563. element.name = 'PTH (Tracks only)';
  1564. element.nameFormatted = 'PTH (Tracks only)';
  1565. }
  1566.  
  1567. yadgTemplates.addTemplateUrl(element.id, element.url);
  1568. }
  1569.  
  1570. if (!element.isUtility) {
  1571. nonUtility.push(element);
  1572. }
  1573. }
  1574.  
  1575. factory.setSelect(formatSelect, nonUtility);
  1576. factory.setDefaultFormat();
  1577. factory.setDefaultTarget();
  1578. factory.setDefaultDescriptionTarget();
  1579.  
  1580. if (factory.UPDATE_PROGRESS > 0) {
  1581. yadgUtil.storage.addItem(factory.KEY_FORMAT_LIST, saveTemplates);
  1582. factory.UPDATE_PROGRESS |= 1 << 2;
  1583.  
  1584. if (factory.UPDATE_PROGRESS === 7) {
  1585. yadgUtil.storage.addItem(factory.KEY_LAST_CHECKED, new Date());
  1586. }
  1587. }
  1588. },
  1589.  
  1590. setSelect(select, data) {
  1591. select.options.length = data.length;
  1592.  
  1593. for (const [i, element] of data.entries()) {
  1594. // We are not using the javascript constructor to create an Option instance because this will create an
  1595. // incompatibility with jQuery in Chrome which will make it impossible to add a new artist field on redacted.ch
  1596. const o = document.createElement('option');
  1597. if ('nameFormatted' in element) {
  1598. o.text = element.nameFormatted;
  1599. } else {
  1600. o.text = element.name;
  1601. }
  1602.  
  1603. o.value = element.value || element.id;
  1604. o.selected = element.default;
  1605. select.options[i] = o;
  1606. if (element.default) {
  1607. select.selectedIndex = i;
  1608. }
  1609.  
  1610. if (element.url) {
  1611. o.dataset.url = element.url;
  1612. }
  1613. }
  1614. },
  1615.  
  1616. setStyles() {
  1617. // General styles
  1618. yadgUtil.addCSS(
  1619. '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 }'
  1620. );
  1621.  
  1622. // Location specific styles will go here
  1623. switch (this.currentLocation) {
  1624. case 'waffles_upload':
  1625. yadgUtil.addCSS(
  1626. 'div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'
  1627. );
  1628. break;
  1629.  
  1630. case 'waffles_request':
  1631. yadgUtil.addCSS(
  1632. 'div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'
  1633. );
  1634. break;
  1635.  
  1636. default:
  1637. break;
  1638. }
  1639. },
  1640.  
  1641. // eslint-disable-next-line complexity
  1642. getInputElements() {
  1643. const buttonHTML = '<input type="submit" value="Fetch" id="yadg_submit"/>';
  1644. const scraperSelectHTML =
  1645. '<select name="yadg_scraper" id="yadg_scraper"></select>';
  1646. let optionsHTML =
  1647. '<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>';
  1648. optionsHTML +=
  1649. '<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>';
  1650. if (document.querySelectorAll('.rehost_it_cover')[0]) {
  1651. optionsHTML +=
  1652. '<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>';
  1653. }
  1654.  
  1655. if (window.location.href.match(/\/upload\.php/)) {
  1656. optionsHTML +=
  1657. '<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>';
  1658. }
  1659.  
  1660. optionsHTML +=
  1661. '<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> ';
  1662. optionsHTML +=
  1663. '<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>';
  1664. const inputHTML =
  1665. '<input type="text" name="yadg_input" id="yadg_input" size="60" />';
  1666. const responseDivHTML = '<div id="yadg_response"></div>';
  1667. const toggleOptionsLinkHTML =
  1668. '<a id="yadg_toggle_options" href="#">Toggle options</a>';
  1669. const scraperInfoLink =
  1670. '<a id="yadg_scraper_info" href="https://yadg.cc/available-scrapers" target="_blank" title="Get additional information on the available scrapers">[?]</a>';
  1671.  
  1672. switch (this.currentLocation) {
  1673. case 'nwcd_upload':
  1674. case 'ops_upload':
  1675. case 'dic_upload':
  1676. case 'pth_upload': {
  1677. const tr = document.createElement('tr');
  1678. tr.className = 'yadg_tr';
  1679. tr.innerHTML =
  1680. '<td class="label">YADG:</td><td>' +
  1681. inputHTML +
  1682. scraperSelectHTML +
  1683. scraperInfoLink +
  1684. buttonHTML +
  1685. toggleOptionsLinkHTML +
  1686. optionsHTML +
  1687. responseDivHTML +
  1688. '</td>';
  1689. return tr;
  1690. }
  1691.  
  1692. case 'nwcd_edit':
  1693. case 'ops_edit':
  1694. case 'dic_edit':
  1695. case 'pth_edit': {
  1696. const div = document.createElement('div');
  1697. div.className = 'yadg_div';
  1698. div.innerHTML =
  1699. '<h3 class="label">YADG:</h3>\n' +
  1700. inputHTML +
  1701. '\n' +
  1702. scraperSelectHTML +
  1703. '\n' +
  1704. scraperInfoLink +
  1705. '\n' +
  1706. buttonHTML +
  1707. '\n' +
  1708. toggleOptionsLinkHTML +
  1709. '\n' +
  1710. optionsHTML +
  1711. '\n' +
  1712. responseDivHTML;
  1713. return div;
  1714. }
  1715.  
  1716. case 'nwcd_torrent_overview':
  1717. case 'ops_torrent_overview':
  1718. case 'dic_torrent_overview':
  1719. case 'pth_torrent_overview': {
  1720. const div = document.createElement('div');
  1721. div.id = 'yadg_div';
  1722. div.className = 'box';
  1723. div.innerHTML =
  1724. '<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' +
  1725. scraperSelectHTML +
  1726. '\n' +
  1727. scraperInfoLink +
  1728. '\n' +
  1729. buttonHTML +
  1730. '\n' +
  1731. toggleOptionsLinkHTML +
  1732. '\n' +
  1733. optionsHTML +
  1734. '\n' +
  1735. responseDivHTML;
  1736. return div;
  1737. }
  1738.  
  1739. case 'nwcd_request':
  1740. case 'nwcd_request_edit':
  1741. case 'ops_request':
  1742. case 'ops_request_edit':
  1743. case 'dic_request':
  1744. case 'dic_request_edit':
  1745. case 'pth_request':
  1746. case 'pth_request_edit': {
  1747. const tr = document.createElement('tr');
  1748. tr.className = 'yadg_tr';
  1749. tr.innerHTML =
  1750. '<td class="label">YADG:</td><td>' +
  1751. inputHTML +
  1752. scraperSelectHTML +
  1753. scraperInfoLink +
  1754. buttonHTML +
  1755. toggleOptionsLinkHTML +
  1756. optionsHTML +
  1757. responseDivHTML +
  1758. '</td>';
  1759. return tr;
  1760. }
  1761.  
  1762. case 'waffles_upload': {
  1763. const tr = document.createElement('tr');
  1764. tr.className = 'yadg_tr';
  1765. tr.innerHTML =
  1766. '<td class="heading" valign="top" align="right"><label for="yadg_input">YADG:</label></td><td>' +
  1767. inputHTML +
  1768. scraperSelectHTML +
  1769. scraperInfoLink +
  1770. buttonHTML +
  1771. toggleOptionsLinkHTML +
  1772. optionsHTML +
  1773. responseDivHTML +
  1774. '</td>';
  1775. return tr;
  1776. }
  1777.  
  1778. case 'waffles_upload_new': {
  1779. const p = document.createElement('p');
  1780. p.className = 'yadg_p';
  1781. p.innerHTML =
  1782. '<label for="yadg_input">YADG:</label>' +
  1783. inputHTML +
  1784. scraperSelectHTML +
  1785. scraperInfoLink +
  1786. buttonHTML +
  1787. toggleOptionsLinkHTML +
  1788. optionsHTML +
  1789. responseDivHTML;
  1790. return p;
  1791. }
  1792.  
  1793. case 'waffles_request': {
  1794. const tr = document.createElement('tr');
  1795. tr.className = 'yadg_tr';
  1796. tr.innerHTML =
  1797. '<td style="text-align:left;width:100px;">YADG:</td><td style="text-align:left;">' +
  1798. inputHTML +
  1799. scraperSelectHTML +
  1800. scraperInfoLink +
  1801. buttonHTML +
  1802. toggleOptionsLinkHTML +
  1803. optionsHTML +
  1804. responseDivHTML +
  1805. '</td>';
  1806. return tr;
  1807. }
  1808.  
  1809. default:
  1810. // This should actually never happen
  1811. return document.createElement('div');
  1812. }
  1813. },
  1814.  
  1815. // eslint-disable-next-line complexity
  1816. insertIntoPage(element) {
  1817. switch (this.currentLocation) {
  1818. case 'nwcd_upload':
  1819. case 'ops_upload':
  1820. case 'dic_upload':
  1821. case 'pth_upload': {
  1822. const yearTr = document.querySelector('#year_tr');
  1823. yearTr.parentNode.insertBefore(element, yearTr);
  1824. break;
  1825. }
  1826.  
  1827. case 'nwcd_edit':
  1828. case 'ops_edit':
  1829. case 'dic_edit':
  1830. case 'pth_edit': {
  1831. const [summaryInput] = document.getElementsByName('summary');
  1832. summaryInput.parentNode.insertBefore(
  1833. element,
  1834. summaryInput.nextSibling.nextSibling
  1835. );
  1836. break;
  1837. }
  1838.  
  1839. case 'nwcd_torrent_overview':
  1840. case 'ops_torrent_overview':
  1841. case 'dic_torrent_overview':
  1842. case 'pth_torrent_overview': {
  1843. const [addArtistsBox] = document.querySelectorAll('.box_addartists');
  1844. addArtistsBox.parentNode.insertBefore(
  1845. element,
  1846. addArtistsBox.nextSibling.nextSibling
  1847. );
  1848. break;
  1849. }
  1850.  
  1851. case 'nwcd_request':
  1852. case 'nwcd_request_edit':
  1853. case 'ops_request':
  1854. case 'ops_request_edit':
  1855. case 'dic_request':
  1856. case 'dic_request_edit':
  1857. case 'pth_request':
  1858. case 'pth_request_edit': {
  1859. const artistTr = document.querySelector('#artist_tr');
  1860. artistTr.parentNode.insertBefore(element, artistTr);
  1861. break;
  1862. }
  1863.  
  1864. case 'waffles_upload': {
  1865. const [submitButton] = document.getElementsByName('submit');
  1866. submitButton.parentNode.parentNode.parentNode.insertBefore(
  1867. element,
  1868. submitButton.parentNode.parentNode
  1869. );
  1870. break;
  1871. }
  1872.  
  1873. case 'waffles_upload_new': {
  1874. const h4s = document.querySelectorAll('h4');
  1875. let div;
  1876. for (const h4 of h4s) {
  1877. if (h4s[h4].innerHTML.includes('read the rules')) {
  1878. div = h4s[h4].parentNode;
  1879. break;
  1880. }
  1881. }
  1882.  
  1883. div.append(element);
  1884. break;
  1885. }
  1886.  
  1887. case 'waffles_request': {
  1888. const [categorySelect] = document.getElementsByName('category');
  1889. categorySelect.parentNode.parentNode.parentNode.insertBefore(
  1890. element,
  1891. categorySelect.parentNode.parentNode
  1892. );
  1893. break;
  1894. }
  1895.  
  1896. default:
  1897. break;
  1898. }
  1899. },
  1900.  
  1901. // eslint-disable-next-line complexity
  1902. getDescriptionBox() {
  1903. switch (this.currentLocation) {
  1904. case 'nwcd_upload':
  1905. case 'ops_upload':
  1906. case 'dic_upload':
  1907. case 'pth_upload':
  1908. if (factory.getDescriptionTargetSelect().value === 'album') {
  1909. return document.querySelector('#album_desc');
  1910. }
  1911.  
  1912. if (factory.getDescriptionTargetSelect().value === 'release') {
  1913. return document.querySelector('#release_desc');
  1914. }
  1915.  
  1916. if (factory.getDescriptionTargetSelect().value === 'both') {
  1917. return [
  1918. document.querySelector('#album_desc'),
  1919. document.querySelector('#release_desc')
  1920. ];
  1921. }
  1922.  
  1923. break;
  1924.  
  1925. case 'nwcd_edit':
  1926. case 'ops_edit':
  1927. case 'dic_edit':
  1928. case 'pth_edit':
  1929. return document.getElementsByName('body')[0];
  1930.  
  1931. case 'nwcd_torrent_overview':
  1932. case 'ops_torrent_overview':
  1933. case 'dic_torrent_overview':
  1934. case 'pth_torrent_overview':
  1935. if (!{}.hasOwnProperty.call(this, 'dummybox')) {
  1936. this.dummybox = document.createElement('div');
  1937. }
  1938.  
  1939. return this.dummybox;
  1940.  
  1941. case 'nwcd_request':
  1942. case 'nwcd_request_edit':
  1943. case 'ops_request':
  1944. case 'ops_request_edit':
  1945. case 'dic_request':
  1946. case 'dic_request_edit':
  1947. case 'pth_request':
  1948. case 'pth_request_edit':
  1949. return document.getElementsByName('description')[0];
  1950.  
  1951. case 'waffles_upload':
  1952. return document.querySelector('#descr');
  1953.  
  1954. case 'waffles_upload_new':
  1955. return document.querySelector('#id_descr');
  1956.  
  1957. case 'waffles_request':
  1958. return document.getElementsByName('information')[0];
  1959.  
  1960. default:
  1961. // That should actually never happen
  1962. return document.createElement('div');
  1963. }
  1964. },
  1965.  
  1966. // eslint-disable-next-line complexity
  1967. getFormFillFunction() {
  1968. const currentTarget = factory.getTargetSelect().value;
  1969. switch (this.currentLocation) {
  1970. case 'pth_upload': {
  1971. // eslint-disable-next-line complexity
  1972. const f = function (rawData) {
  1973. let albumTitleInput;
  1974. let yearInput;
  1975. let labelInput;
  1976. let catalogInput;
  1977. if (currentTarget === 'other') {
  1978. albumTitleInput = document.querySelector('#title');
  1979. yearInput = document.querySelector('#remaster_year');
  1980. labelInput = document.querySelector('#remaster_record_label');
  1981. catalogInput = document.querySelector('#remaster_catalogue_number');
  1982. unsafeWindow.CheckYear(); // eslint-disable-line new-cap
  1983. } else {
  1984. albumTitleInput = document.querySelector('#title');
  1985. yearInput = document.querySelector('#year');
  1986. labelInput = document.querySelector('#remaster_record_label');
  1987. catalogInput = document.querySelector('#remaster_catalogue_number');
  1988. }
  1989.  
  1990. if (/music.apple/.test(rawData.url)) {
  1991. const releaseTypeInput = document.querySelector('#releasetype');
  1992. switch (true) {
  1993. case /.+ - Single$/.test(rawData.title):
  1994. rawData.title = rawData.title.replace(/ - Single$/, '');
  1995. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  1996. releaseTypeInput.value = 9;
  1997. }
  1998.  
  1999. break;
  2000. case /.+ - EP$/.test(rawData.title):
  2001. rawData.title = rawData.title.replace(/ - EP$/, '');
  2002. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2003. releaseTypeInput.value = 5;
  2004. }
  2005.  
  2006. break;
  2007. default:
  2008. break;
  2009. }
  2010. }
  2011.  
  2012. let artistInputs = document.getElementsByName('artists[]');
  2013. const tagsInput = document.querySelector('#tags');
  2014. const data = yadg.prepareRawResponse(rawData);
  2015. let nullArtistCount = 0;
  2016.  
  2017. if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
  2018. if (data.artists === false) {
  2019. for (const element of artistInputs) {
  2020. element.value = '';
  2021. }
  2022. } else {
  2023. let inputIdx = 0;
  2024.  
  2025. yadgUtil.addRemoveArtistBoxes(
  2026. data.effective_artist_count - artistInputs.length
  2027. );
  2028.  
  2029. artistInputs = document.getElementsByName('artists[]');
  2030.  
  2031. for (let i = 0; i < data.artist_keys.length; i++) {
  2032. const artistKey = data.artist_keys[i];
  2033. if (artistKey === 'null') {
  2034. nullArtistCount++;
  2035. continue;
  2036. }
  2037.  
  2038. const artistTypes = data.artists[artistKey];
  2039.  
  2040. for (const artistType of artistTypes) {
  2041. const artistInput = artistInputs[inputIdx];
  2042. let typeSelect = artistInput.nextSibling;
  2043.  
  2044. while (typeSelect.tagName !== 'SELECT') {
  2045. typeSelect = typeSelect.nextSibling;
  2046. }
  2047.  
  2048. artistInput.value = artistKey;
  2049.  
  2050. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2051.  
  2052. if (artistType === 'main') {
  2053. typeSelect.selectedIndex = optionOffsets[1];
  2054. } else if (artistType === 'guest') {
  2055. typeSelect.selectedIndex = optionOffsets[2];
  2056. } else if (artistType === 'remixer') {
  2057. typeSelect.selectedIndex = optionOffsets[3];
  2058. } else {
  2059. // We don't know this artist type, default to "main"
  2060. typeSelect.selectedIndex = optionOffsets[1];
  2061. }
  2062.  
  2063. // Next artist input
  2064. inputIdx += 1;
  2065. }
  2066. }
  2067.  
  2068. if (nullArtistCount > 0) {
  2069. yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
  2070. }
  2071. }
  2072. }
  2073.  
  2074. if (tagsInput.getAttribute('disabled') !== 'disabled') {
  2075. if (data.tags === false) {
  2076. tagsInput.value = '';
  2077. } else {
  2078. const tagsArray = data.tag_string.split(', ');
  2079. const tagsUnique = tagsArray.filter((elem, index, self) => {
  2080. return index === self.indexOf(elem);
  2081. });
  2082. tagsInput.value = tagsUnique.join(',').toLowerCase();
  2083. }
  2084. }
  2085.  
  2086. if (yearInput.getAttribute('disabled') !== 'disabled') {
  2087. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2088. }
  2089.  
  2090. if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
  2091. yadgUtil.setValueIfSet(
  2092. data.title,
  2093. albumTitleInput,
  2094. data.title !== false
  2095. );
  2096. }
  2097.  
  2098. if (labelInput.getAttribute('disabled') !== 'disabled') {
  2099. yadgUtil.setValueIfSet(
  2100. data.label,
  2101. labelInput,
  2102. data.label !== false
  2103. );
  2104. }
  2105.  
  2106. if (catalogInput.getAttribute('disabled') !== 'disabled') {
  2107. yadgUtil.setValueIfSet(
  2108. data.catalog,
  2109. catalogInput,
  2110. data.catalog !== false
  2111. );
  2112. }
  2113. };
  2114.  
  2115. return f;
  2116. }
  2117.  
  2118. case 'ops_upload': {
  2119. // eslint-disable-next-line complexity
  2120. const f = function (rawData) {
  2121. let albumTitleInput;
  2122. let yearInput;
  2123. let labelInput;
  2124. let catalogInput;
  2125. if (currentTarget === 'other') {
  2126. const remaster = document.querySelector('#remaster');
  2127. albumTitleInput = document.querySelector('#title');
  2128. yearInput = document.querySelector('#remaster_year');
  2129. labelInput = document.querySelector('#remaster_record_label');
  2130. catalogInput = document.querySelector('#remaster_catalogue_number');
  2131. remaster.checked = 'checked';
  2132. unsafeWindow.Remaster(); // eslint-disable-line new-cap
  2133. unsafeWindow.CheckYear(); // eslint-disable-line new-cap
  2134. } else {
  2135. albumTitleInput = document.querySelector('#title');
  2136. yearInput = document.querySelector('#year');
  2137. labelInput = document.querySelector('#record_label');
  2138. catalogInput = document.querySelector('#catalogue_number');
  2139. }
  2140.  
  2141. if (/itunes/.test(rawData.url)) {
  2142. const releaseTypeInput = document.querySelector('#releasetype');
  2143. switch (true) {
  2144. case /.+ - Single$/.test(rawData.title):
  2145. rawData.title = rawData.title.replace(/ - Single$/, '');
  2146. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2147. releaseTypeInput.value = 9;
  2148. }
  2149.  
  2150. break;
  2151. case /.+ - EP$/.test(rawData.title):
  2152. rawData.title = rawData.title.replace(/ - EP$/, '');
  2153. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2154. releaseTypeInput.value = 5;
  2155. }
  2156.  
  2157. break;
  2158. default:
  2159. break;
  2160. }
  2161. }
  2162.  
  2163. let artistInputs = document.getElementsByName('artists[]');
  2164. const tagsInput = document.querySelector('#tags');
  2165. const data = yadg.prepareRawResponse(rawData);
  2166. let nullArtistCount = 0;
  2167.  
  2168. if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
  2169. if (data.artists === false) {
  2170. for (const element of artistInputs) {
  2171. element.value = '';
  2172. }
  2173. } else {
  2174. let inputIdx = 0;
  2175.  
  2176. yadgUtil.addRemoveArtistBoxes(
  2177. data.effective_artist_count - artistInputs.length
  2178. );
  2179.  
  2180. artistInputs = document.getElementsByName('artists[]');
  2181.  
  2182. for (let i = 0; i < data.artist_keys.length; i++) {
  2183. const artistKey = data.artist_keys[i];
  2184. if (artistKey === 'null') {
  2185. nullArtistCount++;
  2186. continue;
  2187. }
  2188.  
  2189. const artistTypes = data.artists[artistKey];
  2190.  
  2191. for (const artistType of artistTypes) {
  2192. const artistInput = artistInputs[inputIdx];
  2193. let typeSelect = artistInput.nextSibling;
  2194.  
  2195. while (typeSelect.tagName !== 'SELECT') {
  2196. typeSelect = typeSelect.nextSibling;
  2197. }
  2198.  
  2199. artistInput.value = artistKey;
  2200.  
  2201. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2202.  
  2203. if (artistType === 'main') {
  2204. typeSelect.selectedIndex = optionOffsets[1];
  2205. } else if (artistType === 'guest') {
  2206. typeSelect.selectedIndex = optionOffsets[2];
  2207. } else if (artistType === 'remixer') {
  2208. typeSelect.selectedIndex = optionOffsets[3];
  2209. } else {
  2210. // We don't know this artist type, default to "main"
  2211. typeSelect.selectedIndex = optionOffsets[1];
  2212. }
  2213.  
  2214. // Next artist input
  2215. inputIdx += 1;
  2216. }
  2217. }
  2218.  
  2219. if (nullArtistCount > 0) {
  2220. yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
  2221. }
  2222. }
  2223. }
  2224.  
  2225. if (tagsInput.getAttribute('disabled') !== 'disabled') {
  2226. if (data.tags === false) {
  2227. tagsInput.value = '';
  2228. } else {
  2229. const tagsArray = data.tag_string.split(', ');
  2230. const tagsUnique = tagsArray.filter((elem, index, self) => {
  2231. return index === self.indexOf(elem);
  2232. });
  2233. tagsInput.value = tagsUnique.join(',').toLowerCase();
  2234. }
  2235. }
  2236.  
  2237. if (yearInput.getAttribute('disabled') !== 'disabled') {
  2238. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2239. }
  2240.  
  2241. if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
  2242. yadgUtil.setValueIfSet(
  2243. data.title,
  2244. albumTitleInput,
  2245. data.title !== false
  2246. );
  2247. }
  2248.  
  2249. if (labelInput.getAttribute('disabled') !== 'disabled') {
  2250. yadgUtil.setValueIfSet(
  2251. data.label,
  2252. labelInput,
  2253. data.label !== false
  2254. );
  2255. }
  2256.  
  2257. if (catalogInput.getAttribute('disabled') !== 'disabled') {
  2258. yadgUtil.setValueIfSet(
  2259. data.catalog,
  2260. catalogInput,
  2261. data.catalog !== false
  2262. );
  2263. }
  2264. };
  2265.  
  2266. return f;
  2267. }
  2268.  
  2269. case 'nwcd_upload': {
  2270. // eslint-disable-next-line complexity
  2271. const f = function (rawData) {
  2272. let albumTitleInput;
  2273. let yearInput;
  2274. let labelInput;
  2275. let catalogInput;
  2276. if (currentTarget === 'other') {
  2277. albumTitleInput = document.querySelector('#title');
  2278. yearInput = document.querySelector('#remaster_year');
  2279. labelInput = document.querySelector('#remaster_record_label');
  2280. catalogInput = document.querySelector('#remaster_catalogue_number');
  2281. unsafeWindow.CheckYear(); // eslint-disable-line new-cap
  2282. } else {
  2283. const unknownCheckbox = document.querySelector('#unknown');
  2284. albumTitleInput = document.querySelector('#title');
  2285. yearInput = document.querySelector('#year');
  2286. unknownCheckbox.checked = 'checked';
  2287. unsafeWindow.ToggleUnknown(); // eslint-disable-line new-cap
  2288. }
  2289.  
  2290. if (/itunes/.test(rawData.url)) {
  2291. const releaseTypeInput = document.querySelector('#releasetype');
  2292. switch (true) {
  2293. case /.+ - Single$/.test(rawData.title):
  2294. rawData.title = rawData.title.replace(/ - Single$/, '');
  2295. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2296. releaseTypeInput.value = 9;
  2297. }
  2298.  
  2299. break;
  2300. case /.+ - EP$/.test(rawData.title):
  2301. rawData.title = rawData.title.replace(/ - EP$/, '');
  2302. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2303. releaseTypeInput.value = 5;
  2304. }
  2305.  
  2306. break;
  2307. default:
  2308. break;
  2309. }
  2310. }
  2311.  
  2312. let artistInputs = document.getElementsByName('artists[]');
  2313. const tagsInput = document.querySelector('#tags');
  2314. const data = yadg.prepareRawResponse(rawData);
  2315. let nullArtistCount = 0;
  2316.  
  2317. if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
  2318. if (data.artists === false) {
  2319. for (const element of artistInputs) {
  2320. element.value = '';
  2321. }
  2322. } else {
  2323. let inputIdx = 0;
  2324.  
  2325. yadgUtil.addRemoveArtistBoxes(
  2326. data.effective_artist_count - artistInputs.length
  2327. );
  2328.  
  2329. artistInputs = document.getElementsByName('artists[]');
  2330.  
  2331. for (let i = 0; i < data.artist_keys.length; i++) {
  2332. const artistKey = data.artist_keys[i];
  2333. if (artistKey === 'null') {
  2334. nullArtistCount++;
  2335. continue;
  2336. }
  2337.  
  2338. const artistTypes = data.artists[artistKey];
  2339.  
  2340. for (const artistType of artistTypes) {
  2341. const artistInput = artistInputs[inputIdx];
  2342. let typeSelect = artistInput.nextSibling;
  2343.  
  2344. while (typeSelect.tagName !== 'SELECT') {
  2345. typeSelect = typeSelect.nextSibling;
  2346. }
  2347.  
  2348. artistInput.value = artistKey;
  2349.  
  2350. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2351.  
  2352. if (artistType === 'main') {
  2353. typeSelect.selectedIndex = optionOffsets[1];
  2354. } else if (artistType === 'guest') {
  2355. typeSelect.selectedIndex = optionOffsets[2];
  2356. } else if (artistType === 'remixer') {
  2357. typeSelect.selectedIndex = optionOffsets[3];
  2358. } else {
  2359. // We don't know this artist type, default to "main"
  2360. typeSelect.selectedIndex = optionOffsets[1];
  2361. }
  2362.  
  2363. // Next artist input
  2364. inputIdx += 1;
  2365. }
  2366. }
  2367.  
  2368. if (nullArtistCount > 0) {
  2369. yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
  2370. }
  2371. }
  2372. }
  2373.  
  2374. if (tagsInput.getAttribute('disabled') !== 'disabled') {
  2375. if (data.tags === false) {
  2376. tagsInput.value = '';
  2377. } else {
  2378. const tagsArray = data.tag_string.split(', ');
  2379. const tagsUnique = tagsArray.filter((elem, index, self) => {
  2380. return index === self.indexOf(elem);
  2381. });
  2382. tagsInput.value = tagsUnique.join(',').toLowerCase();
  2383. }
  2384. }
  2385.  
  2386. if (yearInput.getAttribute('disabled') !== 'disabled') {
  2387. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2388. }
  2389.  
  2390. if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
  2391. yadgUtil.setValueIfSet(
  2392. data.title,
  2393. albumTitleInput,
  2394. data.title !== false
  2395. );
  2396. }
  2397.  
  2398. if (labelInput) {
  2399. if (labelInput.getAttribute('disabled') !== 'disabled') {
  2400. yadgUtil.setValueIfSet(
  2401. data.label,
  2402. labelInput,
  2403. data.label !== false
  2404. );
  2405. }
  2406. }
  2407.  
  2408. if (catalogInput) {
  2409. if (catalogInput.getAttribute('disabled') !== 'disabled') {
  2410. yadgUtil.setValueIfSet(
  2411. data.catalog,
  2412. catalogInput,
  2413. data.catalog !== false
  2414. );
  2415. }
  2416. }
  2417. };
  2418.  
  2419. return f;
  2420. }
  2421.  
  2422. case 'dic_upload': {
  2423. // eslint-disable-next-line complexity
  2424. const f = function (rawData) {
  2425. let albumTitleInput;
  2426. let yearInput;
  2427. let labelInput;
  2428. let catalogInput;
  2429. if (currentTarget === 'other') {
  2430. albumTitleInput = document.querySelector('#title');
  2431. yearInput = document.querySelector('#remaster_year');
  2432. labelInput = document.querySelector('#remaster_record_label');
  2433. catalogInput = document.querySelector('#remaster_catalogue_number');
  2434. unsafeWindow.CheckYear(); // eslint-disable-line new-cap
  2435. } else {
  2436. const unknownCheckbox = document.querySelector('#unknown');
  2437. albumTitleInput = document.querySelector('#title');
  2438. yearInput = document.querySelector('#year');
  2439. unknownCheckbox.checked = 'checked';
  2440. unsafeWindow.ToggleUnknown(); // eslint-disable-line new-cap
  2441. }
  2442.  
  2443. if (/itunes/.test(rawData.url)) {
  2444. const releaseTypeInput = document.querySelector('#releasetype');
  2445. switch (true) {
  2446. case /.+ - Single$/.test(rawData.title):
  2447. rawData.title = rawData.title.replace(/ - Single$/, '');
  2448. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2449. releaseTypeInput.value = 9;
  2450. }
  2451.  
  2452. break;
  2453. case /.+ - EP$/.test(rawData.title):
  2454. rawData.title = rawData.title.replace(/ - EP$/, '');
  2455. if (releaseTypeInput.getAttribute('disabled') !== 'disabled') {
  2456. releaseTypeInput.value = 5;
  2457. }
  2458.  
  2459. break;
  2460. default:
  2461. break;
  2462. }
  2463. }
  2464.  
  2465. let artistInputs = document.getElementsByName('artists[]');
  2466. const tagsInput = document.querySelector('#tags');
  2467. const data = yadg.prepareRawResponse(rawData);
  2468. let nullArtistCount = 0;
  2469.  
  2470. if (artistInputs[0].getAttribute('disabled') !== 'disabled') {
  2471. if (data.artists === false) {
  2472. for (const element of artistInputs) {
  2473. element.value = '';
  2474. }
  2475. } else {
  2476. let inputIdx = 0;
  2477.  
  2478. yadgUtil.addRemoveArtistBoxes(
  2479. data.effective_artist_count - artistInputs.length
  2480. );
  2481.  
  2482. artistInputs = document.getElementsByName('artists[]');
  2483.  
  2484. for (let i = 0; i < data.artist_keys.length; i++) {
  2485. const artistKey = data.artist_keys[i];
  2486. if (artistKey === 'null') {
  2487. nullArtistCount++;
  2488. continue;
  2489. }
  2490.  
  2491. const artistTypes = data.artists[artistKey];
  2492.  
  2493. for (const artistType of artistTypes) {
  2494. const artistInput = artistInputs[inputIdx];
  2495. let typeSelect = artistInput.nextSibling;
  2496.  
  2497. while (typeSelect.tagName !== 'SELECT') {
  2498. typeSelect = typeSelect.nextSibling;
  2499. }
  2500.  
  2501. artistInput.value = artistKey;
  2502.  
  2503. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2504.  
  2505. if (artistType === 'main') {
  2506. typeSelect.selectedIndex = optionOffsets[1];
  2507. } else if (artistType === 'guest') {
  2508. typeSelect.selectedIndex = optionOffsets[2];
  2509. } else if (artistType === 'remixer') {
  2510. typeSelect.selectedIndex = optionOffsets[3];
  2511. } else {
  2512. // We don't know this artist type, default to "main"
  2513. typeSelect.selectedIndex = optionOffsets[1];
  2514. }
  2515.  
  2516. // Next artist input
  2517. inputIdx += 1;
  2518. }
  2519. }
  2520.  
  2521. if (nullArtistCount > 0) {
  2522. yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
  2523. }
  2524. }
  2525. }
  2526.  
  2527. if (tagsInput.getAttribute('disabled') !== 'disabled') {
  2528. if (data.tags === false) {
  2529. tagsInput.value = '';
  2530. } else {
  2531. const tagsArray = data.tag_string.split(', ');
  2532. const tagsUnique = tagsArray.filter((elem, index, self) => {
  2533. return index === self.indexOf(elem);
  2534. });
  2535. tagsInput.value = tagsUnique.join(',').toLowerCase();
  2536. }
  2537. }
  2538.  
  2539. if (yearInput.getAttribute('disabled') !== 'disabled') {
  2540. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2541. }
  2542.  
  2543. if (albumTitleInput.getAttribute('disabled') !== 'disabled') {
  2544. yadgUtil.setValueIfSet(
  2545. data.title,
  2546. albumTitleInput,
  2547. data.title !== false
  2548. );
  2549. }
  2550.  
  2551. if (labelInput) {
  2552. if (labelInput.getAttribute('disabled') !== 'disabled') {
  2553. yadgUtil.setValueIfSet(
  2554. data.label,
  2555. labelInput,
  2556. data.label !== false
  2557. );
  2558. }
  2559. }
  2560.  
  2561. if (catalogInput) {
  2562. if (catalogInput.getAttribute('disabled') !== 'disabled') {
  2563. yadgUtil.setValueIfSet(
  2564. data.catalog,
  2565. catalogInput,
  2566. data.catalog !== false
  2567. );
  2568. }
  2569. }
  2570. };
  2571.  
  2572. return f;
  2573. }
  2574.  
  2575. case 'nwcd_edit':
  2576. case 'ops_edit':
  2577. case 'dic_edit':
  2578. case 'pth_edit': {
  2579. const f = function (rawData) {
  2580. const [summaryInput] = document.getElementsByName('summary');
  2581. const [yearInput] = document.getElementsByName('year');
  2582. const [labelInput] = document.getElementsByName('record_label');
  2583. const [catalogInput] = document.getElementsByName('catalogue_number');
  2584. const data = yadg.prepareRawResponse(rawData);
  2585.  
  2586. summaryInput.value = 'YADG Update';
  2587. if (yearInput && yearInput.getAttribute('disabled') !== 'disabled') {
  2588. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2589. }
  2590.  
  2591. if (
  2592. labelInput &&
  2593. labelInput.getAttribute('disabled') !== 'disabled'
  2594. ) {
  2595. yadgUtil.setValueIfSet(
  2596. data.label,
  2597. labelInput,
  2598. data.label !== false
  2599. );
  2600. }
  2601.  
  2602. if (
  2603. catalogInput &&
  2604. catalogInput.getAttribute('disabled') !== 'disabled'
  2605. ) {
  2606. yadgUtil.setValueIfSet(
  2607. data.catalog,
  2608. catalogInput,
  2609. data.catalog !== false
  2610. );
  2611. }
  2612. };
  2613.  
  2614. return f;
  2615. }
  2616.  
  2617. case 'nwcd_torrent_overview':
  2618. case 'ops_torrent_overview':
  2619. case 'dic_torrent_overview':
  2620. case 'pth_torrent_overview': {
  2621. const f = function (rawData) {
  2622. let artistInputs = document.getElementsByName('aliasname[]');
  2623. const data = yadg.prepareRawResponse(rawData);
  2624.  
  2625. if (data.artists === false) {
  2626. for (const element of artistInputs) {
  2627. element.value = '';
  2628. }
  2629. } else {
  2630. let inputIdx = 0;
  2631.  
  2632. yadgUtil.addRemoveArtistBoxes(
  2633. data.effective_artist_count - artistInputs.length
  2634. );
  2635.  
  2636. artistInputs = document.getElementsByName('aliasname[]');
  2637.  
  2638. for (let i = 0; i < data.artist_keys.length; i++) {
  2639. const artistKey = data.artist_keys[i];
  2640. const artistTypes = data.artists[artistKey];
  2641.  
  2642. for (const artistType of artistTypes) {
  2643. const artistInput = artistInputs[inputIdx];
  2644. let typeSelect = artistInput.nextSibling;
  2645.  
  2646. while (typeSelect.tagName !== 'SELECT') {
  2647. typeSelect = typeSelect.nextSibling;
  2648. }
  2649.  
  2650. artistInput.value = artistKey;
  2651.  
  2652. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2653.  
  2654. if (artistType === 'main') {
  2655. typeSelect.selectedIndex = optionOffsets[1];
  2656. } else if (artistType === 'guest') {
  2657. typeSelect.selectedIndex = optionOffsets[2];
  2658. } else if (artistType === 'remixer') {
  2659. typeSelect.selectedIndex = optionOffsets[3];
  2660. } else {
  2661. // We don't know this artist type, default to "main"
  2662. typeSelect.selectedIndex = optionOffsets[1];
  2663. }
  2664.  
  2665. // Next artist input
  2666. inputIdx += 1;
  2667. }
  2668. }
  2669. }
  2670. };
  2671.  
  2672. return f;
  2673. }
  2674.  
  2675. case 'nwcd_request':
  2676. case 'nwcd_request_edit':
  2677. case 'ops_request':
  2678. case 'ops_request_edit':
  2679. case 'dic_request':
  2680. case 'dic_request_edit':
  2681. case 'pth_request':
  2682. case 'pth_request_edit': {
  2683. const f = function (rawData) {
  2684. let artistInputs = document.getElementsByName('artists[]');
  2685. const [albumTitleInput] = document.getElementsByName('title');
  2686. const [yearInput] = document.getElementsByName('year');
  2687. const [labelInput] = document.getElementsByName('recordlabel');
  2688. const [catalogInput] = document.getElementsByName('cataloguenumber');
  2689. const tagsInput = document.querySelector('#tags');
  2690. const data = yadg.prepareRawResponse(rawData);
  2691. let nullArtistCount = 0;
  2692.  
  2693. if (!/groupid=\d+/.test(document.location.search)) {
  2694. if (data.artists === false) {
  2695. for (const element of artistInputs) {
  2696. element.value = '';
  2697. }
  2698. } else {
  2699. let inputIdx = 0;
  2700.  
  2701. yadgUtil.addRemoveArtistBoxes(
  2702. data.effective_artist_count - artistInputs.length
  2703. );
  2704.  
  2705. artistInputs = document.getElementsByName('artists[]');
  2706.  
  2707. for (let i = 0; i < data.artist_keys.length; i++) {
  2708. const artistKey = data.artist_keys[i];
  2709. const artistTypes = data.artists[artistKey];
  2710. if (artistKey === 'null') {
  2711. nullArtistCount++;
  2712. continue;
  2713. }
  2714.  
  2715. for (const artistType of artistTypes) {
  2716. const artistInput = artistInputs[inputIdx];
  2717. let typeSelect = artistInput.nextSibling;
  2718.  
  2719. while (typeSelect.tagName !== 'SELECT') {
  2720. typeSelect = typeSelect.nextSibling;
  2721. }
  2722.  
  2723. artistInput.value = artistKey;
  2724.  
  2725. const optionOffsets = yadgUtil.getOptionOffsets(typeSelect);
  2726.  
  2727. if (artistType === 'main') {
  2728. typeSelect.selectedIndex = optionOffsets[1];
  2729. } else if (artistType === 'guest') {
  2730. typeSelect.selectedIndex = optionOffsets[2];
  2731. } else if (artistType === 'remixer') {
  2732. typeSelect.selectedIndex = optionOffsets[3];
  2733. } else {
  2734. // We don't know this artist type, default to "main"
  2735. typeSelect.selectedIndex = optionOffsets[1];
  2736. }
  2737.  
  2738. // Next artist input
  2739. inputIdx += 1;
  2740. }
  2741. }
  2742.  
  2743. if (nullArtistCount > 0) {
  2744. yadgUtil.addRemoveArtistBoxes((nullArtistCount *= -1));
  2745. }
  2746. }
  2747.  
  2748. if (data.tags === false) {
  2749. tagsInput.value = '';
  2750. } else {
  2751. tagsInput.value = data.tag_string.toLowerCase();
  2752. }
  2753.  
  2754. yadgUtil.setValueIfSet(
  2755. data.title,
  2756. albumTitleInput,
  2757. data.title !== false
  2758. );
  2759. }
  2760.  
  2761. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2762. yadgUtil.setValueIfSet(data.label, labelInput, data.label !== false);
  2763. yadgUtil.setValueIfSet(
  2764. data.catalog,
  2765. catalogInput,
  2766. data.catalog !== false
  2767. );
  2768. };
  2769.  
  2770. return f;
  2771. }
  2772.  
  2773. case 'waffles_upload': {
  2774. const f = function (rawData) {
  2775. const [artistInput] = document.getElementsByName('artist');
  2776. const [albumTitleInput] = document.getElementsByName('album');
  2777. const [yearInput] = document.getElementsByName('year');
  2778. const vaCheckbox = document.querySelector('#va');
  2779. const tagsInput = document.querySelector('#tags');
  2780. const data = yadg.prepareRawResponse(rawData);
  2781.  
  2782. if (data.artists === false) {
  2783. vaCheckbox.checked = false;
  2784. artistInput.value = '';
  2785. } else if (data.is_various) {
  2786. artistInput.value = '';
  2787. vaCheckbox.checked = true;
  2788. } else {
  2789. artistInput.value = data.flat_artistString;
  2790. vaCheckbox.checked = false;
  2791. }
  2792.  
  2793. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2794. yadgUtil.setValueIfSet(
  2795. data.title,
  2796. albumTitleInput,
  2797. data.title !== false
  2798. );
  2799.  
  2800. if (data.tags === false) {
  2801. tagsInput.value = '';
  2802. } else {
  2803. tagsInput.value = data.tag_string_nodots.toLowerCase();
  2804. }
  2805.  
  2806. yadgUtil.exec(() => {
  2807. formatName();
  2808. });
  2809. };
  2810.  
  2811. return f;
  2812. }
  2813.  
  2814. case 'waffles_upload_new': {
  2815. const f = function (rawData) {
  2816. const artistInput = document.querySelector('#id_artist');
  2817. const albumTitleInput = document.querySelector('#id_album');
  2818. const yearInput = document.querySelector('#id_year');
  2819. const vaCheckbox = document.querySelector('#id_va');
  2820. const tagsInput = document.querySelector('#id_tags');
  2821. const data = yadg.prepareRawResponse(rawData);
  2822.  
  2823. if (data.artists === false) {
  2824. if (vaCheckbox.checked) {
  2825. vaCheckbox.click();
  2826. }
  2827.  
  2828. artistInput.value = '';
  2829. } else if (data.is_various) {
  2830. if (!vaCheckbox.checked) {
  2831. vaCheckbox.click();
  2832. }
  2833. } else {
  2834. if (vaCheckbox.checked) {
  2835. vaCheckbox.click();
  2836. }
  2837.  
  2838. artistInput.value = data.flat_artistString;
  2839. }
  2840.  
  2841. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2842. yadgUtil.setValueIfSet(
  2843. data.title,
  2844. albumTitleInput,
  2845. data.title !== false
  2846. );
  2847.  
  2848. if (data.tags === false) {
  2849. tagsInput.value = '';
  2850. } else {
  2851. tagsInput.value = data.tag_string_nodots.toLowerCase();
  2852. }
  2853. };
  2854.  
  2855. return f;
  2856. }
  2857.  
  2858. case 'waffles_request': {
  2859. const f = function (rawData) {
  2860. const [artistInput] = document.getElementsByName('artist');
  2861. const [albumTitleInput] = document.getElementsByName('title');
  2862. const [yearInput] = document.getElementsByName('year');
  2863. const data = yadg.prepareRawResponse(rawData);
  2864.  
  2865. if (data.artists === false) {
  2866. artistInput.value = '';
  2867. } else if (data.is_various) {
  2868. artistInput.value = 'Various Artists';
  2869. } else {
  2870. artistInput.value = data.flat_artistString;
  2871. }
  2872.  
  2873. yadgUtil.setValueIfSet(data.year, yearInput, data.year !== false);
  2874. yadgUtil.setValueIfSet(
  2875. data.title,
  2876. albumTitleInput,
  2877. data.title !== false
  2878. );
  2879. };
  2880.  
  2881. return f;
  2882. }
  2883.  
  2884. default:
  2885. // That should actually never happen
  2886. return function () { };
  2887. }
  2888. }
  2889. };
  2890.  
  2891. yadgTemplates = {
  2892. _templates: {},
  2893. _templateUrls: {},
  2894.  
  2895. getTemplate(id, callback) {
  2896. if (id in this._templates) {
  2897. callback(this._templates[id]);
  2898. } else if (id in this._templateUrls) {
  2899. const request = new Requester(
  2900. this._templateUrls[id],
  2901. 'GET',
  2902. template => {
  2903. yadgTemplates.addTemplate(template);
  2904. callback(template);
  2905. },
  2906. null,
  2907. yadgTemplates.errorTemplate
  2908. );
  2909. request.send();
  2910. } else {
  2911. this.errorTemplate();
  2912. }
  2913. },
  2914.  
  2915. addTemplate(template) {
  2916. this._templates[template.id] = template;
  2917. },
  2918.  
  2919. addTemplateUrl(id, url) {
  2920. this._templateUrls[id] = url;
  2921. },
  2922.  
  2923. errorTemplate() {
  2924. yadg.printError('Could not get template. Please choose another one.', true);
  2925. }
  2926. };
  2927.  
  2928. yadgRenderer = {
  2929. _lastData: null,
  2930. _lastTemplateId: null,
  2931.  
  2932. render(templateId, data, callback, errorCallback) {
  2933. this._lastData = data;
  2934. const newTemplate = this._lastTemplateId !== templateId;
  2935. this._lastTemplateId = templateId;
  2936.  
  2937. yadgTemplates.getTemplate(templateId, template => {
  2938. // The new template might have different dependencies, so initialize Swig with those
  2939. if (newTemplate) {
  2940. yadgSandbox.resetSandbox();
  2941. yadgSandbox.initializeSwig(template.dependencies);
  2942. }
  2943.  
  2944. template.code = template.code.replace(
  2945. 'https://what.cd',
  2946. 'https://' + window.location.hostname
  2947. );
  2948. yadgSandbox.renderTemplate(template.code, data, callback, errorCallback);
  2949. });
  2950. },
  2951.  
  2952. renderCached(templateId, callback, errorCallback) {
  2953. if (this.hasCached()) {
  2954. this.render(templateId, this._lastData, callback, errorCallback);
  2955. }
  2956. },
  2957.  
  2958. hasCached() {
  2959. return this._lastData !== null;
  2960. },
  2961.  
  2962. clearCached() {
  2963. this._lastData = null;
  2964. }
  2965. };
  2966.  
  2967. yadg = {
  2968. yadgHost: 'https://yadg.cc',
  2969. baseURI: '/api/v2/',
  2970.  
  2971. standardError:
  2972. '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.',
  2973. authenticationError:
  2974. 'Your API token is invalid. Please provide a valid API token or remove the current one.',
  2975. lastStateError: false,
  2976.  
  2977. isBusy: false,
  2978.  
  2979. init() {
  2980. this.scraperSelect = document.querySelector('#yadg_scraper');
  2981. this.formatSelect = document.querySelector('#yadg_format');
  2982. this.input = document.querySelector('#yadg_input');
  2983. this.targetSelect = document.querySelector('#yadg_target');
  2984. this.targetDescriptionSelect = document.querySelector(
  2985. '#yadg_description_target'
  2986. );
  2987. this.responseDiv = document.querySelector('#yadg_response');
  2988. this.button = document.querySelector('#yadg_submit');
  2989. },
  2990.  
  2991. getBaseURL() {
  2992. return this.yadgHost + this.baseURI;
  2993. },
  2994.  
  2995. getScraperList(callback) {
  2996. const url = this.getBaseURL() + 'scrapers/';
  2997.  
  2998. const request = new Requester(url, 'GET', callback);
  2999.  
  3000. request.send();
  3001. },
  3002.  
  3003. getFormatsList(callback) {
  3004. const url = this.getBaseURL() + 'templates/';
  3005.  
  3006. this.getTemplates(url, [], callback);
  3007. },
  3008.  
  3009. getTemplates(url, templates, callback) {
  3010. const request = new Requester(url, 'GET', data => {
  3011. for (let i = 0; i < data.results.length; i++) {
  3012. templates.push(data.results[i]);
  3013. }
  3014.  
  3015. if (data.next === null) {
  3016. callback(templates);
  3017. } else {
  3018. yadg.getTemplates(data.next, templates, callback);
  3019. }
  3020. });
  3021.  
  3022. request.send();
  3023. },
  3024.  
  3025. makeRequest(params) {
  3026. if (this.isBusy) {
  3027. return;
  3028. }
  3029.  
  3030. let data;
  3031. if (params) {
  3032. data = params;
  3033. } else {
  3034. // If beta.musicbrainz.org link strip query params and remove beta
  3035. if (this.input.value.includes('beta.musicbrainz.org')) {
  3036. this.input.value = this.input.value.replace(/beta./, '');
  3037. this.input.value = this.input.value.replace(/\?.*$/, '');
  3038. }
  3039.  
  3040. data = {
  3041. scraper: this.scraperSelect.options[this.scraperSelect.selectedIndex]
  3042. .value,
  3043. input: this.input.value
  3044. };
  3045. }
  3046.  
  3047. const url = this.getBaseURL() + 'query/';
  3048.  
  3049. if (data.input !== '') {
  3050. const request = new Requester(
  3051. url,
  3052. 'POST',
  3053. result => {
  3054. yadg.getResult(result.url);
  3055. },
  3056. data
  3057. );
  3058. this.busyStart();
  3059. request.send();
  3060. }
  3061. },
  3062.  
  3063. getResult(resultUrl) {
  3064. const request = new Requester(resultUrl, 'GET', response => {
  3065. if (response.status === 'done') {
  3066. if (response.data.type === 'ReleaseResult') {
  3067. const templateId =
  3068. yadg.formatSelect.options[yadg.formatSelect.selectedIndex].value;
  3069. yadgRenderer.render(
  3070. templateId,
  3071. response,
  3072. factory.setDescriptionBoxValue,
  3073. factory.setDescriptionBoxValue
  3074. );
  3075.  
  3076. if (yadg.lastStateError === true) {
  3077. yadg.responseDiv.innerHTML = '';
  3078. yadg.lastStateError = false;
  3079. }
  3080.  
  3081. const fillFunc = factory.getFormFillFunction();
  3082. fillFunc(response.data);
  3083. } else if (response.data.type === 'ListResult') {
  3084. const ul = document.createElement('ul');
  3085. ul.id = 'yadg_release_list';
  3086.  
  3087. const releaseList = response.data.items;
  3088. for (const element of releaseList) {
  3089. const {name, info, queryParams} = element;
  3090. const releaseUrl = element.url;
  3091.  
  3092. const li = document.createElement('li');
  3093. const a = document.createElement('a');
  3094.  
  3095. a.textContent = name;
  3096. a.params = queryParams;
  3097. a.href = releaseUrl;
  3098.  
  3099. a.addEventListener(
  3100. 'click',
  3101. function (e) {
  3102. e.preventDefault();
  3103. yadg.makeRequest(this.params);
  3104. if (factory.getFetchImageCheckbox().checked) {
  3105. fetchImage(this.href, data => {
  3106. insertImage(data, () => {
  3107. if (
  3108. factory.getAutoRehostCheckbox() &&
  3109. factory.getAutoRehostCheckbox().checked
  3110. ) {
  3111. pthImgIt();
  3112. }
  3113. });
  3114. });
  3115. }
  3116. },
  3117. false
  3118. );
  3119.  
  3120. li.append(a);
  3121. li.append(document.createElement('br'));
  3122. if (info) {
  3123. li.append(document.createTextNode(info));
  3124. }
  3125.  
  3126. ul.append(li);
  3127. }
  3128.  
  3129. if (ul.childNodes.length === 0) {
  3130. yadg.printError('Sorry, there were no matches.');
  3131. } else {
  3132. yadg.responseDiv.innerHTML = '';
  3133. yadg.responseDiv.append(ul);
  3134. yadg.lastStateError = false;
  3135.  
  3136. // We got a ListResult so clear the last ReleaseResult from the render cache
  3137. yadgRenderer.clearCached();
  3138. }
  3139. } else if (response.data.type === 'NotFoundResult') {
  3140. yadg.printError(
  3141. 'I could not find the release with the given ID. You may want to try again with another one.'
  3142. );
  3143. } else {
  3144. yadg.printError('Something weird happened. Please try again');
  3145. }
  3146.  
  3147. yadg.busyStop();
  3148. } else if (response.status === 'failed') {
  3149. yadg.failedCallback();
  3150. } else {
  3151. const delay = function () {
  3152. yadg.getResult(response.url);
  3153. };
  3154.  
  3155. window.setTimeout(delay, 1000);
  3156. }
  3157. });
  3158. request.send();
  3159. },
  3160.  
  3161. printError(message, templateError) {
  3162. this.responseDiv.innerHTML = message;
  3163. if (!templateError) {
  3164. this.lastStateError = true;
  3165.  
  3166. // There was a non template related error, so for consistencies sake clear the last ReleaseResult from the
  3167. // render cache
  3168. yadgRenderer.clearCached();
  3169. }
  3170. },
  3171.  
  3172. failedCallback() {
  3173. yadg.printError(yadg.standardError);
  3174. yadg.busyStop();
  3175. },
  3176.  
  3177. failedAuthenticationCallback() {
  3178. yadg.printError(yadg.authenticationError);
  3179. yadg.busyStop();
  3180. },
  3181.  
  3182. busyStart() {
  3183. this.isBusy = true;
  3184. this.button.setAttribute('disabled', true);
  3185. this.button.value = 'Please wait...';
  3186. this.input.setAttribute('disabled', true);
  3187. this.scraperSelect.setAttribute('disabled', true);
  3188. this.formatSelect.setAttribute('disabled', true);
  3189. this.targetSelect.setAttribute('disabled', true);
  3190. },
  3191.  
  3192. busyStop() {
  3193. this.button.removeAttribute('disabled');
  3194. this.button.value = 'Fetch';
  3195. this.input.removeAttribute('disabled');
  3196. this.scraperSelect.removeAttribute('disabled');
  3197. this.formatSelect.removeAttribute('disabled');
  3198. this.targetSelect.removeAttribute('disabled');
  3199. this.isBusy = false;
  3200. },
  3201.  
  3202. // eslint-disable-next-line complexity
  3203. prepareRawResponse(rawData) {
  3204. const result = {};
  3205.  
  3206. result.artists = false;
  3207. result.year = false;
  3208. result.title = false;
  3209. result.label = false;
  3210. result.catalog = false;
  3211. result.genre = false;
  3212. result.style = false;
  3213. result.tags = false;
  3214. result.is_various = false; // eslint-disable-line camelcase
  3215. result.flat_artistString = false; // eslint-disable-line camelcase
  3216.  
  3217. if (rawData.artists.length > 0) {
  3218. result.artists = {};
  3219.  
  3220. for (let i = 0; i < rawData.artists.length; i++) {
  3221. const artist = rawData.artists[i];
  3222. if (artist.isVarious) {
  3223. result.is_various = true; // eslint-disable-line camelcase
  3224. } else {
  3225. result.artists[artist.name] = artist.types;
  3226. }
  3227. }
  3228. }
  3229.  
  3230. if (rawData.discs.length > 0) {
  3231. for (let k = 0; k < rawData.discs.length; k++) {
  3232. const disc = rawData.discs[k];
  3233. for (let l = 0; l < disc.tracks.length; l++) {
  3234. const track = disc.tracks[l];
  3235. for (let m = 0; m < track.artists.length; m++) {
  3236. const {name} = track.artists[m];
  3237. const type = track.artists[m].types;
  3238.  
  3239. let newTypes = null;
  3240. if (name in result.artists) {
  3241. newTypes = result.artists[name].concat(type);
  3242. // Deduplicate new types array
  3243. for (let i = 0; i < newTypes.length; ++i) {
  3244. for (let j = i + 1; j < newTypes.length; ++j) {
  3245. if (newTypes[i] === newTypes[j]) {
  3246. newTypes.splice(j--, 1);
  3247. }
  3248. }
  3249. }
  3250. } else {
  3251. newTypes = type;
  3252. }
  3253.  
  3254. result.artists[name] = newTypes;
  3255. }
  3256. }
  3257. }
  3258. }
  3259.  
  3260. for (let i = 0; i < rawData.releaseEvents.length; i++) {
  3261. const event = rawData.releaseEvents[i];
  3262. if (event.date) {
  3263. [result.year] = event.date.match(/\d{4}/);
  3264. if (result.year.length === 4) {
  3265. break;
  3266. } else {
  3267. result.year = false;
  3268. }
  3269. }
  3270. }
  3271.  
  3272. if (rawData.title) {
  3273. result.title = rawData.title;
  3274. }
  3275.  
  3276. if (rawData.labelIds.length > 0) {
  3277. const [labelId] = rawData.labelIds;
  3278. if (labelId.label) {
  3279. result.label = labelId.label;
  3280. }
  3281.  
  3282. if (labelId.catalogueNrs.length > 0) {
  3283. [result.catalog] = labelId.catalogueNrs;
  3284. }
  3285. }
  3286.  
  3287. if (rawData.genres.length > 0) {
  3288. result.genre = rawData.genres;
  3289. }
  3290.  
  3291. if (rawData.styles.length > 0) {
  3292. result.style = rawData.styles;
  3293. }
  3294.  
  3295. if (result.genre !== false && result.style !== false) {
  3296. result.tags = rawData.genres.concat(rawData.styles);
  3297. } else if (result.genre !== false) {
  3298. result.tags = rawData.genres;
  3299. } else if (result.style !== false) {
  3300. result.tags = rawData.styles;
  3301. }
  3302.  
  3303. if (result.tags !== false) {
  3304. result.tag_string = ''; // eslint-disable-line camelcase
  3305. result.tag_string_nodots = ''; // eslint-disable-line camelcase
  3306.  
  3307. for (let i = 0; i < result.tags.length; i++) {
  3308. result.tag_string += result.tags[i].replace(/\s+/g, '.'); // eslint-disable-line camelcase
  3309. result.tag_string_nodots += result.tags[i].replace(/\s+/g, ' '); // eslint-disable-line camelcase
  3310. if (i !== result.tags.length - 1) {
  3311. result.tag_string += ', '; // eslint-disable-line camelcase
  3312. result.tag_string_nodots += ', '; // eslint-disable-line camelcase
  3313. }
  3314. }
  3315. }
  3316.  
  3317. if (result.artists !== false) {
  3318. // Count the artists
  3319. result.artists_length = 0; // eslint-disable-line camelcase
  3320. result.artist_keys = []; // eslint-disable-line camelcase
  3321. result.effective_artist_count = 0; // eslint-disable-line camelcase
  3322.  
  3323. for (const i in result.artists) {
  3324. if ({}.hasOwnProperty.call(result.artists, i)) {
  3325. result.artists_length++;
  3326. result.artist_keys.push(i);
  3327. result.effective_artist_count += result.artists[i].length; // eslint-disable-line camelcase
  3328. }
  3329. }
  3330. }
  3331.  
  3332. if (result.artists_length === 0) {
  3333. result.artists = false;
  3334. } else {
  3335. // Create a flat string of all the main artists
  3336. let artistString = '';
  3337.  
  3338. for (let i = 0; i < result.artists_length; i++) {
  3339. if (result.artists[result.artist_keys[i]].includes('main')) {
  3340. if (artistString !== '' && i < result.artists_length - 2) {
  3341. artistString += ', ';
  3342. } else if (artistString !== '' && i < result.artists_length - 1) {
  3343. artistString += ' & ';
  3344. }
  3345.  
  3346. artistString += result.artist_keys[i];
  3347. }
  3348. }
  3349.  
  3350. result.flat_artistString = artistString; // eslint-disable-line camelcase
  3351. }
  3352.  
  3353. return result;
  3354. }
  3355. };
  3356.  
  3357. yadgSandbox.init(() => {
  3358. if (factory.init()) {
  3359. // Returns true if we run on a valid location
  3360. yadg.init();
  3361. }
  3362. });
  3363.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement