Files
crossfade/userscript.js
T

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);
}
});
})();