Last active
August 29, 2015 14:24
-
-
Save he7d3r/f503e056f77fd0fd1a90 to your computer and use it in GitHub Desktop.
WMGrep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on https://meta.wikimedia.org/wiki/User:Krinkle/Tools/Global_SUL.js?oldid=10130488 | |
/** | |
* This script provides an extra Special-page action called "WMGrep" which | |
* allows searching over all WMF wikis. | |
* After enabling the script, the tool is accessible from [[Special:BlankPage/wmgrep]]. | |
* | |
* @source meta.wikimedia.org/wiki/User:Krinkle/Tools/Global_SUL | |
* @revision 4 (2014-10-08) | |
* @stats [[File:Krinkle_Global_SUL.js]] | |
*/ | |
(function ($, mw) { | |
/** | |
* Iterate over all SiteMatrix wikis. | |
* @source www.mediawiki.org/wiki/User:Krinkle/Snippets/Iterate_SiteMatrix_in_JavaScript | |
* @revision 5 (2012-01-29) | |
* @example | |
* <code> | |
* var it = new mw.siteMatrix.Iterator({ | |
* centralApiPath: mw.util.wikiScript('api'), | |
* // iterator {Iterator} | |
* // wikiObj {Object}: contains 'url', 'dbname' and maybe 'private' | |
* // iterationNr {Number}: starting at 0 | |
* // listLength {Number}: length of list iteration array | |
* onIteration: function (iterator, wikiObj, iterationNr, listLength) { | |
* iterator.next(); | |
* }, | |
* onComplete: function (iterator, wikiObj, listLength) { | |
* | |
* } | |
* }); | |
* it.start(); | |
* </code> | |
* | |
* @param options {Object} | |
* - centralApiPath string: Path to api of a wiki that has the SiteMatrix installed | |
* - onIteration function: callback for action on each wiki | |
*/ | |
if (mw.siteMatrix === undefined) { | |
mw.siteMatrix = {}; | |
} | |
mw.siteMatrix.Iterator = function Iterate(options) { | |
var i, current, list, instance = this; | |
if (!options.centralApiPath || !options.onIteration) { | |
throw new Error('Invalid arguments'); | |
} | |
if (!(this instanceof mw.siteMatrix.Iterator)) { | |
throw new TypeError('Illegal function call'); | |
} | |
instance.start = function start() { | |
if (i !== undefined) { | |
throw new Error('Cannot start twice'); | |
} | |
$.getJSON(options.centralApiPath + '?format=json&action=sitematrix&callback=?', function (data) { | |
i = 0; | |
list = []; | |
if (!data || !data.sitematrix) { | |
return; | |
} | |
$.each(data.sitematrix, function (key, value) { | |
var group, wi; | |
if (key === 'count') return; | |
group = key === 'specials' ? value : value.site; | |
if ($.isArray(group) && group.length) { | |
for (wi = 0; wi < group.length; wi += 1) { | |
// Only public wikis | |
if (group[wi]/*reserved_word*/['private'] === undefined && group[wi].closed === undefined && group[wi].fishbowl === undefined) { | |
list.push(group[wi]); | |
} | |
} | |
} | |
}); | |
instance.next(); | |
}); | |
}; | |
instance.next = function next() { | |
if (i < list.length) { | |
current = list[i]; | |
options.onIteration(instance, current, i, list.length); | |
i += 1; | |
} else { | |
options.onComplete(instance, current, list.length); | |
} | |
}; | |
return instance; | |
}; | |
function initWmGrep() { | |
var $content, $fieldset, $subtitle, $table, | |
$status, $btnStart, $progress, $done, $log, | |
searchTerm; | |
$content = $('#bodyContent').empty(); | |
$fieldset = $('<fieldset>'); | |
$subtitle = $('<div id="contentSub"></div>'); | |
$table = $( | |
'<table class="wikitable" style="width: 100%;"><tbody>' | |
+ '<tr><th>Status</th><th>Progress</th></tr>' | |
+ '<tr>' | |
+ '<td id="mw-wmgrep-status" style="width: 80%;">Ready for action! <button id="mw-wmgrep-start">Start</button></td>' | |
+ '<td style="vertical-align: top;"><span id="mw-wmgrep-progress">0%</span>' | |
+ '<span id="mw-wmgrep-done" style="float: right;"></span>' | |
+ '</td>' | |
+ '</tr>' | |
+ '<tr>' | |
+ '<td colspan="2" id="mw-wmgrep-log" style="padding-top: 1em;"><ul></ul></td>' | |
+ '</tr></tbody></table>' | |
); | |
$status = $table.find('#mw-wmgrep-status'); | |
$btnStart = $table.find('#mw-wmgrep-start'); | |
$log = $table.find('#mw-wmgrep-log > ul'); | |
$progress = $table.find('#mw-wmgrep-progress'); | |
$done = $table.find('#mw-wmgrep-done'); | |
function doUpdate(msg, iterationNr, listLength) { | |
$status.text(msg); | |
$log.prepend('<li>' + new Date().toString().replace(/^\w+ /, '').replace(/:[^:]+$/, '') + ': ' + mw.html.escape(msg) + '</li>'); | |
if (iterationNr && listLength) { | |
$progress.text((Math.round(((iterationNr) / listLength) * 100 * 10) / 10) + '%'); | |
$done.text('(' + iterationNr + '/' + listLength + ' wikis)'); | |
} | |
} | |
// function getGlobalAccountInfo(ok, err) { | |
// $.ajax({ | |
// url: mw.util.wikiScript('api'), | |
// dataType: 'json', | |
// data: { | |
// format: 'json', | |
// action: 'query', | |
// meta: 'globaluserinfo', | |
// guiuser: mw.user.getName(), | |
// guiprop: 'merged|unattached' | |
// }, | |
// success: function (data) { | |
// if (data && data.query && data.query.globaluserinfo) { | |
// ok(data.query.globaluserinfo); | |
// } else { | |
// err(); | |
// } | |
// }, | |
// error: err | |
// }); | |
// } | |
// Build front-end | |
$('#firstHeading').text('WMGrep'); | |
document.title = 'WMGrep - ' + mw.config.get('wgSiteName'); | |
$fieldset | |
.text('Check all public Wikimedia wikis for pages containing a search term.') | |
.prepend($('<legend>').text('Search WMF wikis')) | |
.append($table); | |
// Bind events | |
$btnStart.click(function (e) { | |
var iterator, found = []; | |
searchTerm = prompt( 'Search for:', 'wikiGetlink' ); | |
if (!searchTerm) { | |
return; | |
} | |
$(this).remove(); | |
doUpdate('Initializing...'); | |
iterator = new mw.siteMatrix.Iterator({ | |
centralApiPath: mw.util.wikiScript('api'), | |
onIteration: function (instance, wikiObj, iterationNr, listLength) { | |
var url, hostname; | |
// All WMF wikis support https, but canonical is still 'http' | |
// convert API absolute urls to relative urls so that | |
// users of this gadget can be on either http or https and it works | |
url = wikiObj.url.replace(/^https?:/, ''); | |
hostname = url.replace(/^\/\/?/, ''); | |
doUpdate(hostname + ': searching...', iterationNr, listLength); | |
$.ajax({ | |
url: wikiObj.url + mw.util.wikiScript('api'), | |
dataType: 'jsonp', | |
data: { | |
format: 'json', | |
action: 'query', | |
list: 'search', | |
srsearch: searchTerm, | |
srnamespace: 8, | |
srwhat: 'text', | |
srinfo: 'totalhits|suggestion', | |
srprop: 'size|wordcount|timestamp|snippet|titlesnippet'+ | |
'|redirecttitle|redirectsnippet|sectiontitle'+ | |
'|sectionsnippet|isfilematch|categorysnippet' | |
} | |
}) | |
.done(function (data) { | |
if (data && data.query && data.query.search) { | |
$.each(data.query.search, function (i, obj) { | |
var url = 'https://' + hostname + '/wiki/' + obj.title; | |
found.push( url ); | |
doUpdate( url ); | |
// <code>obj.snippet</code> | |
}); | |
} | |
instance.next(); | |
}) | |
.fail( instance.next ); | |
}, | |
onComplete: function (instance, wikiObj, listLength) { | |
doUpdate('Finished.', listLength, listLength); | |
$status.html('Found ' + found.length + ' results.'); | |
if (found.length > 0) { | |
$status.append('<ul><li>' + found.join('</li><li>') + '</li></ul>'); | |
} | |
} | |
}); | |
found = []; | |
doUpdate('Loading wiki SiteMatrix...'); | |
iterator.start(); | |
}); | |
// Output | |
$content.append($subtitle, $fieldset); | |
} | |
// Enqueue init | |
if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && mw.config.get('wgTitle').indexOf('/wmgrep') > 2) { | |
mw.loader.using('mediawiki.util', initWmGrep); | |
} | |
}(jQuery, mediaWiki)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment