// ==UserScript== // @name Internet Archive (by MixesDB) (BETA) // @author User:Martin@MixesDB (Subfader@GitHub) // @version 2026.03.02.2 // @description Change the look and behaviour of certain DJ culture related websites to help contributing to MixesDB, e.g. add copy-paste ready tracklists in wiki syntax. // @homepageURL https://www.mixesdb.com/w/Help:MixesDB_userscripts // @supportURL https://discord.com/channels/1258107262833262603/1261652394799005858 // @updateURL https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/InternetArchive/script.user.js // @downloadURL https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/InternetArchive/script.user.js // @require https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/includes/jquery-3.7.1.min.js // @require https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/includes/waitForKeyElements.js // @require https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/includes/global.js?v-InternetArchive_3 // @require https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/includes/toolkit.js?v-InternetArchive_3 // @require https://cdn.jsdelivr.net/npm/sorttable@1.0.2/sorttable.js // @include http*archive.org/details/* // @icon https://www.google.com/s2/favicons?sz=64&domain=archive.org // @noframes // @grant unsafeWindow // @run-at document-end // ==/UserScript== /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Load @ressource files with variables * global.js URL needs to be changed manually * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ var cacheVersion = 7, scriptName = "InternetArchive"; loadRawCss( githubPath_raw + "includes/global.css?v-" + scriptName + "_" + cacheVersion ); loadRawCss( githubPath_raw + scriptName + "/script.css?v-" + cacheVersion ); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * playsetLists * https://archive.org/details/Clubnight2011 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ var playsetList_wrapper = $("#theatre-ia-wrap"); if( playsetList_wrapper.length ) { var playsetList_item = $('div[itemprop="hasPart"]', playsetList_wrapper); /* * Prepare mdb table */ var playsetList_mdbTable_html = '
'; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += ''; playsetList_mdbTable_html += '
#NameDetailDurDLMixesDB usage
'; playsetList_mdbTable_html += '
'; playsetList_wrapper.after( playsetList_mdbTable_html ); var playsetList_mdbTable_wrapper = $( "#playsetList_mdbTable_wrapper" ), playsetList_mdbTable = $( "#playsetList_mdbTable" ), playsetList_apiLink = $( '' ); playsetList_mdbTable.before( playsetList_apiLink ); function setApiLink( identifier ) { if ( !identifier ) return false; var currentIdentifier = playsetList_apiLink.data( "identifier" ); if ( currentIdentifier === identifier ) return true; playsetList_apiLink.data( "identifier", identifier ); playsetList_apiLink.html( 'API' ); return true; } function setApiUnavailable() { if ( playsetList_apiLink.find( "a" ).length ) return; playsetList_apiLink.text( "API link unavailable" ); } function getIdentifierFromPath() { try { var pathParts = window.location.pathname.split( "/" ).filter( Boolean ), detailsIndex = pathParts.indexOf( "details" ); if ( detailsIndex !== -1 && pathParts.length > detailsIndex + 1 ) { return decodeURIComponent( pathParts[ detailsIndex + 1 ] ); } if ( pathParts.length ) return decodeURIComponent( pathParts[0] ); } catch ( error ) { console.error( "InternetArchive: Failed to derive identifier from path", error ); } return ""; } setApiLink( getIdentifierFromPath() ); // each playsetList item var i = 0; playsetList_item.each(function(){ i++; /* * Extract values */ var item_name = $('meta[itemprop="name"]', this).attr("content"); // Clubnight 2011.01.01 var item_dur = $('meta[itemprop="duration"]', this).attr("content"); // PT0M7206S var item_url = $('link[itemprop="associatedMedia"]', this).first().attr("href"); // https://archive.org/download/Clubnight2011/Clubnight%202011.01.01%20-%20Motorcitysoul.ogg var item_detailUrl = $('meta[itemprop="url"]', this).attr("content") || $('link[itemprop="url"]', this).attr("href") || ""; /* * Work with the values */ // Name var episode = item_name; // detail var filename = decodeURIComponent( item_url.split("/").pop() // get last part after "/" .replace(/\.[^/.]+$/, "") // remove extension ); var episode_detail = filename.replace( item_name + " - ", "" ); // Motorcitysoul // dur var dur = isoDurationToTime( item_dur ); // 2:00:06 // download links var urls = []; $("link[itemprop='associatedMedia']", this).each(function() { var url = $(this).attr("href"); if (url) urls.push(url); }); // If we have mp3 and ogg → remove ogg(s) var hasMp3 = urls.some(u => u.toLowerCase().endsWith(".mp3")); if (hasMp3) { urls = urls.filter(u => !u.toLowerCase().endsWith(".ogg")); } // Build download links var formats = urls.map(function(url) { var ext = url.split(".").pop().toLowerCase(); return '' + ext + ''; }); var download_links = formats.join(' | '); var first_download_url = urls[0] ? new URL( urls[0], window.location.origin ).href : ""; var details_url = item_detailUrl ? new URL( item_detailUrl, window.location.origin ).href : ""; /* * Add row to table */ var episode_row = ''; episode_row += ''+episode+''; episode_row += ''+episode_detail+''; episode_row += ''+dur+''; episode_row += ''+download_links+''; episode_row += ''+( first_download_url ? "Checking…" : "No download URL" )+''; episode_row += ''; playsetList_mdbTable.append( episode_row ); }); /* * Metadata JS */ waitForKeyElements( "input.js-ia-metadata", function( jNode ) { var arrString = jNode.attr("value"); var apiIdentifier = ""; try { var arr = JSON.parse( arrString ); if ( Array.isArray( arr ) && arr.length ) { var arrItemWithMetadata = arr.find( function( item ) { return item && item.metadata && item.metadata.identifier; } ); apiIdentifier = arrItemWithMetadata?.metadata?.identifier || arr.find( function( item ) { return item && item.identifier; } )?.identifier || ""; } else if ( arr && typeof arr === "object" ) { apiIdentifier = arr.metadata?.identifier || arr.identifier || ""; } } catch ( error ) { console.error( "InternetArchive: Failed to parse metadata", error ); } logVar( "arr", arrString ); if ( apiIdentifier ) { setApiLink( apiIdentifier ); } else { setApiUnavailable(); } }); var playsetList_hasRows = playsetList_mdbTable.find( "tr" ).length > 0, playsetList_hasSlug = playsetList_mdbTable.find( "tr[data-download-url]" ).length > 0; if ( !playsetList_hasRows || !playsetList_hasSlug ) { playsetList_mdbTable.remove(); playsetList_mdbTable_wrapper.append( '
No URLs for MixesDB usage check found
' ); } else { /* * MixesDB usage */ var mixesdbApiUrl = "https://www.mixesdb.com/w/api.php"; function buildMixesdbSearchPath( downloadUrl ) { try { var urlObj = new URL( downloadUrl, window.location.origin ), pathParts = urlObj.pathname.split( "/" ), downloadIndex = pathParts.indexOf( "download" ); if ( downloadIndex !== -1 && pathParts.length > downloadIndex + 2 ) { var identifier = pathParts[ downloadIndex + 1 ], filenamePart = pathParts.slice( downloadIndex + 2 ).join( "/" ); return "/" + identifier + "/" + filenamePart; filenamePart = pathParts.slice( downloadIndex + 2 ).join( "/" ), encodedFilename = encodeURIComponent( filenamePart ); return "/" + identifier + "/" + encodedFilename; } } catch ( error ) { console.error( "InternetArchive: Failed to build MixesDB search path", error ); } return downloadUrl; } playsetList_mdbTable.find( "tr" ).each(function() { var row = $( this ), downloadUrl = row.data( "download-url" ), mixesdbSearchPath = downloadUrl ? buildMixesdbSearchPath( downloadUrl ) : "", mixesdbCell = $( ".playsetList_mdbTable-mixesdb", row ); if ( !mixesdbCell.length ) return; if ( !downloadUrl ) { mixesdbCell.text( "No download URL" ); return; } var mixesdbApiParams = { action: "query", list: "search", srprop: "timestamp", format: "json", origin: "*", srsearch: 'insource:"' + mixesdbSearchPath.replace(/(["\\])/g, "\\$1") + '"' }; $.ajax({ dataType: "json", url: mixesdbApiUrl, data: mixesdbApiParams, success: function( data ) { var searchResults = data?.query?.search; if ( Array.isArray( searchResults ) && searchResults.length ) { var firstResult = searchResults[0], pageTitle = firstResult?.title || "MixesDB", pageId = firstResult?.pageid, pageUrl = pageId ? "https://www.mixesdb.com/w/index.php?curid=" + pageId : "https://www.mixesdb.com/w/" + encodeURIComponent( pageTitle.replace( / /g, "_" ) ); mixesdbCell.html( '' + pageTitle + '' ); } else { var mixesdbApiSearchUrl = mixesdbApiUrl + "?" + $.param( mixesdbApiParams ); mixesdbCell.html( 'Slug not used' ); } }, error: function() { mixesdbCell.text( "MixesDB check failed" ); } }); }); } }