353 lines
19 KiB
JavaScript
353 lines
19 KiB
JavaScript
// ==UserScript==
|
|
// @name Redacted :: Import JSON to Upload Form
|
|
// @namespace https://greasyfork.org/en/scripts/393534-redacted-import-json-to-upload-form
|
|
// @version 2.0.0
|
|
// @description Adds buttons to attach and parse a .json file from NWCD, OPS, or Crossfade to fill in the upload form.
|
|
// @author newstarshipsmell & rewritten by anon28410 for Crossfade
|
|
// @include /https://redacted\.sh/upload\.php/
|
|
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAOTSURBVFhH7ZdbSJNhHMY/TTfCusjMtCiaMjFdXmQwL2wX4YgowguDEsGEKIjCSJC8yc4SeeguKI2oC7uolZrK1kkJs1Ir0dKmlkWGh06C0Zmn//9l73pbn+sru3TwY9vzPv/nfeb3bh9qADSDjxgil6gk7hOvCR5mxog24gSRTURNTED7E2JvAwVSCBchNzPKZcKut7HESIGThAg0m81YsyYLpaWVaGpqx8DAKMbHv+P9+2/o7x/B9et3UVJyAk5npvDKOaKKfJoewQrMJvgTICwsDNnZ2/HkySu8ffvFEH19w9iypUAt0kjMoTVNJViBWgIxMbGoqWnG6OhHQXt7HwoKDiM9fS1iYxeIciaTGfPmRSM1dSW2bSvEjRsdfr/Hcw+LFi2RJTxEOOmaZLICfMhog4Vobe3B0NAEentHkJOzQ2zIa3/C4cgUZXmWny2WOLl2ljRNolfASSA83ASXqxmDg+NoaelFQsJSGWCYqKhof4bH04GIiAi5tok0jdEr4CawdWsRvN431P4ZrNZkOfjXREbOxbVrD0VWYWGZ1G/Se40JLLCaoOs5nzZ+ju7uEWRkbJRD/8yyZXZ0dQ2js3MIixf7L0UO5f9WoJpAbu4edNwfQmVlA0JCQuTAlDh4sEpk7io4JrU6ev9LgRm8EBoaStftHh2+F0hLWyfNUyYpKVVkut3d9K0xSX2mWiCVRavVhqbmp6ipe2j4xBvlzNkmkW2zOaS2Wi2Qz6LTuRnuq17k51dI038jL2+fyM7K2i21Q2oBcf237yxHXX0PHKtypEkXE1FC9BMDvtes6XklK1asF9mFRSel1qAW6GSx5KgLFy91ISFxuTTpcoR4E8BeQs8rsViSRHZFRb3UvGoBcWu12zeQMVEaJoU/eWAB1vS8Kpydlu7/an9QC3zziYb41wKBqAWEYLEko/jAedQ3PEZb20u6zb7D2Ngn/4BE7xIUE4E+uueLec5pvfMCpRWXEB9v86+rBT6yULz/AqrPP0CjuzdoAXkI+QAGO4RqgbuUx7nl5Q1y/dNvf4FTVXcMFTCKXgHOl+vTBaYLTBeYLqAW6GPB6C+hUfQKKL+Eg2qB0yzGxSVj775q1F55NFkBB3GMaCGGic8++DVrvMYe4VcLtNweRFmZC/HWFJl1Ti1gJjp8C5Nxi71GYK8ypwf/dz1LeAMGjxPtxFdCHeBAm+oNBnt9M2oGZ3L28Z9eaD8A1I4FiHzaEHoAAAAASUVORK5CYII=
|
|
// @grant none
|
|
// ==/UserScript==
|
|
|
|
(function () {
|
|
'use strict';
|
|
var sourceWebsites = ['NWCD', 'OPS', 'Crossfade'];
|
|
var sourceWebsiteDomains = ['notwhat.cd', 'orpheus.network', 'crossfade.local'];
|
|
var sourceWebsite, sourceWebsiteIndex;
|
|
var JSONReleaseTypes = {
|
|
'NWCD': {
|
|
'1': 'Album', '3': 'Soundtrack', '5': 'EP', '6': 'Anthology', '7': 'Compilation', '9': 'Single', '11': 'Live album', '13': 'Remix', '14': 'Bootleg', '15': 'Interview', '16': 'Mixtape', '17': 'Sampler', '21': 'Unknown', '22': 'Demo', '23': 'DJ Mix', '24': 'Concert Recording'
|
|
},
|
|
'OPS': {
|
|
'1': 'Album', '3': 'Soundtrack', '5': 'EP', '6': 'Anthology', '7': 'Compilation', '9': 'Single', '11': 'Live album', '13': 'Remix', '14': 'Bootleg', '15': 'Interview', '16': 'Mixtape', '17': 'DJ Mix', '18': 'Concert recording', '21': 'Unknown'
|
|
},
|
|
'Crossfade': {
|
|
'1': 'Album', '3': 'Soundtrack', '5': 'EP', '6': 'Anthology', '7': 'Compilation', '9': 'Single', '11': 'Live album', '13': 'Remix', '14': 'Bootleg', '15': 'Interview', '16': 'Mixtape', '17': 'DJ Mix', '18': 'Concert recording', '21': 'Unknown'
|
|
}
|
|
};
|
|
|
|
var addFormat = /(\?|&)groupid=/.test(location.href) ? true : false;
|
|
var uploadRequest = /(\?|&)requestid=/.test(location.href) ? true : false;
|
|
|
|
var ChooseTypeDropdown = document.getElementById('categories');
|
|
|
|
var ChooseJSONTR = document.createElement('tr');
|
|
|
|
var ChooseJSONTD = document.createElement('td');
|
|
ChooseJSONTD.classList.add('label');
|
|
ChooseJSONTD.textContent = 'JSON file:';
|
|
|
|
var ChooseJSONBtnTD = document.createElement('td');
|
|
|
|
var ChooseJSONBtn = document.createElement('input');
|
|
ChooseJSONBtn.id = 'json';
|
|
ChooseJSONBtn.type = 'file';
|
|
ChooseJSONBtn.name = 'json_input';
|
|
ChooseJSONBtn.accept = '.application/json,.json';
|
|
|
|
var ChooseJSONPasteBtn = document.createElement('button');
|
|
ChooseJSONPasteBtn.textContent = 'Paste JSON';
|
|
ChooseJSONPasteBtn.type = 'button';
|
|
ChooseJSONPasteBtn.style.marginLeft = '10px';
|
|
ChooseJSONPasteBtn.style.padding = '2px 8px';
|
|
ChooseJSONPasteBtn.style.cursor = 'pointer';
|
|
|
|
ChooseJSONTR.appendChild(ChooseJSONTD);
|
|
ChooseJSONTR.appendChild(ChooseJSONBtnTD);
|
|
ChooseJSONBtnTD.appendChild(ChooseJSONBtn);
|
|
ChooseJSONBtnTD.appendChild(ChooseJSONPasteBtn);
|
|
ChooseTypeDropdown.parentNode.parentNode.parentNode.insertBefore(ChooseJSONTR, ChooseTypeDropdown.parentNode.parentNode);
|
|
|
|
function processJSON(releaseJSON, filename) {
|
|
// Determine source
|
|
if (releaseJSON.response && releaseJSON.response.source === 'Crossfade') {
|
|
sourceWebsite = 'Crossfade';
|
|
sourceWebsiteIndex = 2;
|
|
} else {
|
|
sourceWebsiteIndex = /NWCD .+\.json/.test(filename) ? 0 : (/.+(\.opsnet| \[orpheus\.network\])\.json/.test(filename) ? 1 : -1);
|
|
sourceWebsite = sourceWebsiteIndex > -1 && sourceWebsiteIndex < sourceWebsites.length ? sourceWebsites[sourceWebsiteIndex] : "N/A";
|
|
}
|
|
|
|
if (sourceWebsite == 'N/A') {
|
|
alert('The userscript failed to parse a supported website from the json filename or content! Aborting...')
|
|
return;
|
|
}
|
|
|
|
var categories = ['Music', 'Applications', 'E-Books', 'Audiobooks', 'E-Learning Videos', 'Comedy', 'Comics'];
|
|
var category = document.getElementById('categories');
|
|
var categoryJSON = parseInt(releaseJSON.response.group.categoryId);
|
|
var categoryNameJSON = releaseJSON.response.group.categoryName;
|
|
var categoryIndex = categories.indexOf(categoryNameJSON);
|
|
|
|
if (categoryIndex > -1) {
|
|
if (categoryIndex != 0) {
|
|
alert('Currently only Music category torrents are supported. Aborting...');
|
|
return;
|
|
} else {
|
|
category.selectedIndex = categories.indexOf(categoryNameJSON);
|
|
// Trigger change event to load fields
|
|
var event = new Event('change');
|
|
category.dispatchEvent(event);
|
|
}
|
|
} else {
|
|
alert('The category name indicated in the JSON (' + categoryNameJSON + ') is not one of the available category types! Aborting...');
|
|
return;
|
|
}
|
|
|
|
// Wait a bit for fields to load if category changed
|
|
setTimeout(function () {
|
|
switch (categoryIndex) {
|
|
case 0:
|
|
if (!addFormat) {
|
|
if (!uploadRequest) {
|
|
var artists = [];
|
|
var artistRoles = [
|
|
{ 'name': 'artists', 'index': 0 },
|
|
{ 'name': 'with', 'index': 1 },
|
|
{ 'name': 'composers', 'index': 2 },
|
|
{ 'name': 'conductor', 'index': 3 },
|
|
{ 'name': 'dj', 'index': 4 },
|
|
{ 'name': 'remixedBy', 'index': 5 },
|
|
{ 'name': 'producer', 'index': 6 },
|
|
];
|
|
var artistsJSON = releaseJSON.response.group.musicInfo;
|
|
|
|
for (var i = 0, len = artistRoles.length; i < len; i++) {
|
|
if (!artistsJSON[artistRoles[i].name] || artistsJSON[artistRoles[i].name].length == 0) continue;
|
|
for (var j = 0, lenj = artistsJSON[artistRoles[i].name].length; j < lenj; j++) {
|
|
artists.push({ 'name': artistsJSON[artistRoles[i].name][j].name, 'index': artistRoles[i].index });
|
|
}
|
|
}
|
|
|
|
if (artists.length > 0) {
|
|
var artistInputs = [];
|
|
artistInputs.length = artists.length;
|
|
for (i = 0, len = artists.length; i < len; i++) {
|
|
if (i > 0) {
|
|
// Check if AddArtistField exists (it should on upload page)
|
|
if (typeof window.AddArtistField === 'function') {
|
|
window.AddArtistField();
|
|
} else {
|
|
// Fallback for some versions of the site
|
|
var addLink = document.querySelector('a[onclick="AddArtistField()"]');
|
|
if (addLink) addLink.click();
|
|
}
|
|
}
|
|
artistInputs[i] = document.getElementById('artist' + (i > 0 ? '_' + i : ''));
|
|
if (artistInputs[i]) {
|
|
artistInputs[i].value = artists[i].name;
|
|
var roles = document.querySelectorAll('select#importance'); // Changed selector to match typical RED form
|
|
if (roles[i]) roles[i].selectedIndex = artists[i].index;
|
|
}
|
|
}
|
|
} else {
|
|
// alert('No artists are included in the JSON!');
|
|
}
|
|
}
|
|
|
|
var albumTitle = document.getElementById('title');
|
|
var albumTitleJSON = releaseJSON.response.group.name;
|
|
|
|
if (albumTitleJSON != '') {
|
|
albumTitle.value = albumTitleJSON;
|
|
} else {
|
|
alert('No album title is included in the JSON!');
|
|
}
|
|
|
|
var initialYear = document.getElementById('year');
|
|
var initialYearJSON = releaseJSON.response.group.year;
|
|
|
|
if (initialYearJSON != '') {
|
|
initialYear.value = initialYearJSON;
|
|
} else {
|
|
alert('No initial year is included in the JSON!');
|
|
}
|
|
|
|
var releaseType = document.getElementById('releasetype');
|
|
var releaseTypes = [];
|
|
for (i = 0, len = releaseType.options.length; i < len; i++) {
|
|
releaseTypes.push(releaseType.options[i].textContent.toLowerCase());
|
|
}
|
|
|
|
var releaseTypeIndexJSON = parseInt(releaseJSON.response.group.releaseType || 1); // Default to Album if missing
|
|
var releaseTypeNameJSON = JSONReleaseTypes[sourceWebsite][releaseTypeIndexJSON] || 'Album';
|
|
var releaseTypeIndex = releaseTypes.indexOf(releaseTypeNameJSON.toLowerCase());
|
|
|
|
if (releaseTypeIndex > -1) {
|
|
releaseType.selectedIndex = releaseTypeIndex;
|
|
}
|
|
}
|
|
|
|
var editionYear = document.getElementById('remaster_year');
|
|
var editionTitle = document.getElementById('remaster_title');
|
|
var editionLabel = document.getElementById('remaster_record_label');
|
|
var editionCatNo = document.getElementById('remaster_catalogue_number');
|
|
var edition = releaseJSON.response.torrent.remastered;
|
|
|
|
if (edition) {
|
|
var editionYearJSON = releaseJSON.response.torrent.remasterYear;
|
|
var editionTitleJSON = releaseJSON.response.torrent.remasterTitle;
|
|
var editionLabelJSON = releaseJSON.response.torrent.remasterRecordLabel;
|
|
var editionCatNoJSON = releaseJSON.response.torrent.remasterCatalogueNumber;
|
|
} else {
|
|
editionYearJSON = initialYearJSON ? initialYearJSON : releaseJSON.response.group.year;
|
|
editionTitleJSON = '';
|
|
editionLabelJSON = releaseJSON.response.group.recordLabel;
|
|
editionCatNoJSON = releaseJSON.response.group.catalogueNumber;
|
|
}
|
|
|
|
if (editionYear) editionYear.value = editionYearJSON || '';
|
|
if (editionTitle) editionTitle.value = editionTitleJSON || '';
|
|
if (editionLabel) editionLabel.value = editionLabelJSON || '';
|
|
if (editionCatNo) editionCatNo.value = editionCatNoJSON || '';
|
|
|
|
var scene = document.getElementById('scene');
|
|
var sceneJSON = releaseJSON.response.torrent.scene;
|
|
if (sceneJSON && scene) scene.checked = true;
|
|
|
|
var format = document.getElementById('format');
|
|
var formats = [];
|
|
for (i = 0, len = format.options.length; i < len; i++) {
|
|
formats.push(format.options[i].textContent.toLowerCase());
|
|
}
|
|
|
|
var formatJSON = releaseJSON.response.torrent.format;
|
|
var formatIndex = formats.indexOf(formatJSON.toLowerCase());
|
|
|
|
if (formatIndex > -1) {
|
|
format.selectedIndex = formatIndex;
|
|
}
|
|
|
|
var bitrate = document.getElementById('bitrate');
|
|
var bitrates = [];
|
|
for (i = 0, len = bitrate.options.length; i < len; i++) {
|
|
bitrates.push(bitrate.options[i].textContent.toLowerCase());
|
|
}
|
|
var otherBitrate = document.getElementById('other_bitrate');
|
|
var otherBitrateVBR = document.getElementById('vbr');
|
|
|
|
var bitrateJSON = releaseJSON.response.torrent.encoding;
|
|
var bitrateIndex = bitrates.indexOf(bitrateJSON.toLowerCase());
|
|
|
|
if (bitrateIndex > -1) {
|
|
bitrate.selectedIndex = bitrateIndex;
|
|
} else {
|
|
var otherIndex = bitrates.indexOf('other');
|
|
if (otherIndex > -1) {
|
|
bitrate.selectedIndex = otherIndex;
|
|
var span = document.getElementById('other_bitrate_span');
|
|
if (span) span.classList.remove('hidden');
|
|
if (otherBitrate) otherBitrate.value = bitrateJSON.replace(/ \(VBR\)$/i, '');
|
|
if (otherBitrateVBR) otherBitrateVBR.checked = /.+ \(VBR\)$/i.test(bitrateJSON);
|
|
}
|
|
}
|
|
|
|
var media = document.getElementById('media');
|
|
var medias = [];
|
|
for (i = 0, len = media.options.length; i < len; i++) {
|
|
medias.push(media.options[i].textContent.toLowerCase());
|
|
}
|
|
|
|
var mediaJSON = releaseJSON.response.torrent.media;
|
|
var mediaIndex = medias.indexOf(mediaJSON.toLowerCase());
|
|
|
|
if (mediaIndex > -1) {
|
|
media.selectedIndex = mediaIndex;
|
|
}
|
|
|
|
if (!addFormat) {
|
|
var tags = document.getElementById('tags');
|
|
var tagsJSON = releaseJSON.response.group.tags;
|
|
var tagList = '';
|
|
|
|
if (tagsJSON && tagsJSON.length > 0) {
|
|
for (i = 0, len = tagsJSON.length; i < len; i++) {
|
|
tagList += (i > 0 ? ', ' : '') + tagsJSON[i];
|
|
}
|
|
}
|
|
|
|
if (tags) tags.value = tagList;
|
|
|
|
var image = document.getElementById('image');
|
|
var imageJSON = releaseJSON.response.group.wikiImage;
|
|
if (image && imageJSON) image.value = imageJSON;
|
|
|
|
var albumDesc = document.getElementById('album_desc');
|
|
var albumDescJSON = releaseJSON.response.group.wikiBBcode ? releaseJSON.response.group.wikiBBcode : releaseJSON.response.group.wikiBody;
|
|
|
|
if (albumDescJSON != '') {
|
|
if (!releaseJSON.response.group.wikiBBcode) {
|
|
// Basic cleanup if needed, but Crossfade provides clean tracklist
|
|
}
|
|
|
|
if (albumDesc) {
|
|
albumDesc.value = albumDescJSON;
|
|
// Trigger preview if possible
|
|
// document.querySelector('input.button_preview_0').click();
|
|
}
|
|
}
|
|
}
|
|
|
|
var relDesc = document.getElementById('release_desc');
|
|
var relDescJSON = releaseJSON.response.torrent.description;
|
|
|
|
if (sourceWebsite !== 'Crossfade') {
|
|
var groupIDJSON = releaseJSON.response.group.id;
|
|
var torrentIDJSON = releaseJSON.response.torrent.id;
|
|
relDescJSON += (relDescJSON ? '\n\n' : '') + 'Cross-posted from ' + sourceWebsite + ': https://';
|
|
relDescJSON += sourceWebsiteDomains[sourceWebsiteIndex] + '/torrents.php?id=' + groupIDJSON + '&torrentid=' + torrentIDJSON;
|
|
}
|
|
|
|
if (relDesc) relDesc.value = relDescJSON;
|
|
|
|
// Show success message
|
|
ChooseJSONTR.innerHTML = '';
|
|
var successTD = document.createElement('td');
|
|
successTD.colSpan = 2;
|
|
successTD.style.fontWeight = 'bold';
|
|
successTD.style.color = 'green';
|
|
successTD.style.textAlign = 'center';
|
|
successTD.textContent = 'Data imported successfully!';
|
|
ChooseJSONTR.appendChild(successTD);
|
|
|
|
break;
|
|
}
|
|
}, 500); // Delay to allow category change to propagate
|
|
}
|
|
|
|
ChooseJSONBtn.addEventListener('change', function (evt) {
|
|
var file = document.getElementById('json').files[0];
|
|
|
|
if (file) {
|
|
var reader = new FileReader();
|
|
reader.readAsText(file, "UTF-8");
|
|
reader.onload = function (evt) {
|
|
var releaseJSON = JSON.parse(evt.target.result);
|
|
processJSON(releaseJSON, file.name);
|
|
}
|
|
reader.onerror = function (evt) {
|
|
alert('There was an error reading the file.');
|
|
}
|
|
} else {
|
|
alert('No JSON file has been chosen!');
|
|
}
|
|
});
|
|
|
|
ChooseJSONPasteBtn.addEventListener('click', async function () {
|
|
try {
|
|
const text = await navigator.clipboard.readText();
|
|
if (!text) {
|
|
alert('Clipboard is empty!');
|
|
return;
|
|
}
|
|
try {
|
|
const releaseJSON = JSON.parse(text);
|
|
processJSON(releaseJSON, 'clipboard.json');
|
|
} catch (e) {
|
|
alert('Failed to parse JSON from clipboard. Make sure you copied the correct content.');
|
|
}
|
|
} catch (err) {
|
|
alert('Failed to read clipboard: ' + err);
|
|
}
|
|
});
|
|
})(); |