From 43dd77488dc2a4f8287f762de4700750996732d1 Mon Sep 17 00:00:00 2001 From: herbert Date: Mon, 9 Jan 2023 19:14:25 +0100 Subject: [PATCH] initial --- README.md | 1 + sugoi_clickable_category_icons.user.js | 63 ++++++ sugoi_filter_toggle.user.js | 72 +++++++ sugoi_import_json_upload.user.js | 381 +++++++++++++++++++++++++++++++++ 4 files changed, 517 insertions(+) create mode 100644 README.md create mode 100644 sugoi_clickable_category_icons.user.js create mode 100644 sugoi_filter_toggle.user.js create mode 100644 sugoi_import_json_upload.user.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..771460b --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Various userscripts to improve SugoiMusic experience \ No newline at end of file diff --git a/sugoi_clickable_category_icons.user.js b/sugoi_clickable_category_icons.user.js new file mode 100644 index 0000000..974ff1d --- /dev/null +++ b/sugoi_clickable_category_icons.user.js @@ -0,0 +1,63 @@ +// ==UserScript== +// @name SugoiMusic Clickable Category Icons +// @namespace http://sugoimusic.me +// @version 0.1 +// @description Changes content type specified in search by clicking on the category icons +// @author herbert +// @icon https://sugoimusic.me/favicon.ico +// @match https://sugoimusic.me/torrents.php* +// @grant none +// ==/UserScript== + +const categoryMap = new Map(); +categoryMap.set('cats_album', 1); +categoryMap.set('cats_ep', 2); +categoryMap.set('cats_single', 3); +categoryMap.set('cats_bluray', 4); +categoryMap.set('cats_dvd', 5); +categoryMap.set('cats_pv', 6); +categoryMap.set('cats_musicperformance', 7); +categoryMap.set('cats_tvmusic', 8); +categoryMap.set('cats_tvvariety', 9); +categoryMap.set('cats_tvdrama', 10); +categoryMap.set('cats_pictures', 11); +categoryMap.set('cats_misc', 12); + +function removeExistingCategoriesFromUrl(urlParams, categorySearchString) { + let cleanedUrlParams = new URLSearchParams(); + for (let entry of urlParams.entries()) { + if (!entry[0].startsWith(categorySearchString) && entry[0]!='page') { + cleanedUrlParams.append(entry[0],entry[1]); + } + } + return cleanedUrlParams; +} + +(function () { + 'use strict'; + let categorySearchString = 'filter_cat'; + let urlParams = new URLSearchParams(window.location.search); + //Identify if we are on the torrent search or snatched/seeding/uploaded pages + if (urlParams.has('type')) { + categorySearchString = 'categories'; + } + urlParams = removeExistingCategoriesFromUrl(urlParams, categorySearchString); + let categoryIcons = document.querySelectorAll('div[class*="cats"]'); + for (let iconDiv of categoryIcons) { + let newCat; + for (let e of iconDiv.classList) { + if (categoryMap.has(e)) { + newCat = e; + } + } + let newUrlParams = new URLSearchParams(urlParams) + newUrlParams.append(categorySearchString + '[' + categoryMap.get(newCat) + ']','1'); + //Create new anchor wrapped around the div + let url = window.location.pathname.split('?')[0]; + let parent = iconDiv.parentNode; + let a = document.createElement('a'); + a.setAttribute('href', url + '?' + newUrlParams.toString()) + parent.replaceChild(a, iconDiv); + a.appendChild(iconDiv); + } +})(); \ No newline at end of file diff --git a/sugoi_filter_toggle.user.js b/sugoi_filter_toggle.user.js new file mode 100644 index 0000000..403d083 --- /dev/null +++ b/sugoi_filter_toggle.user.js @@ -0,0 +1,72 @@ +// ==UserScript== +// @name SugoiMusic Filter Toggle +// @namespace http://sugoimusic.me +// @version 0.1 +// @description Modifies filter bar behavior on artist pages so that mutiple categories can be selected +// @author herbert +// @icon https://sugoimusic.me/favicon.ico +// @match https://sugoimusic.me/artist.php?id=* +// @grant none +// ==/UserScript== + +function filter(e){ + if (e.getAttribute('selected') === 'true'){ + hideCategory(e); + } else { + showCategory(e); + } + apply_torrent_table_styling(); +} + +function showAll(e){ + let filterCats = document.querySelectorAll('li[id^="nav"]>a.filter-cat'); + console.log(filterCats); + for (let element of filterCats){ + console.log(element); + showCategory(element); + } + apply_torrent_table_styling(); +} + +function hideCategory(e) { + let className = e.parentElement.getAttribute('id').replace('nav_',''); + if (e.closest('#discog_table')){ + $('.non_contrib_table .'+className).ghide(); + } else { + $('.contrib_table .'+className).ghide(); + } + e.setAttribute('selected',false); + e.style.fontWeight = 'normal'; +} + +function showCategory(e) { + let className = e.parentElement.getAttribute('id').replace('nav_',''); + if (e.closest('#discog_table')){ + $('.non_contrib_table .'+className).gshow(); + } else { + $('.contrib_table .'+className).gshow(); + } + e.setAttribute('selected',true); + e.style.fontWeight = 'bold'; +} + +(function() { + 'use strict'; + let filterAll = document.querySelector('a#nav_all'); + filterAll.removeAttribute('onclick'); + filterAll.setAttribute('href','#/'); + filterAll.addEventListener('click',function(){ + showAll(this); + }); + + let filterCats = document.querySelectorAll('li[id^="nav"]>a.filter-cat'); + for (let element of filterCats){ + element.removeAttribute('onclick'); + element.setAttribute('selected',true); + element.setAttribute('href','#/'); + element.style.fontWeight = 'bold'; + element.addEventListener('click',function(event){ + filter(this); + }); + } +})(); \ No newline at end of file diff --git a/sugoi_import_json_upload.user.js b/sugoi_import_json_upload.user.js new file mode 100644 index 0000000..77149c3 --- /dev/null +++ b/sugoi_import_json_upload.user.js @@ -0,0 +1,381 @@ +// ==UserScript== +// @name SM :: Import JSON to Upload Form +// @version 0.0.1 +// @description Adds buttons to attach and parse a .json file from RED or OPS to fill in the upload form. +// @author herbert (original: newstarshipsmell) +// @include /https://sugoimusic\.me/upload\.php/ +// @grant none +// ==/UserScript== + +(function() { + 'use strict'; + var sourceWebsites = ['RED', 'OPS']; + var sourceWebsiteDomains = ['redacted.ch', 'orpheus.network']; + var sourceWebsite, sourceWebsiteIndex; + var JSONReleaseTypes = { + 'RED': { + '1': 'Album', + '3': 'Soundtrack', + '5': 'EP', + '6': 'Anthology', + '7': 'Compilation', + '9': 'Single', + '11': 'Live album', + '13': 'Remix', + '14': 'Bootleg', + '15': 'Interview', + '16': 'Mixtape', + '17': 'Demo', + '18': 'Concert Recording', + '19': 'DJ Mix', + '21': 'Unknown' + }, + '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' + } + }; + + 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 ChooseJSONParseBtn = document.createElement('input'); + ChooseJSONParseBtn.id = 'json_parse'; + ChooseJSONParseBtn.type = 'button'; + ChooseJSONParseBtn.name = 'json_parse'; + ChooseJSONParseBtn.value = 'Parse JSON'; + + ChooseJSONTR.appendChild(ChooseJSONTD); + ChooseJSONTR.appendChild(ChooseJSONBtnTD); + ChooseJSONBtnTD.appendChild(ChooseJSONBtn); + ChooseJSONBtnTD.appendChild(document.createTextNode(' | ')); + ChooseJSONBtnTD.appendChild(ChooseJSONParseBtn); + ChooseTypeDropdown.parentNode.parentNode.parentNode.insertBefore(ChooseJSONTR, ChooseTypeDropdown.parentNode.parentNode); + + ChooseJSONParseBtn.addEventListener('click', function (evt) { + var file = document.getElementById('json').files[0]; + + if (file) { + sourceWebsiteIndex = /.+ \[redacted\.ch\]\.json/.test(file.name) ? 0 : (/.+ \[orpheus\.network\]\.json/.test(file.name) ? 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! Aborting...') + return; + + } else { + var reader = new FileReader(); + reader.readAsText(file, "UTF-8"); + reader.onload = function (evt) { + var releaseJSON = JSON.parse(evt.target.result); + + 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); + } + } else { + alert('The category name indicated in the JSON (' + categoryNameJSON + ') is not one of the available category types! Aborting...'); + return; + } + + switch(categoryIndex) { + case 0: + 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].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) window.eval('AddArtistField();'); + artistInputs[i] = document.getElementById('idols_' + i ); + artistInputs[i].value = artists[i].name; + // SM does not support roles + //var roles = document.querySelectorAll('td#artistfields > #importance'); + //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('categories'); //On SM 'categories' == '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); + var releaseTypeNameJSON = JSONReleaseTypes[sourceWebsite][releaseTypeIndexJSON]; + var releaseTypeIndex = releaseTypes.indexOf(releaseTypeNameJSON.toLowerCase()); + + if (releaseTypeIndex > -1) { + releaseType.selectedIndex = releaseTypeIndex; + } else { + alert('The release type indicated in the JSON (' + releaseTypeNameJSON + ' [' + releaseTypeIndexJSON + ']) ' + + 'is not one of the available release types!\n\nManually select the appropriate release type.'); + } + + var editionYear = document.getElementById('remasteryear'); + var editionTitle = document.getElementById('remastertitle'); + //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; + document.getElementById('remaster').click(); + } else { + editionYearJSON = initialYearJSON + editionTitleJSON = ''; + //editionLabelJSON = releaseJSON.response.group.recordLabel; + //editionCatNoJSON = releaseJSON.response.group.catalogueNumber; + } + + if (editionYearJSON == '') { + alert('No edition year is included in the JSON!'); + } + + editionYear.value = editionYearJSON; + editionTitle.value = editionTitleJSON; + //editionLabel.value = editionLabelJSON; + //editionCatNo.value = editionCatNoJSON; + + //Scene does not exist on SM + //var scene = document.getElementById('scene'); + //var sceneJSON = releaseJSON.response.torrent.scene; + //if (sceneJSON) scene.checked = true; + + var format = document.getElementsByName('audioformat')[0]; + 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; + } else { + alert('The format indicated in the JSON (' + formatJSON + ') ' + + 'is not one of the available formats!\n\nManually select the appropriate formats.'); + } + + var bitrate = document.getElementsByName('bitrate')[0]; + 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 { + bitrate.selectedIndex = bitrates.indexOf('other'); + document.getElementById('other_bitrate_span').classList.remove('hidden'); + otherBitrate.value = bitrateJSON.replace(/ \(VBR\)$/i, ''); + otherBitrateVBR.checked = /.+ \(VBR\)$/i.test(bitrateJSON); + } + + var media = document.getElementsByName('media')[0]; + 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; + } else { + alert('The media indicated in the JSON (' + mediaJSON + ') ' + + 'is not one of the available media!\n\nManually select the appropriate media.'); + } + + /* SM does not support logs yet + if (formats[formatIndex] == 'flac' && bitrates[bitrateIndex] == 'lossless' && medias[mediaIndex] == 'cd') { + var hasLogJSON = releaseJSON.response.torrent.hasLog; + var logs = document.getElementById('upload_logs'); + if (hasLogJSON) logs.classList.remove('hidden'); + }*/ + + var tags = document.getElementById('tags'); + var tagsJSON = releaseJSON.response.group.tags; + var tagList = ''; + + if (tagsJSON.length > 0) { + for (i = 0, len = tagsJSON.length; i < len; i++) { + tagList += (i > 0 ? ', ' : '') + tagsJSON[i]; + } + } + + tags.value = tagList; + + var image = document.getElementById('image'); + var imageJSON = releaseJSON.response.group.wikiImage; + image.value = imageJSON; + + var albumDesc = document.getElementById('album_desc'); + var albumDescJSON = releaseJSON.response.group.wikiBody; + + if (albumDescJSON != '') { + albumDescJSON = albumDescJSON.replace(/
/g, ''); + albumDescJSON = albumDescJSON.replace(/&/g, '&'); + albumDescJSON = albumDescJSON.replace(/</g, '<'); + albumDescJSON = albumDescJSON.replace(/>/g, '>'); + albumDescJSON = albumDescJSON.replace(/"/g, '"'); + albumDescJSON = albumDescJSON.replace(/'/g, '\''); + albumDescJSON = albumDescJSON.replace(/'/g, '\''); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/a>/g, '[artist]$1[/artist]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/a>/g, '[user]$1[/user]'); + albumDescJSON = albumDescJSON.replace(/(https?:\/\/.+?)<\/a>/g, '$1'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/a>/g, '[url=$1]$2[/url]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/span>/g, '[size=$1]$2[/size]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/span>/g, '[i]$1[/i]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/span>/g, '[u]$1[/u]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/span>/g, '[s]$1[/s]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/span>/g, '[color=$1]$2[/color]'); + albumDescJSON = albumDescJSON.replace(/
(.+?)<\/div>/g, '[align=$1]$2[/align]'); + albumDescJSON = albumDescJSON.replace( + /(.+?)/g, + '[img]$1[/img]'); + albumDescJSON = albumDescJSON.replace( + /(.+?)<\/strong> wrote: <\/a>
(.+?)<\/blockquote>/g, + '[quote=$2|$1]$3[/quote]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/strong> wrote:
(.+?)<\/blockquote>/g, + '[quote=$1]$2[/quote]'); + albumDescJSON = albumDescJSON.replace(/
(.+?)<\/blockquote>/g, '[quote]$1[/quote]'); + albumDescJSON = albumDescJSON.replace(/(.+?)<\/strong>: Show<\/a>