User:Chieftain Alex/Wiki javascripts
From Guild Wars 2 Wiki
Jump to navigationJump to search
- See also: User:Chieftain Alex/API javascripts
<div id="apidata">[[File:Mediawiki loading animation.gif]]</div>
Wiki API - All categories[edit]
/* GW2W API query tool for all categories as the generator with additional properties */ console.log('User pressed run. Starting queries for Special:Categories'); var continue_param = ''; // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { if (continue_param == data['continue'][config.continue]) { // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set. return; } continue_param = data['continue'][config.continue]; console.log(continue_param); // Make next query apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML(config) { var data = config.resultsarray; var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>Categories</th></tr>'; $.each(data, function(index, val) { result += '<tr>'; // Add english page title result += '<td>'+val['title']+'</td>'; // Add categories if (typeof val['categories'] !== 'undefined'){ result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ') + '</td>'; } else { result += '<td>...</td>'; } result += '</tr>\n'; }); result += '</table>'; $('#mw-content-text').html('<pre'+'>' + result + '</'+'pre>'); } // ------------ Notes ----------------------- // We're using a generator here, so all the parameters usually used from action=query have a "g" on the front of it. // Generators allow you to extract additional properties not normally available from "list=allpages". // The output format is dumb from generators, you need to set "formatversion=2" to make it use an array like every other endpoint. // Generators are dumb; the limits need to be set for each of the individual props too. These limits should be higher than that // set for the actual generator. 4x higher seems to be the sweetspot. (e.g. gaplimit=1000, cllimit=4000) // Admins and bots have limits of 5000 as well as no throttling. Regular users have limits of 500. // Make the request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allcategories&gaclimit=1000' + '&prop=categories&cllimit=5000', output: 'pages', continue: 'gaccontinue', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - All pages[edit]
/* GW2W API query tool for all pages */ // Setup var redirectfilter = 'nonredirects'; // all, redirects var languagelinkfilter = 'all'; // withlanglinks, withoutlanglinks var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=allpages&aplimit=500&apfilterredir='+redirectfilter+'&apfilterlanglinks='+languagelinkfilter; var datadrop = []; // Function to concatenate all data function processdata (datadrop) { var contribs = []; $.each(datadrop, function(k,v){ $.each(v, function(kk,vv){ contribs.push(vv); }); }); $('#mw-content-text').html(makeTableHTML(contribs)); } // Function to convert an object variable into a table function makeTableHTML( data ) { var result = '<table class="table mech1"><tbody>' +'<tr><th>Pageid</th><th>Name</th></tr>'; $.each(data, function(k, v) { result += '<tr id="'+v['revid']+'">' +'<td>'+v['pageid']+'</td><td>'+v['title']+'</td>' +'</tr>'; }); result += "</tbody></table>"; return result; } // Fetch all the pages function apiQuery (token,startkey) { var url = baseurl; if (startkey) { url += '&apfrom=' + startkey; } if (token) { url += '&apcontinue=' + token; } // console.log(url); $.getJSON(url).done(function(data){ datadrop.push(data['query']['allpages']); if (data['continue']) { apiQuery(data['continue']['apcontinue']); } else { console.log('Query complete.'); processdata(datadrop); } }); } console.log('User pressed run. Starting queries for Special:AllPages'); //apiQuery(null,'Z'); apiQuery();
Wiki API - All pages (v2)[edit]
/* GW2W API query tool for all pages */ console.log('User pressed run. Starting queries for Special:AllPages'); // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML (config) { var data = config.resultsarray; // Generate table html var result = '<table class="table mech1"><tbody>'; if (data.length > 0) { var columns = Object.keys(data[0]); result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>'; result += $.map(data, function(v) { return '<tr>' + $.map(columns, function(c) { return '<td>' + v[c] + '</td>'; }).join('') + '</tr>'; }).join('\n'); } result += '</tbody></table>'; $('#mw-content-text').html(result); } // Make request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&action=query&list=allpages&aplimit=500&apfilterredir=nonredirects&apfilterlanglinks=all', output: 'allpages', continue: 'apcontinue', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - Category pages[edit]
/* GW2W API query tool for all pages in a category */ console.log('User pressed run. Starting queries for Special:Category'); var category_page = 'Category:' + 'Bestiary screenshots'; // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML (config) { var data = config.resultsarray; // Generate table html var result = '<table class="wikitable"><tbody>'; if (data.length > 0) { var columns = Object.keys(data[0]); result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>'; result += $.map(data, function(v) { return '<tr>' + $.map(columns, function(c) { return '<td>' + v[c] + '</td>'; }).join('') + '</tr>'; }).join('\n'); } result += '</tbody></table>'; $('#mw-content-text').html(result); } // Make request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&action=query&list=categorymembers&cmlimit=500&cmtitle=' + category_page, output: 'categorymembers', continue: 'cmcontinue', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - Generator example (all pages, categories and interwikis)[edit]
/* GW2W API query tool for all pages as the generator with additional properties */ console.log('User pressed run. Starting queries for Special:AllPages'); var continue_param = ''; // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { if (continue_param == data['continue'][config.continue]) { // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set. return; } continue_param = data['continue'][config.continue]; console.log(continue_param); // Make next query apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML(config) { var data = config.resultsarray; var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>DE page</th><th>ES page</th><th>FR page</th><th>Categories</th></tr>'; $.each(data, function(index, val) { result += '<tr>'; // Add english page title result += '<td>'+val['title']+'</td>'; if (typeof val['langlinks'] !== 'undefined'){ // Placeholder with all interwiki language keys var resultobj = { de: '', es: '', fr: '' }; // Go through each interwiki on the page and add them into the object $.map(val['langlinks'], function(v){ resultobj[v['lang']] = v['title']; }); // Add to the results result += $.map(resultobj, function(v){ return '<td>' + v + '</td>'; }).join(''); } else { result += '<td>...</td><td>...</td><td>...</td>'; } if (typeof val['categories'] !== 'undefined'){ result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ') + '</td>'; } else { result += '<td>...</td>'; } result += '</tr>\n'; }); result += '</table>'; $('#mw-content-text').html(result); } // ------------ Notes ----------------------- // We're using a generator here, so all the parameters usually used from action=query have a "g" on the front of it. // Generators allow you to extract additional properties not normally available from "list=allpages". // The output format is dumb from generators, you need to set "formatversion=2" to make it use an array like every other endpoint. // Generators are dumb; the limits need to be set for each of the individual props too. These limits should be higher than that // set for the actual generator. 4x higher seems to be the sweetspot. (e.g. gaplimit=1000, lllimit=4000, cllimit=4000) // Admins and bots have limits of 5000 as well as no throttling. Regular users have limits of 500. // Make the request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allpages&gapfilterredir=nonredirects&gapfilterlanglinks=all&gaplimit=1000' + '&prop=categories|langlinks&lllimit=5000&cllimit=5000', output: 'pages', continue: 'gapcontinue', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - Generator for images[edit]
/* GW2W API query tool for all pages as the generator with additional properties */ console.log('User pressed run. Starting queries for Special:AllPages'); var continue_param = ''; // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } else { // for testing with a large offset // url += '&' + config.continue + '=' + 'Zaan_Ruinbringer.jpg'; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { if (continue_param == data['continue'][config.continue]) { // Quit if its making two queries in a row with the same continue offset... probably indicates wrong limits set. return; } continue_param = data['continue'][config.continue]; console.log(continue_param); // Make next query apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML(config) { var data = config.resultsarray; var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Title</th><th>Height (px)</th><th>Width (px)</th><th>Size (Kb)</th><th>Uploader</th><th>Timestamp</th><th>Categories</th></tr>'; $.each(data, function(index, val) { result += '<tr>'; // Add english page title result += '<td>'+val['title']+'</td>'; // Add image metadata if (typeof val['imageinfo'] !== 'undefined' && val.imageinfo.length > 0){ var h = val.imageinfo[0].height || 0, w = val.imageinfo[0].width || 0, s = val.imageinfo[0].size || 0, u = val.imageinfo[0].user || '', t = val.imageinfo[0].timestamp || ''; result += '<td>'+h+'</td><td>'+w+'</td><td>'+(s/1024).toFixed(1)+'</td><td>'+u+'</td><td>'+t.replace('Z','').replace('T',' ') +'</td>'; } else { result += '<td>...</td><td>...</td><td>...</td><td>...</td><td>...</td>'; } // Add categories if (typeof val['categories'] !== 'undefined'){ result += '<td>' + $.map(val['categories'], function(v) { return v.title }).join(', ') + '</td>'; } else { result += '<td>...</td>'; } result += '</tr>\n'; }); result += '</table>'; $('#mw-content-text').html(result); } // Make the request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=allpages&gapfilterredir=nonredirects&gapfilterlanglinks=all&gapnamespace=6&gaplimit=1000' + '&prop=categories|imageinfo&iiprop=size|user|timestamp&iilimit=5000&cllimit=5000', output: 'pages', continue: 'gapcontinue', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - Generator for images with fileusage[edit]
/* GW2W API query tool for FILES in a given CATEGORY (as the generator) returning additional image properties via prop=fileusage */ console.log('User pressed run. Starting queries for Special:CategoryMembers'); var cat = 'Category:Screenshots'; // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if ('continue' in data) { var continue_suffix = $.map(data['continue'], function(v,k){ return k + '=' + v; }).join('&'); console.log(continue_suffix); // debugging // Make next query apiQuery(config, continue_suffix); } else if ('batchcomplete' in data && data.batchcomplete == true){ // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } else { console.log('Error - landed on an API query without a batchcomplete or continue.'); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML(config) { var data = config.resultsarray; var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>file page id</th><th>file page title</th><th>index</th><th>Page title</th></tr>'; $.each(data, function(index, val) { if (typeof val['fileusage'] !== 'undefined'){ $.each(val['fileusage'], function(i,v){ result += '<tr>'; result += '<td>'+val['pageid']+'</td>' + '<td>'+val['title']+'</td>'; result += '<td>' + i + '</td>' + '<td>' + v.title + '</td>' result += '</tr>\n'; }); } else { result += '<tr>'; result += '<td>'+val['pageid']+'</td><td>'+val['title']+'</td><td>...</td><td>...</td>'; result += '</tr>\n'; } }); result += '</table>'; $('#mw-content-text').html(result); } // Make the request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&formatversion=2' + '&action=query' + '&generator=categorymembers&gcmtitle=' + cat + '&gcmlimit=1000' + '&prop=fileusage&funamespace=0&fulimit=5000', // always leave the generator limit (5000) much higher than the page limit (1000) output: 'pages', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - Image metadata[edit]
/* GW2W API query tool for image metadata. You're supposed to be able to query not using names, but I dunno how to convert filenames to page numbers. */ // Function to convert an object variable into a table function makeTableHTML(data) { var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Image title</th><th>Size</th><th>Width</th><th>Height</th><th>User</th></tr>'; $.each(data, function(index, val) { if (typeof val['imageinfo'] !== 'undefined'){ result += '<tr><td>'+val['title']+'</td>' +'<td>'+val['imageinfo'][0]['size']+'</td>' +'<td>'+val['imageinfo'][0]['width']+'</td>' +'<td>'+val['imageinfo'][0]['height']+'</td>' +'<td>'+val['imageinfo'][0]['user']+'</td>' +'</tr>'; } }); result += '</table>'; return result; } // Fetch all the possible itemsIDs (function fetchAPIData() { var ids = ["File:Master Blaster.jpg","File:Master Blaster.png","File:Moonshank.jpg"]; console.log('Number of items: ' + ids.length); // Query API until all the ids have been requested var promises = [], baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&prop=imageinfo&iiprop=size|user&titles='; var lines = [[]], maxlength = 1800, j = 0, running_total = 0; for (var i=0; i<ids.length; i++) { if ((running_total + ids[i].length) >= maxlength) { j += 1; lines.push([]); running_total = 0; } running_total += 1 + ids[i].length; lines[j].push(ids[i]); } for (var k=0; k<lines.length; k++) { var promise = $.getJSON(baseurl + lines[k].join('|') ); promises.push(promise); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { var newarguments = {}; if ( promises.length > 1 ) { newarguments = arguments; } else { newarguments[0] = arguments; } console.log(newarguments); var alldata = []; $.each(newarguments, function(i,v){ $.each(v[0]['query']['pages'], function(ii,vv){ alldata.push(vv); }); }); // Write to document $('#apidata').html(makeTableHTML(alldata)); }); })();
Wiki API - Interwikis[edit]
/* GW2W API query tool for language links. */ // Function to convert an object variable into a table function makeTableHTML(data) { var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>EN page</th><th>DE page</th><th>ES page</th><th>FR page</th></tr>'; $.each(data, function(index, val) { if (typeof val['langlinks'] !== 'undefined'){ // Add english page title result += '<tr>' + '<td>'+val['title']+'</td>'; // Placeholder with all interwiki language keys var resultobj = { de: '', es: '', fr: '' }; // Go through each interwiki on the page and add them into the object $.map(val['langlinks'], function(v){ resultobj[v['lang']] = v['*']; }); // Add to the results result += $.map(resultobj, function(v){ return '<td>' + v + '</td>'; }).join('\n'); result += '</tr>'; } else { result += '<tr>' + '<td>'+val['title']+'</td><td>...</td><td>...</td><td>...</td></tr>'; } }); result += '</table>'; return result; } // Fetch all the possible itemsIDs (function fetchAPIData() { var ids = ["Main Page","Charr","Asura"]; console.log('Number of pages: ' + ids.length); // Query API until all the page ids have been requested var promises = [], baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&prop=langlinks&lllimit=500&titles='; var lines = [[]], maxlength = 1500, j = 0, running_count = 0, running_total = 0; for (var i=0; i<ids.length; i++) { if ((running_total + ids[i].length) >= maxlength || running_count > 500) { j += 1; lines.push([]); running_count = 0; running_total = 0; } running_count += 1; running_total += 1 + ids[i].length; lines[j].push(ids[i]); } for (var k=0; k<lines.length; k++) { var promise = $.getJSON(baseurl + lines[k].join('|') ); promises.push(promise); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { var newarguments = {}; if ( promises.length > 1 ) { newarguments = arguments; } else { newarguments[0] = arguments; } console.log(newarguments); var alldata = []; $.each(newarguments, function(i,v){ $.each(v[0]['query']['pages'], function(ii,vv){ alldata.push(vv); }); }); // Write to document $('#apidata').html(makeTableHTML(alldata)); }); })();
Wiki API - Log entries[edit]
/* GW2W API query tool for log entries */ // Useful reference link: "https://www.mediawiki.org/wiki/API:Lists/All#Logevents" // Setup var loguser = 'Chieftain Alex'; var logtype = 'delete/delete'; var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=logevents&lelimit=500&leaction=' + logtype + '&leuser=' + loguser; var datadrop = []; // Function to concatenate all data function processdata (datadrop) { var contribs = []; $.each(datadrop, function(k,v){ $.each(v, function(kk,vv){ contribs.push(vv); }); }); $('#mw-content-text').html(makeTableHTML(contribs)); } // Function to convert an object variable into a table function makeTableHTML( data ) { var result = '<table class="table mech1"><tbody>' +'<tr><th>Namespace</th><th>Timestamp</th><th>Title</th></tr>'; $.each(data, function(k, v) { result += '<tr id="'+v['revid']+'">' +'<td>'+v['ns']+'</td><td>'+v['timestamp']+'</td><td>'+v['title']+'</td>' +'</tr>'; }); result += "</tbody></table>"; return result; } // Fetch all the log entries function apiQuery (token) { var url = baseurl; if (token) { url += '&lecontinue=' + token } // console.log(url); $.getJSON(url).done(function(data){ datadrop.push(data['query']['logevents']); if (data['continue']) { apiQuery(data['continue']['lecontinue']); } else { console.log('Query complete.'); processdata(datadrop); } }); } console.log('User pressed run. Starting deletion log queries for User:' + user + '...'); apiQuery();
Wiki API - Namespaces[edit]
/* GW2W API query tool for Mediawiki namespaces statistics */ // Function to convert an object variable into a table function makeTableHTML( data ) { var result = '<table class="table mech1"><tbody>'+'<tr><th>Namespace ID</th><th>Name</th></tr>'; $.each(data, function(k, v) { result += '<tr>'+'<td>'+v['id']+'</td><td>'+v['canonical']+'</td>'+'</tr>'; }); result += "</tbody></table>"; return result; } // Fetch all the namespaces function apiQuery () { // console.log(url); $.getJSON('https://wiki.guildwars2.com/api.php?action=query&format=json&meta=siteinfo&siprop=namespaces').done(function(data){ $('#mw-content-text').html(makeTableHTML(data['query']['namespaces'])); }); } apiQuery();
Wiki API - Redirect resolving[edit]
/* GW2W API query tool for finding where redirects go. */ // https://www.mediawiki.org/wiki/API:Query#Resolving_redirects // Function to convert an object variable into a table function makeTableHTML(data) { console.log(data); var result = '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Redirect from</th><th>Redirect to</th><th>Fragment</th></tr>'; $.each(data, function(index, val) { result += '<tr><td>'+val['from']+'</td><td>'+val['to']+'</td><td>'+ ('tofragment' in val ? val['tofragment'] : '') +'</td></tr>'; }); result += '</table>'; return result; } // Fetch all the possible redirects for the given pages (function fetchAPIData() { var ids = [ "Ascended Flanged Mace", "Bluebriar Emergency Waypoint" ]; console.log('Number of items: ' + ids.length); // Query API until all the ids have been requested var promises = [], baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&formatversion=2&prop=redirects&rdprop=pageid|title|fragment&rdnamespace=0|6|10&rdlimit=500&redirects&titles='; var lines = [[]], maxlength = 1200, j = 0, running_total = 0; for (var i=0; i<ids.length; i++) { if ((running_total + ids[i].length) >= maxlength) { j += 1; lines.push([]); running_total = 0; } running_total += 1 + ids[i].length; lines[j].push(ids[i]); } for (var k=0; k<lines.length; k++) { var promise = $.getJSON(baseurl + lines[k].join('|') ); promises.push(promise); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { var newarguments = {}; if ( promises.length > 1 ) { newarguments = arguments; } else { newarguments[0] = arguments; } //console.log(newarguments); var alldata = []; $.each(newarguments, function(i,v){ $.each(v[0]['query']['redirects'], function(ii,vv){ alldata.push(vv); }); }); // Write to document $('#apidata').html(makeTableHTML(alldata)); }); })();
Wiki API - SMW single result (via template)[edit]
/* GW2W API query tool for SMW results */ function apiQuery () { mw.loader.using('mediawiki.api.parse', function () { var query = '[[Has equipment supertype::Weapon]] [[Has appearance::+]]'; var parameters = 'Has weapon type'; var firstquery = '{{User:Chieftain Alex/Templates/SMW query|mode=1|query='+query+'}}'; var api = new mw.Api(); api.parse(firstquery).done(function (resulttext) { // Find the output token var pattern = /\<div class\="apiresults"\>(\d+)\<\/div\>/; var m = resulttext.match(pattern); console.log('regexp', m); // Check something matched if (!m) { console.log('No regular expression matched, quitting.') return; } // Convert match from text into a number. var n = Number(m[1]); if (n == 0) { console.log('Zero results found, quitting.'); } else { console.log(n, ' results found, querying...'); // Check if n > 5000 -- SMW bug won't let us get more results than this if (n > 5000) { console.log('Truncating results to 5000 (SMW bug)'); n = 5000; } // Repeat query n/500 times until done var promises = []; for (var i=0; i<n; i+=500) { var furtherquery = '{{User:Chieftain Alex/Templates/SMW query|mode=2|query='+query+'|parameters='+parameters+'|offset='+i+'}}'; promises.push(api.parse(furtherquery)); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { // Concatenate the api results var table = $.map(arguments, function(v) { return v; }).join('\n'); // Write to document $('#apidata').html(table); // Now copy the output to excel, then remove duplicates including table headings. console.log('Batch query complete.'); }); } }); }); } apiQuery();
Wiki API - SMW result misc inputs (via template)[edit]
/* GW2W API query tool for SMW results for miscellaneous page inputs */ function apiQuery () { mw.loader.using('mediawiki.api.parse', function () { var parameters = 'Has game id#;Has context'; var pages = ["Precise Strike","Tail Wind","Loud Whistle"]; var api = new mw.Api(); // Break the list of pages down into a url almost 2000 characters long. var lines = [[]], maxlength = 1800, j = 0, running_count = 0, running_total = 0; for (var i=0; i<pages.length; i++) { if ((running_total + pages[i].length) >= maxlength || running_count > 200) { j += 1; lines.push([]); running_count = 0; running_total = 0; } running_count += 1; running_total += 3 + pages[i].length; lines[j].push(pages[i]); } // Submit each request, result is returned as a table. var promises = []; for (var k=0; k<lines.length; k++) { var current_pages = lines[k].join(';'); var parsetext = '{{User:Chieftain Alex/Templates/SMW query misc|pages='+current_pages+'|parameters='+parameters+'}}'; promises.push(api.parse(parsetext)); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { // Concatenate the api results var table = $.map(arguments, function(v) { return v; }).join('\n'); // Write to document $('#apidata').html(table); // Now copy the output to excel, then remove duplicates including table headings. console.log('Batch query complete.'); }); }); } apiQuery();
Wiki API - SMW recipes[edit]
/* GW2W API SMW query tool for recipes */ // Setup\ var baseurl = 'https://wiki.guildwars2.com/api.php?action=ask&format=json&query=' var query = encodeURIComponent('[[Requires discipline::Chef]][[Has item data object::+]]|?Has recipe id|?Has output quantity|?Has item data object|?Has output game id|?Has ingredient with id|limit=500|link=none'); var datadrop = []; // Function to concatenate all data function processdata (datadrop) { var a = $.map(datadrop, function(v){ return v; }); $('#apidata').html('<pre'+'></pre'+'>'); $('#apidata pre').text(JSON.stringify(a, null, 2) .replace(new RegExp("\n( ){4}", "g")," ") .replace(new RegExp("\n( ){3}\}", "g")," }") ); console.log('Query and formatting complete.'); } // Fetch all the recipes function apiQuery (token) { var url = baseurl+query; if (token) { url += encodeURIComponent('|offset=') + token } // console.log(url); $.getJSON(url).done(function(rawdata){ // Streamline results prior to storage var data = $.map(rawdata['query']['results'], function(v){ var w = v.printouts; return { 'wiki_page': v.fulltext, // only available if '|mainlabel=-' is not added. 'recipe_id': w['Has recipe id'][0], 'output_item_id': (w['Has output game id'].length > 0 ? w['Has output game id'][0] : null), 'output_item_count': w['Has output quantity'][0], 'output_item_wikiname': w['Has item data object'][0]['fulltext'], 'ingredients': $.map(w['Has ingredient with id'], function(x){ return { 'item_id': (x['Has ingredient id']['item'].length > 0 ? x['Has ingredient id']['item'][0] : null), 'count': (x['Has ingredient quantity']['item'].length > 0 ? x['Has ingredient quantity']['item'][0] : null ), 'wikiname': (x['Has ingredient name']['item'].length > 0 ? x['Has ingredient name']['item'][0]['fulltext'] : null ) } }) } }); datadrop.push(data); if (rawdata['query-continue-offset']) { apiQuery(rawdata['query-continue-offset']); } else { processdata(datadrop); } }); } console.log('User pressed run. Starting SMW queries...'); apiQuery();
Wiki API - Template parameter check[edit]
/* GW2W API query tool for Template parameters */ function apiQuery () { mw.loader.using('mediawiki.api.parse', function () { var template = 'ArenaNet image'; var category = 'Guild emblems'; var parameters = '1:2:id'; var firstquery = '{{User:Chieftain Alex/Templates/Parameter check|mode=1|template='+template+( category != '' ? ('|category=' + category) : '' )+'}}'; var api = new mw.Api(); api.parse(firstquery).done(function (resulttext) { // Find the output token var pattern = /\<div class\="apiresults"\>(\d+)\<\/div\>/; var m = resulttext.match(pattern); console.log('regexp', m); // Check something matched if (!m) { console.log('No regular expression matched, quitting.') return; } // Convert match from text into a number. var n = Number(m[1]); if (n == 0) { console.log('Zero results found, quitting.'); } else { console.log(n, ' results found, querying...'); // Repeat query n/500 times until done var promises = []; for (var i=0; i<n; i+=500) { var furtherquery = '{{User:Chieftain Alex/Templates/Parameter check|mode=2|template='+template+( category != '' ? ('|category=' + category) : '' )+'|parameters='+parameters+'|offset='+i+'}}'; promises.push(api.parse(furtherquery)); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { // Concatenate the api results var table = $.map(arguments, function(v) { return v; }).join('\n'); // Write to document $('#apidata').html(table); // Replace first column PAGENAME with FULLPAGENAME (i.e. add namespace) $.map($('#apidata td:first-child a') ,function(v,i){ $(v).text( v.title ); }); // Now copy the output to excel, then remove duplicates including table headings. console.log('Batch query complete.'); }); } }); }); } apiQuery();
Wiki API - Unused images[edit]
/* GW2W API query tool for Special pages such as Unused images - see https://www.mediawiki.org/wiki/API:Querypage */ console.log('User pressed run. Starting queries for Special page.'); var special_page = 'Unusedimages'; // Ancientpages, BrokenRedirects, Deadendpages, DisambiguationPageLinks, DisambiguationPages, DoubleRedirects, Fewestrevisions, GadgetUsage, GloballyWantedFiles, ListDuplicatedFiles, Listredirects, Lonelypages, Longpages, MediaStatistics, MostGloballyLinkedFiles, Mostcategories, Mostimages, Mostinterwikis, Mostlinked, Mostlinkedcategories, Mostlinkedtemplates, Mostrevisions, Shortpages, Uncategorizedcategories, Uncategorizedimages, Uncategorizedpages, Uncategorizedtemplates, UnconnectedPages, Unusedcategories, Unusedimages, Unusedtemplates, Unwatchedpages, Wantedcategories, Wantedfiles, Wantedpages, Wantedtemplates, Withoutinterwiki // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query']['querypage']['results']); // Get further results if available if ('continue' in data) { var continue_suffix = $.map(data['continue'], function(v,k){ return k + '=' + v; }).join('&'); // console.log(continue_suffix); // debugging // Make next query apiQuery(config, continue_suffix); } else if ('batchcomplete' in data && data.batchcomplete == true){ // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log('Query complete.'); // Call the next function callbackfunction(config); } else { console.log('Error - landed on an API query without a batchcomplete or continue. Trying to finish anyway.'); config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); console.log(config.resultsarray); callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML (config) { var data = config.resultsarray; // Generate table html var result = '<table class="wikitable"><tbody>'; if (data.length > 0) { var columns = Object.keys(data[0]); result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>'; result += $.map(data, function(v) { return '<tr>' + $.map(columns, function(c) { return '<td>' + v[c] + '</td>'; }).join('') + '</tr>'; }).join('\n'); } result += '</tbody></table>'; $('#mw-content-text').html(result); } // Make request apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&action=query&list=querypage&qplimit=500&qppage=' + special_page, tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - User contributions[edit]
/* GW2W API query tool for contribution statistics */ // Useful reference link: https://wiki.guildwars2.com/api.php?action=query&meta=siteinfo&siprop=namespaces // Setup var user = 'Darqbot'; var baseurl = 'https://wiki.guildwars2.com/api.php?action=query&format=json&list=usercontribs&uclimit=500&ucdir=newer&ucuser=' + user; var datadrop = []; // Function to concatenate all data function processdata (datadrop) { var contribs = []; $.each(datadrop, function(k,v){ $.each(v, function(kk,vv){ contribs.push(vv); }); }); $('#mw-content-text').html(makeTableHTML(contribs)); } // Function to convert an object variable into a table function makeTableHTML( data ) { var result = '<table class="table mech1"><tbody>' +'<tr><th>Namespace</th><th>Timestamp</th><th>Size</th><th>Title</th></tr>'; $.each(data, function(k, v) { result += '<tr id="'+v['revid']+'">' +'<td>'+v['ns']+'</td><td>'+v['timestamp']+'</td><td>'+v['size']+'</td><td>'+v['title']+'</td>' +'</tr>'; }); result += "</tbody></table>"; return result; } // Fetch all the contributions function apiQuery (token) { var url = baseurl; if (token) { url += '&uccontinue=' + token } // console.log(url); $.getJSON(url).done(function(data){ datadrop.push(data['query']['usercontribs']); if (data['continue']) { apiQuery(data['continue']['uccontinue']); } else { console.log('Query complete.'); processdata(datadrop); } }); } console.log('User pressed run. Starting queries for User:' + user + '...'); apiQuery();
Wiki API - User groups[edit]
https://wiki.guildwars2.com/api.php?action=query&list=users&usprop=editcount|groups|rights&ususers=Chieftain_Alex
Wiki API - Users who are autoconfirmed[edit]
/* GW2W API query tool for all autoconfirmed users */ console.log('User pressed run. Starting queries for Special:AllUsers'); // Wrapper function to return the results once complete function apiWrapper (config, callbackfunction) { // Fetch all the pages function apiQuery (config, token) { var url = config.baseurl; if (token) { url += '&' + config.continue + '=' + token; } $.getJSON(url).done(function(data){ // Add results to stack config.tempresultsarray.push(data['query'][config.output]); // Get further results if available if (data['continue']) { apiQuery(config, data['continue'][config.continue]); } else { // Flatten data from nested arrays to one array of result objects config.resultsarray = $.map(config.tempresultsarray, function(v) { return v; }); // Modification 1 - filter for only autoconfirmed users function onlyIfAutoconfirmed(e){ return e.implicitgroups.indexOf('autoconfirmed') > -1; } config.resultsarray = config.resultsarray.filter(onlyIfAutoconfirmed); // Modification 2 - filter for only names shorter than 50 characters function onlyAcceptableNames(e){ return e.name.length < 50; } config.resultsarray = config.resultsarray.filter(onlyAcceptableNames); console.log('Query complete.'); // Call the next function callbackfunction(config); } }); } apiQuery(config); } // Function to convert an object variable into a table function makeTableHTML (config) { var data = config.resultsarray; // Generate table html var result = '<table class="wikitable"><tbody>'; if (data.length > 0) { var columns = Object.keys(data[0]); result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>'; result += $.map(data, function(v) { return '<tr>' + $.map(columns, function(c) { return '<td>' + v[c] + '</td>'; }).join('') + '</tr>'; }).join('\n'); } result += '</tbody></table>'; $('#mw-content-text').html(result); } // Make request // https://www.mediawiki.org/w/api.php?action=help&modules=query%2Ballusers // Initial filters: Only users with Edits // Post filters: Autoconfirmed Users, Users with usernames shorter than 50 characters (probably gww vandals) apiWrapper({ baseurl: 'https://wiki.guildwars2.com/api.php?format=json&action=query&list=allusers&aulimit=500' + '&auwitheditsonly=true' + '&auprop=implicitgroups|editcount|registration', output: 'allusers', continue: 'aufrom', tempresultsarray: [], resultsarray: [] }, makeTableHTML);
Wiki API - WhatLinksHere misc inputs using DPL (via template)[edit]
/* GW2W API query tool for SMW results for miscellaneous page inputs */ function apiQuery () { mw.loader.using('mediawiki.api.parse', function () { var pages = ["Precise Strike","Tail Wind","Loud Whistle"]; var api = new mw.Api(); // Break the list of pages down into a url almost 2000 characters long. var lines = [[]], maxlength = 1800, j = 0, running_count = 0, running_total = 0; for (var i=0; i<pages.length; i++) { if ((running_total + pages[i].length) >= maxlength || running_count > 100) { j += 1; lines.push([]); running_count = 0; running_total = 0; } running_count += 1; running_total += 3 + pages[i].length; lines[j].push(pages[i]); } // Submit each request, result is returned as a table. var promises = []; for (var k=0; k<lines.length; k++) { var current_pages = lines[k].join('\n'); var parsetext = '{{User:Chieftain Alex/Templates/WhatLinksHere query|1='+current_pages+'}}'; promises.push(api.parse(parsetext)); } // Wait until all the GET requests have finished $.when.apply($,promises).done(function() { // Concatenate the api results var table = $.map(arguments, function(v) { return v; }).join('\n'); // Write to document $('#apidata').html(table); // Now copy the output to excel, then remove duplicates including table headings. console.log('Batch query complete.'); }); }); } apiQuery();
Wiki API - WhatLinksfrom via DPL[edit]
/* GW2W API query tool for DPL linksfrom results for miscellaneous page inputs */ function nextQuery(stringstackarray) { // Get the next chunk var current_pages = stringstackarray.shift(); // Wrap in the wikitext, and join the chunk's array elements with a semi-colon. var direction = 'linksfrom'; // 'linksto' = same as Special:WhatLinksHere. 'linksfrom' = a DPL special. var uses = ''; // including "Template:" prefix var parsetext = '{{User:Chieftain Alex/Templates/DPL query links|direction='+direction+'|pages='+current_pages.join(';')+'|uses='+uses+'}}'; // Make the request var api = new mw.Api(); api.parse(parsetext) .done(function (result) { // Write to document $('#apidata').append(result); }) .fail( function(code, result) { console.log('Batch query failed.'); console.log(parsetext); if ( code === "http" ) { console.log( "HTTP error: " + result.textStatus ); } else if ( code === "ok-but-empty" ) { console.log( "Got an empty response from the server" ); } else { console.log( "API error: " + code ); } }) .always( function (){ // Check if any chunks left if (stringstackarray.length > 0) { nextQuery(stringstackarray); } else { // Done $('#apidata').append('<p>Batch query complete</p>'); console.log('Batch query complete.'); } }); } function apiQuery () { mw.loader.using('mediawiki.api.parse', function () { var pages = ["Aspect Arena","Basket Brawl","Bell Choir Ensemble"]; // Break the list of pages down into a url almost 2000 characters long. // but actually limit it to bunches of 25 pages (depending on the popularity/density, each page could have upwards of 250+ links from each page) var lines = [[]], maxlength = 1800, j = 0, running_count = 0, running_total = 0; for (var i=0; i<pages.length; i++) { if ((running_total + pages[i].length) >= maxlength || running_count >= 25) { j += 1; lines.push([]); running_count = 0; running_total = 0; } running_count += 1; running_total += 3 + pages[i].length; lines[j].push(pages[i]); } // For each line, parse the text and append the results into the page. $('#apidata').html(''); nextQuery(lines); }); } apiQuery();
Wiki - Whatlinkshere arraymap[edit]
{| class="wikitable" {{#arraymap: Acolyte Boots (PvP) Acolyte Coat (PvP) |\n|@@@| {{#vardefine:title|@@@}}{{#arraymap:{{#dpl: | linksto = @@@ | mode = userformat | format = ,,%PAGE%;, }}|;|$$$| {{!}}- {{!}} {{#var:title}} {{!!}} $$$|\n}} |\n}} |}
Wiki - Tools[edit]
Wiki - enumerate achievement page[edit]
var a = $.map( $('.widget-account-achievement.line'), function(v){ return $(v).find('th:first-child').text().trim(); }); console.log(JSON.stringify(a,null,2));
Wiki - ChatLinkSearch tabler (for Special:Search)[edit]
/* GW2W tool to turn the verbose output of the chatlinksearch script into something you can copy into excel */ var listitems = $('.gw2w-chat-link-search ul li'); var tabletext = '<table><tr><th>id</th></tr>'; $.each(listitems, function(k,v){ tabletext += '<tr>' + '<td>' + v.attributes['data-gameid']['nodeValue'] + '</td>' + '</tr>'; }); tabletext += '</table>'; $('.gw2w-chat-link-search').html(tabletext);
Wiki - Diff changes only[edit]
var rows = []; rows.push( $('tr.diff-title').outerHTML ); $.map( $('td.diff-marker:first-child') , function(v,i){ if (i < 5) { console.log(v); console.log(v.hasAttribute('data-marker')); } if ( v.hasAttribute('data-marker') ) { rows.push( v.parentElement.outerHTML ); } }); $('table.diff tbody').html( rows.join('') );
Wiki - Drop rate research[edit]
// Input var item_ids = [698,758,761,1032,1297,1309,1594,1594,1605,1625,1834,1842,1849,1849,2088,2088,2096,2110,2115,2355,2360,2360,2363,23175,23194,24995,25435,25715,25930,25941,25944,25947,25949,25949,26125,26127,26128,26496,26521,26521,26818,26826,26826,26874,27131,27153,27160,27160,27588,27610,27610,27610,27610,27610,27622,27919,27937,28224,28243,28245,28245,28249,28251,28405,28414,28546,28780,28793,28796,28797,32958,32966,32998,34137,34809,34825,34825,34845,34853,34861,34881,45084,45090,45092,45092,47218,47442,47442,47442,47474,47482,47490,47502,47753,47753,47753,47769,47813,47825,47825]; var opener = '{{en}} Adeira Beta'; var signature = '[[User:Adeira Tasharo]]'; // -------------------------------------------------------- var inputs = { item_ids: item_ids, opener: opener, signature: signature } // Helper function to remove duplicates. Usage: a.unique() Array.prototype.unique = function() { return this.filter(function (el, i, self) { return self.indexOf(el) === i; }); }; // Helper function to find elements in A which are not in B. Usage: a.diff(b) Array.prototype.diff = function(a) { return this.filter(function(el) { return a.indexOf(el) < 0; }); }; function makeTableHTML (inputs, reference_data, ref) { console.log(inputs, reference_data); var column_titles = ['Rarity','Supertype','Type','Level','ID','Name','Suffix','Prefix','Opened on','Signature']; // Construct array with values to print to page var rows = []; $.map(inputs.item_ids, function(item_id){ var row = []; if (item_id in reference_data.items) { // Rarity row.push(reference_data.items[item_id].rarity); // Supertype row.push(reference_data.items[item_id].type); // Type var t = reference_data.items[item_id].details.type || ''; row.push(t); // Level row.push(reference_data.items[item_id].level); // ID row.push(item_id); // Name row.push(reference_data.items[item_id].name); // Suffix var s_id = reference_data.items[item_id].details.suffix_item_id || 0; if (s_id == 0) { row.push('None'); } else if (s_id in reference_data.items) { row.push(reference_data.items[s_id].name); } else { row.push('not in the api'); } // Prefix var p_id = reference_data.items[item_id].details.infix_upgrade.id || 0; if (p_id == 0) { row.push('None'); } else if (p_id in reference_data.itemstats) { row.push(reference_data.itemstats[p_id].name); } else { row.push('not in the api'); } } else { // Rarity row.push('not in the api'); // Supertype row.push('not in the api'); // Type row.push('not in the api'); // Level row.push('not in the api'); // ID row.push(item_id); // Name row.push('not in the api'); // Suffix row.push('not in the api'); // Prefix row.push('not in the api'); } // Opened on character row.push(inputs.opener); // Signature row.push(inputs.signature); rows.push(row); }); // Sort array logically: supertype, type, rarity, id rows = rows.sort(function(a,b){ var rarity_num = ['Basic','Fine','Masterwork','Rare','Exotic','Ascended','Legendary']; return a[1].localeCompare(b[1]) || a[2].localeCompare(b[2]) || rarity_num.indexOf(a[0]) > rarity_num.indexOf(b[0]) || a[4] - b[4]; }); // Print to page as html table var h = '<table class="table mech1"><tbody>'; h += '<tr>' + $.map(column_titles, function(x) { return '<th>' + x + '</th>' }).join('') + '</tr>\n'; h += $.map(rows, function(r) { return '<tr>' + $.map(r, function(x) { return '<td>' + x + '</td>' }).join('') + '</tr>'; }).join('\n') + '\n'; h += '</tbody></table>'; // Print to page as wikicode var w = '{| {{STDT|mech1}}'; w += '\n! ' + $.map(column_titles, function(x) { return x }).join(' !! '); w += '\n' + $.map(rows, function(r) { return '|-\n| ' + $.map(r, function(x) { return x }).join(' || '); }).join('\n') + '\n'; w += '|}'; $(ref).html(h); $(ref).after('<pre' + '>' + w + '</' + 'pre>'); } // Main function function dropResearch (inputs) { var item_ids = inputs.item_ids.unique(); var promises = [], maxsize = 200, ids, typearray = []; // Items ids = item_ids; for (var i=0; i<ids.length; i+=maxsize) { var current_ids = ids.slice(i,i+maxsize).join(','); var promise = $.getJSON('https://api.guildwars2.com/v2/items?ids='+current_ids+'&lang=en'); promises.push(promise); typearray.push('items'); } // Itemstats (just get all of them) var promise = $.getJSON('https://api.guildwars2.com/v2/itemstats?ids=all'+'&lang=en'); promises.push(promise); typearray.push('itemstats'); $.when.apply($,promises) .done(function() { // Collate data by type and id var reference_data = { 'items': {}, 'itemstats': {} }; // Ensure data is an object var response = arguments; $.each(response, function(i,e){ $.each(e[0], function(k,v){ reference_data[typearray[i]][v.id] = v; }); }); // Obtain upgrade item ids var item_ids2 = $.map(reference_data.items, function(v){ if ('details' in v && 'suffix_item_id' in v.details) { return v.details.suffix_item_id; } }); item_ids2 = item_ids2.diff(item_ids); // Further API queries // Request upgrade item ids var promises2 = [], typearray2 = []; ids = item_ids2; for (var i=0; i<ids.length; i+=maxsize) { var current_ids = ids.slice(i,i+maxsize).join(','); var promise = $.getJSON('https://api.guildwars2.com/v2/items?ids='+current_ids+'&lang=en'); promises2.push(promise); typearray2.push('items'); } $.when.apply($,promises2) .done(function() { // Ensure data is an object var response2 = []; if ( promises2.length > 1 ) { response2 = arguments; } else { response2[0] = arguments; } $.each(response2, function(i,e){ $.each(e[0], function(k,v){ reference_data[typearray2[i]][v.id] = v; }); }); // Send to printer makeTableHTML(inputs, reference_data, '#apidata'); }); }); } dropResearch(inputs);
Wiki - Redirect and new page markup in a list[edit]
$.map( $('.mw-redirect'), function(v){ $(v).text( $(v).text() + '¦REDIRECT' ); }); $.map( $('.new'), function(v){ $(v).text( $(v).text() + '¦NEW' ); });
Wiki - Special:Version[edit]
// Script to run whilst on [[Special:Version]] function jsonVersion() { // Remove table colspan headings $('#mw-content-text [colspan]').remove(); // In each table, remove license (col 3), description (col 4) and authors (col 5) $('table td:nth-child(5), table th:nth-child(5), table td:nth-child(4), table th:nth-child(4), table td:nth-child(3), table th:nth-child(3)').remove(); // Add final heading $('#mw-content-text').append('<h2 id="endofpage">End of page</h2>'); // Remove invisible stuff $('#mw-content-text > div, #mw-content-text > span').remove(); // Put all the dumb text nodes into a div var e1 = getTextInbetween($('#mw-version-parser-extensiontags')[0], $('#mw-version-parser-function-hooks')[0]); $('#mw-version-parser-extensiontags').after('<div id="insert1" class="retain" data-title="Extension tags"></div>'); $('#insert1').text(e1); var e2 = getTextInbetween($('#mw-version-parser-function-hooks')[0], $('#endofpage')[0]); $('#mw-version-parser-function-hooks').after('<div id="insert2" class="retain" data-title="Parser function hooks">' + e2 + '</div>'); $('#insert2').text(e2); // Replace all of the .retain content with tables var r = $('.retain'); $.each(r, function(i,v) { var title = $(v).attr('data-title'); var tx = $(v).text(); var tx_array = tx.replace(' and ',', ').split(','); tx_array = $.map(tx_array, function(x) { return x.trim().replace('<','').replace('>','') }); var tb = $('<table class="wikitable"><tbody><tr><th>' + title + '</th></tr>'+ $.map(tx_array, function(x) { return '<tr><td>' + x + '</td></tr>' }).join('') +'</tbody></table>'); $(v).replaceWith(tb); }); // Remove h2 $('h2').remove(); // Get remaining tables and JSON them. var version = {}; var tables = $('#mw-content-text table'); $.each(tables, function(i,table) { var table_title = $(table).find('th')[0].textContent; var table_data_array = $('tr', table).get().map(function(row) { return $(row).find('td').get().map(function(cell) { return $(cell).text(); }); }); var table_data_obj = {}; $.map(table_data_array, function(x){ if (typeof x !== 'undefined' && x.length != 0) { table_data_obj[x[0]] = x[1] || true; } }); version[table_title] = table_data_obj; }); $('#mw-content-text').html('<pre' + '></' + 'pre>'); $('#mw-content-text pre').text(JSON.stringify(version, null, 2)); } function getTextInbetween(startNode, stopNode) { if (startNode.parentElement != stopNode.parentElement) return; var elements = startNode.parentElement.childNodes; var startPos = [].indexOf.call(elements, startNode); // Get all the text from start to stop var text = []; var i_arr = []; for (var i = startPos; i < elements.length; ++i) { if (elements[i].nodeType == 3 || elements[i].nodeType == 1) { text.push(elements[i].textContent); i_arr.push(i); } if (elements[i] == stopNode) { break; } } // Remove first and last (don't need contents of the h2) text.pop(); text.shift(); // Go back and remove all the garbage i_arr.pop(); i_arr.shift(); i_arr = i_arr.reverse(); for (var i = 0; i < i_arr.length; i++) { elements[i_arr[i]].remove(); } // remove lines and spaces as HTML does text = text.join('').trim(); text = text.replace(/\s+/g, " "); return text; } jsonVersion();
Wiki - Whatlinkshere alphabetical[edit]
// https://stackoverflow.com/questions/1134976 var list = $('#mw-whatlinkshere-list'); var listitems = list.children('li').get(); listitems.sort(function(a, b) { return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase()); }) $.each(listitems, function(idx, itm) { list.append(itm); });
Wiki - Whitespace hunting[edit]
Option 1 - NBSP only[edit]
var a = $('#wpTextbox1').val(); var position = a.indexOf(String.fromCharCode(160)); if ( position !== -1 ) { console.log('Position of non-breaking space character: ', position); console.log( a.substr(0,position), '<<<nbsp>>>' ); } else { console.log('Did not find non-breaking space') }
Option 2 - Tabulate data[edit]
Array.prototype.unique = function() { return this.filter(function (el, i, self) { return self.indexOf(el) === i; }); }; /* Acquire data */ var nodename = 'wpTextbox1' var textareanode = $('#' + nodename); var str = textareanode.val(); /* Note: Selection/highlight only appears when its the active window, so remember to alt+tab after running this script! */ const highlightnode = document.getElementById(nodename); highlightnode.focus(); /* Highlight the adjacent characters (note, this moves the selection so if there's more than one baddie, it'll highlight only the last one */ var j; var results = []; for (var i = 0; i < str.length; i++) { j = str.charCodeAt(i); results.push(j); if (j > 255) { highlightnode.setSelectionRange(i-1, i + 2); } } results_unique = results.unique().sort(); /* Construct a frequency table */ var freq_table = {}; $.map(results_unique, function(v){ freq_table[v] = 0; }); $.map(results, function(v) { freq_table[v] += 1; }); var c = $.map(freq_table, function(v, k){ return String.fromCharCode(k) + ' ==> code ' + k + ' (' + v + ' occurrences)'; }); console.log(JSON.stringify(c,null,2));
Option 3 - Just remove it[edit]
Array.prototype.unique = function() { return this.filter(function (el, i, self) { return self.indexOf(el) === i; }); }; var whitelist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/*-+=,.?<>;#:@~[]{}`¦¬!\"£$%^&*()_,²«»¶¦|—"; var str = $('#wpTextbox1').val(); var N, L, textoutput = '', removed = []; for (var i = 0; i < str.length; i++) { L = str.charAt(i); N = str.charCodeAt(i); /* 160 is nbsp */ if (N > 159) { /* beyond 160 (nbsp) we're going to check if its in our whitelist above */ if (whitelist.includes(L)) { textoutput = textoutput + L; } else { removed.push(N); } } else { textoutput = textoutput + L; } } $('#wpTextbox1').val(textoutput); if (removed.length > 0) { var results_unique = removed.unique().sort(); var freq_table = {}; $.map(results_unique, function(v){ freq_table[v] = 0; }); $.map(removed, function(v) { freq_table[v] += 1; }); var c = $.map(freq_table, function(v, k){ return k + ' ==> "' + String.fromCharCode(k) + '" ' + '(x' + v + ')'; }); $('#wpSummary').val( $('#wpSummary').val() + ' Removed special character codes: ' + c.join(', ')); }
Reddit - API - Weekly questions thread statistics[edit]
/* Reddit API query tool for post count */ // Setup var baseurl = 'https://www.reddit.com/r/Guildwars2/search.json?q=question+thread+author%3AAutoModerator+OR+author%3AIntigo&sort=new&restrict_sr=on&t=all'; var datadrop = []; // Function to concatenate all data function processdata (datadrop) { console.log('datadrop',datadrop); var dump = []; $.each(datadrop, function(kk,vv){ $.each(vv, function(k,v){ if ( (v.data.title.indexOf('Weekly') > -1 ) && (v.data.title.indexOf('Question') > -1) ) { var date = new Date(v.data.created_utc*1000); dump.push({ title: v.data.title, count: v.data.num_comments, date: date }); } }); }); console.log('dump',dump); $('#apidata').html(makeTableHTML(dump)); } // Function to convert an object variable into a table function makeTableHTML ( data ) { var result = '<table class="table mech1"><tbody>' +'<tr><th>Date</th><th>Title</th><th>Comment count</th></tr>'; $.each(data, function(k, v) { result += '<tr>' +'<td>'+ pad(v['date'].getUTCDate()) + '/' + pad(v['date'].getUTCMonth()+1) + '/' + v['date'].getUTCFullYear() + '</td>' +'<td>'+v['title']+'</td>' +'<td>'+v['count']+'</td>' +'</tr>'; }); result += "</tbody></table>"; return result; } // Function to pad numbers into character strings with leading zeroes function pad (s) { return (s < 10 ? '0' : '') + s; } // Fetch all the threads function apiQuery (qc, token) { qc = qc + 1; var url = baseurl; if (token) { url += '&after=' + token } $.getJSON(url).done(function(data){ datadrop.push(data['data']['children']); if (qc > 8) { console.log('Query max count reached.'); processdata(datadrop); } else { if ('after' in data['data'] && data['data']['after'] !== null) { apiQuery(qc, data['data']['after']); } else { console.log('Query complete.'); processdata(datadrop); } } }); } console.log('User pressed run. Starting queries.'); apiQuery(0);
Miscellaneous - Build CSS from table[edit]
var mode = 'common'; // 'common', 'monobook', 'mobile', 'minerva', 'vector' // Lookup object var delete_columns = { 'common': [ 3,4,5,6], 'monobook': [2, 4,5,6], 'mobile': [2,3, 5,6], 'minerva': [2,3,4, 6], 'vector': [2,3,4,5 ], } // Remove irrelevant columns $('small').remove(); $('#csstable tr:nth-child(1)').remove(); $.each(delete_columns[mode].reverse(), function(i,v) { $('#csstable tr td:nth-child(' + v + '), #csstable tr th:nth-child(' + v + ')').remove(); }); // Remove excessive newlines and empty headings var t = $('#csstable').text() .replace(/\n(\n\n+)/g,'\n\n') .replace(/(-------- \*\*\/)(\n+)/g,'$1\n') .replace(/(\/\*\* -------- )(.*?)( -------- \*\*\/)\n(\/\*\* -------- )/g,'$4') .replace(/(\/\*\* -------- )(.*?)( -------- \*\*\/)\n(\/\*\* -------- )/g,'$4') .replace(/^( {4})/gm,' ') .trim(); // Replace content $('#cssoutput').text(t);
Miscellaneous - Chatlinks to IDs[edit]
/** window.atob & window.btoa polyfill * WTFPLv2 – https://github.com/davidchambers/Base64.js */ !function(){function t(t){this.message=t}var e=this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=new Error,t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-a%1*8)){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),e.length%4==1)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(-2*a&6)):0)n=r.indexOf(n);return c})}(); // Decode chatlinks into type and ids function decodeChatLink(code) { var binary = window.atob(code); var octets = new Array(binary.length); for (var i = 0; i < binary.length; i++) { octets[i] = binary.charCodeAt(i); } var type; var id = octets[2] << 8 | octets[1]; if (octets[0] == 2) { type = 'item'; id = octets[3] << 8 | octets[2]; id = (octets.length > 4 ? octets[4] << 16 : 0) | id; } else if (octets[0] == 4 ) { type = 'location'; } else if (octets[0] == 6 ) { type = 'skill'; } else if (octets[0] == 7 ) { type = 'trait'; } else if (octets[0] == 9 ) { type = 'recipe'; } else if (octets[0] == 10) { type = 'skin'; } else if (octets[0] == 11) { type = 'outfit'; } else { type = 'unknown' } var outputobject = { code: code, octets: octets, binary: binary, type: type, id: id }; return outputobject; } // (function chatlinksToIDs () { var rawtext = $('#inputrawtext'); rawtext = rawtext.html().replace("&","&"); // Regular expression matching var expr = /\[&([A-Za-z0-9+/]+=*)\]/g; var match, onlychatlinks = [], internalchatlinks = [], internalIDs = [], outputIDs = []; while ((match = expr.exec(rawtext))) { onlychatlinks.push(match[0]); internalchatlinks.push(match[1]); } // Take each matched expression, and decode it $.each(internalchatlinks, function(i,v){ internalIDs.push(decodeChatLink(v)); }); // Only interested in the ids here $.each(internalIDs, function(i,v){ outputIDs.push(v.id); }); // Print results $('#outputchatlinks').html(JSON.stringify(onlychatlinks)); $('#outputids').html(outputIDs.length + ' ids found.<br>' + JSON.stringify(outputIDs)); })();
Miscellaneous - Compare Silver Mirror with Gemstore[edit]
<div id="apidata1">[[File:Mediawiki loading animation.gif]] 1</div> <div id="apidata2">[[File:Mediawiki loading animation.gif]] 2</div>
/* GW2 API query tool for comparing Silver's Mirror (static address) with the ArenaNet page (moves around) */ var url1 = 'https://api.datawars2.ie/gw2/v1/gemstore/catalogue/json'; var url2 = 'https://2gemstore.staticwars.com/const/gw2/build116703/GemStore/en/catalog.a856377d.js'; // amend when comparing - take the value within the source of https://gemstore-live.ncplatform.net/?buildid=999999&language=en&gamecode=gw2 $.loadScript = function (url, callback, callbackerror) { $.ajax({ url: url, dataType: 'script', success: callback, error: callbackerror, async: true }); }; function makeTableHTML(dataUnsorted,prefix) { var data = $.map(dataUnsorted, function(v,k){ v.uuid = k; return v; }); data = data.sort(function(a,b) { return a.uuid > b.uuid; }); var result = '<h2>' + prefix + '</h2>'; result += '<table class="table mech1" style="margin-bottom:0px;"><tr><th>Gemstore GUID</th><th>Name</th><th>Item id</th></tr>'; $.each(data, function(k, v) { result += '<tr><td>'+v.uuid+'</td><td>'+v.name+'</td><td>'+v.dataId+'</td></tr>'; }); result += '</table>'; return result; } // Fetch all the possible achievement IDs (function fetchAPIData() { $.getJSON(url1).done(function (data) { var data2 = {}, uuid; $.each(data, function(k,v) { // Copy uuid = data[k].uuid; // Remove things that will be different delete data[k].categoriesOld; delete data[k].categoryLifespans; delete data[k].categoryLifespansOld; delete data[k].firstAdded; delete data[k].gemPrice; delete data[k].latestEndDate; delete data[k].latestStartDate; delete data[k].uuid; // Paste into new object data2[uuid] = data[k]; }); $('#apidata1').html(makeTableHTML(data2,"Silver's Mirror")); }); $.loadScript(url2, function () { $('#apidata2').html(makeTableHTML(gemstoreCatalog,"ArenaNet's Hidden Catalogue")); }, function(jqxhr, textStatus, error) { console.log("Request to the gemstore failed.", jqxhr, textStatus, error); }); })();
Miscellaneous - Decimal, Hex and Charcode table[edit]
var a = []; for (var i = 0; i < 256; i++){ a.push('<tr><th>'+i+'</th><td>'+i.toString(16)+'</td><td>'+String.fromCharCode(i)+'</td></tr>'); } $('#apidata').html('<table class="wikitable"><tr><th>decimal value</th><th>hex value</th><th>fromCharCode character equivalent</th></tr>'+a.join('\n')+'</table>');
Miscellaneous - Remove newlines from tables[edit]
// Remove <br> tags $('table br').remove(); // Remove p tags (and possibly newlines?) by converting html to raw text $('table td, table th').each(function(){ $(this).html( $(this).text() ); });
Miscellaneous - Remove dead files from galleries[edit]
// Use this whilst using "show preview" on [[User:Darqam/Dat_Icons]] // Find all gallery elements var gallery_elements = $('.gallerybox .thumb'); // Gather elements with no child elements (i.e. text only with no images) var empty_gallery_elements = $.map(gallery_elements, function(v){ if (v.childElementCount == 0) { return v; } }); // Collate the moved file names var moved_file_names = $.map(empty_gallery_elements, function(v){ return v.childNodes[0].textContent; }); // Get the editing box text content var editing_box_text_lines = $('#wpTextbox1').text().split('\n'); // Scan through editing box lines for moved files var editing_box_text_lines_new = $.map(editing_box_text_lines, function(v){ // Compare left-hand side of any pipe elements with the whole array of moved file names var lhs = v.split('|')[0].trim().replace('File:',''); if (moved_file_names.indexOf( lhs ) == -1 ) { return v; } }); // Update text-box content without moved files $('#wpTextbox1').text( editing_box_text_lines_new.join('\n') ); $("#wpTextbox1").fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100); console.log('Files removed from textbox: ', moved_file_names.length );
Miscellaneous - Template wikicode to html table[edit]
// For use when the edit box of a page calling a template is being viewed function wikiTemplateToTable(){ var config = { inputselector: '#wpTextbox1', templatename: 'Gem store entry', fieldnames: ['item', 'availability', 'cost', 'discounted', 'qty', 'section', 'subsection'] }; var template_array_object = wikitextToObject($(config.inputselector).val(), config); $('#mw-content-text').before( makeTableHTML(template_array_object, config.fieldnames) ); } function wikitextToObject(wikitext, config){ // Remove excess whitespace wikitext = wikitext.trim().replace(/\n\n/g,'\n'); // Remove first line ("{{templatename") and remove last line ("}}") var wikitextlines = wikitext.split('\n'); wikitextlines.shift(); wikitextlines.pop(); wikitext = '\n' + wikitextlines.join('\n'); // Split by template name var templatewikitextlines = wikitext.split('\n}}\n{{' + config.templatename + ''); var temp_by_line, temp_obj, param; var outputarr = $.map(templatewikitextlines, function(v,i){ // Split by newline and template parameter delimiter temp_by_line = v.split('\n| '); // Remove first empty element temp_by_line.shift(); // Loop through each template parameter, check if whitelisted, then add to array temp_obj = {}; $.map(temp_by_line, function(vv){ param = vv.split(' = '); if (config.fieldnames.indexOf(param[0]) != -1) { temp_obj[param[0]] = param[1]; } }); return temp_obj; }); return outputarr; } // Function to convert an array object variable into a table function makeTableHTML(data, fieldnames) { // Remove any previous tables $('#temptable').remove(); // Generate new one var result = '<table id="temptable" class="wikitable"><tbody>'; if (data.length > 0) { var columns = fieldnames; // Object.keys(data[0]); result += '<tr>' + $.map(columns, function(c) { return '<th>' + c + '</th>'; }).join('') + '</tr>'; result += $.map(data, function(v) { return '<tr>' + $.map(columns, function(c) { return '<td>' + v[c] + '</td>'; }).join('') + '</tr>'; }).join('\n'); } result += '</tbody></table>'; return result; } wikiTemplateToTable();
Miscellaneous - Unique keys in object[edit]
// Find all possible keys for an object of depth 1 var obj = {}; var uniquekeys = []; $.each(obj, function(i, v){ $.each(Object.keys(v), function(ii, vv){ if (uniquekeys.indexOf(vv) == -1) { uniquekeys.push(vv); } }); }); console.log(JSON.stringify(uniquekeys));
Miscellaneous - World link history (via werdes.net)[edit]
var continentFilter = 'EU'; var worldFilter = 'Fort Ranik'; var uniqueLinkFilter = false; function makeTableHTML(data) { // First pass var output_arr_full = []; $.each(data, function(k, v) { // Collate team names var teams = []; $.map(["red", "green", "blue"], function(c){ var this_team = []; this_team.push(v.worlds[c].name); $.map(v.worlds[c].additional_worlds, function(ac){ this_team.push(ac.name); }); teams.push( this_team.join(', ') ); }); var continent = (v.arenanet_id[0] == '1' ? 'NA' : 'EU'); var filter_match_continent = true; if (continentFilter && continentFilter.length > 0) { filter_match_continent = false; if (continent === continentFilter) { filter_match_continent = true; } } var teams_smushed = teams.join(', '); var filter_match_world = true; if (worldFilter && worldFilter.length > 0) { filter_match_world = false; if (teams_smushed.indexOf(worldFilter) !== -1) { filter_match_world = true; } } var filter_match_only = ''; if (uniqueLinkFilter) { $.map(teams, function(t){ if (t.indexOf(worldFilter) !== -1) { filter_match_only = t; } }); } // Array of objects output output_arr_full.push({ flag: filter_match_world && filter_match_continent, start_date: v.start.replace('T18:00:00',''), continent: continent, match_tier: v.arenanet_id[2], red: teams[0], green: teams[1], blue: teams[2], server_choice: (uniqueLinkFilter ? filter_match_only : '' ) }); }); Array.prototype.wvwfilter = function(continent) { return this.filter(function (el, i, self) { return (el.continent == continent) && (el.flag); }); }; // Second pass var output_arr_filtered = output_arr_full.wvwfilter(continentFilter).sort(function(a,b){ return Date.parse(b.start_date) < Date.parse(a.start_date); }); // Check all results didn't get removed if (output_arr_filtered.length == 0) { return; } var columns; var output_arr_final = []; if (uniqueLinkFilter) { var prev_world_choice = ''; $.map(output_arr_filtered, function(a) { if (a.server_choice !== prev_world_choice) { output_arr_final.push(a); } prev_world_choice = a.server_choice; }); columns = ["start_date", "server_choice"]; } else { output_arr_final = output_arr_filtered; columns = Object.keys(output_arr_final[0]); } // Convert to output result if (output_arr_final.length == 0) { return; } // Headers var result = '<table class="table mech1">'; $.each(columns, function(i,v) { result += '<th class="header-' + v + '">' + v + '</th>' }); result += '</tr>'; // Rows $.each(output_arr_final, function(i,v) { result += '<tr>'; $.each(columns, function(ii,vv){ if (typeof v[vv] == 'object') { result += '<td>' + JSON.stringify(v[vv]) + '</td>'; } else { if (vv == 'red' || vv == 'green' || vv == 'blue') { result += '<td class="cell-worlds cell-' + v[vv].replace(/ /g,'').replace(/,/g,' cell-') + '">' + v[vv] + '</td>'; } else { result += '<td class="cell-other">' + v[vv] + '</td>'; } } }); result += '</tr>'; }); result += '</table>'; return result; } // Main function $.getJSON('https://api.kills.werdes.net/api/matchlist/all?ts=1700848232594', function(matches) { $('#apidata').html(makeTableHTML(matches)); });
Miscellaneous - CSS for tables in gw2efficiency[edit]
table.c-table { width: auto; } .eff-margin-top-s { margin: 0; } table.account-overview tr td, table.account-overview tr th { border: 1px solid black; } .eff-font-size-xs div { display: none; } .eff-font-size-xs :nth-child(4), .eff-font-size-xs :nth-child(6), .eff-font-size-xs :nth-child(7) { display: block; } table.account-overview tr > :nth-child(2), table.account-overview tr > :nth-child(3), table.account-overview tr > :nth-child(5) { display:none; } table.account-overview tr td:nth-child(1) div:nth-child(2) { display:none; }