User:Waggers/degrandparent.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
This user script seems to have a documentation page at User:Waggers/degrandparent. |
// <!-- to prevent unwanted cats
var dgp_parent_files = [];
var dgp_edit_token;
var files_found = 0;
var parent_cat;
var cat_count = 0;
var files_checked = 0;
var dgp_mode = "";
var dgp_sequential = 0;
function degrandparent()
{
$("div#dgp").html('<div style="border: 1px solid navy; float: left; width: 818px; padding:3px;" >'
+ '<div style="width:812px; float:left; border:2px solid gold;">'
+ '<span>Category:<input type="text" id="dgp_cat" value="" /></span>'
// + '<span>File limit:<input type="Number" id="dgp_file_limit" value="1000"></span>'
+ '</div>'
+ '<div style="width:400px; float:left; border:1px solid gold; clear:left; padding:2px;"><h4>Search all subcategories</h4>'
+ '<span>Depth:<input type="Number" id="dgp_depth" value="5"></span>'
//+ '<span>Subcategory limit:<input type="Number" id="dgp_subcat_limit" value="100"></span><br>'
+ '<button id="dgp_btn_fetch" onclick="dgp_fetch(this);">Fetch</button></div>'
+ '<div style="width:400px; float:right; border:1px solid gold; padding:2px;"><h4>Search specific subcategory</h4>'
// + '<div style="width:800px; float:left; border:1px solid gold; padding:2px;"><h4>Search specific subcategory</h4>'
+ '<span>Subcategory:<input type="text" id="dgp_subcat" value="" /></span>'
+ '<button id="dgp_btn_fetch_subcat" onclick="dgp_fetch_subcat(this);">Fetch</button>'
+ '</div>'
+ '</div>'
+ '<div id="dgp_progress" style="clear:left"></div>'
+ '<div id="dgp_alldiv" style="clear:left"></div>'
+ '<div id="dgp_results" style="clear:left"></div>');
}
function dgp_get_edit_token(callback)
{
var api_url = "/w/api.php?action=query&meta=tokens&format=json";
$.get(api_url, function(tokendata) {
dgp_edit_token = tokendata.query.tokens.csrftoken;
callback();
});
}
function dgp_fetch_subcat(btn_fetch)
{
dgp_mode = "single";
$(btn_fetch).text("Fetching").attr("disabled",true);
write_results_headings();
cat_count = 0;
files_found = 0;
files_checked = 0;
//get edit token
dgp_get_edit_token(function() {
if (parent_cat != "Category:"+$("#dgp_cat").val())
{
parent_cat = "Category:"+$("#dgp_cat").val();
$("#dgp_progress").html("Creating list of files in " + parent_cat);
//get files in parent category
dgp_filesincat(
parent_cat,
"",
1,
[],
true,
function(files) {
dgp_parent_files = files;
dgp_checkcat("Category:"+$("#dgp_subcat").val(),
parseInt($("#dgp_depth").val()));
}
);
} else {
dgp_checkcat("Category:"+$("#dgp_subcat").val(),
parseInt($("#dgp_depth").val()));
}
});
$(btn_fetch).text("Fetch").attr("disabled",false);
$("div#dgp_alldiv").html("<button id='dgp_btn_rmall' onclick='javascript:dgp_rmall();' style='display:none;'>Remove 50 listed files from parent category</button>"
+ "<button id='dgp_btn_sequential' onclick='javascript:dgp_sequential_toggle();'>Sequential action: "+ (dgp_sequential === 0 ? "Off" : "On") +"</button>"
+ "<button id='dgp_btn_hidedone' onclick='javascript:dgp_hidedone();'>Hide done</button>"
);
}
function dgp_fetch(btn_fetch)
{
dgp_mode = "multi";
$(btn_fetch).text("Fetching").attr("disabled",true);
write_results_headings();
cat_count = 0;
files_found = 0;
files_checked = 0;
dgp_parent_files = [];
//get edit token
dgp_get_edit_token(function() {
if (parent_cat != "Category:"+$("#dgp_cat").val())
{
parent_cat = "Category:"+$("#dgp_cat").val();
$("#dgp_progress").html("Creating list of files in " + parent_cat);
//get files in parent category
dgp_filesincat(
parent_cat,
"",
1,
[],
true,
function(files) {
dgp_parent_files = files;
checksubcats(function() {
$(btn_fetch).text("Fetch").attr("disabled",false);
$("#dgp_progress").html(files_found + " of "
+ files_checked + " files in " + cat_count + " subcategories are also in " + parent_cat);
});
}
);
} else {
$("#dgp_progress").html("Creating list of files in " + parent_cat);
checksubcats(function() {
$(btn_fetch).text("Fetch").attr("disabled",false);
$("#dgp_progress").html(files_found + " of "
+ files_checked + " files in " + cat_count + " subcategories are also in " + parent_cat);
});
}
});
$("div#dgp_alldiv").html("<button id='dgp_btn_rmall' onclick='javascript:dgp_rmall();' style='display:none;'>Remove 50 listed files from parent category</button>"
+ "<button id='dgp_btn_sequential' onclick='javascript:dgp_sequential_toggle();'>Sequential action: "+ (dgp_sequential === 0 ? "Off" : "On") +"</button>"
+ "<button id='dgp_btn_hidedone' onclick='javascript:dgp_hidedone();'>Hide done</button>"
);
}
function write_results_headings()
{
$("#dgp_results").html("<div style='font-weight:bold;'>"
+ "<div style='float:left; width:50%'>"
+ "File"
+ "</div><div style='float:left; width:25%'>"
+ "Subcategory"
+ "</div><div style='float:left; width:25%'>"
+ "Action"
+ "</div></div>");
}
function checksubcats(callback)
{
//Get subcategories of parent category
api_url = "/w/api.php?format=json&action=query&list=categorymembers&cmtype=subcat&cmtitle="+parent_cat
+"&cmlimit=500";
$.get(api_url,function(data) {
//each subcategory of parent category
$.each(data.query.categorymembers, function(index, cat) {
// If the subcategory is the parent category (i.e. there's a category loop), ignore it.
if ("Category:"+$("#dgp_cat").val() != cat.title)
{
dgp_checkcat(cat.title, 1, function() { });
}
}); //each subcategory
callback();
}); //get subcagetories
}
function dgp_rmall()
{
$("button.dgp_btn_rm:enabled").slice(0,50).each(function() {
this.click();
});
}
function dgp_sequential_toggle()
{
if (dgp_sequential === 0)
{
dgp_sequential = 1;
} else {
dgp_sequential = 0;
}
$("button#dgp_btn_sequential").text("Sequential action: " + (dgp_sequential === 0 ? "Off" : "On"));
}
function dgp_action_next()
{
if (dgp_sequential === 1)
{
$("button.dgp_btn_rm:enabled:first").text("Wait for it...");
setTimeout(function() { $("button.dgp_btn_rm:enabled:first").click(); }, 2000);
}
}
function dgp_hidedone()
{
$("button.dgp_btn_rm.done").each(function() {
$(this).parent().parent().hide();
});
}
function dgp_makelink(itemtitle)
{
var urlprefix = "/w/index.php?title=";
return '<a href="' + urlprefix + itemtitle + '">' + itemtitle + '</a>';
}
function dgp_rm(itemtitle, callbtn, dgp_edit_token_encoded, subcat)
{
$(callbtn).text("Processing...").attr("disabled", true);
//get wikitext of selected file
$.get("/w/index.php?action=raw&title=" + itemtitle, function(wikitext) {
//remove category from wikitext
var new_wikitext = wikitext.replace("\n[[Category:" + $("#dgp_cat").val()+"]]","")
.replace("[[Category:" + $("#dgp_cat").val()+"]]","");
//update file
$.post("/w/api.php",
{
format: 'json',
action: "edit",
title: decodeURIComponent(itemtitle),
text: new_wikitext,
summary: "[[User:Waggers/degrandparent|DGP:]] Removed from category [[Category:"
+ $("#dgp_cat").val() + "]] because the file is also in subcategory [[" + decodeURIComponent(subcat) + "]] per [[COM:CAT|the Commons Categories policy]].",
token: decodeURIComponent(dgp_edit_token_encoded)
}
).done(function(data){
if ( data && data.edit && data.edit.result == 'Success' ) {
dgp_parent_files.splice(dgp_parent_files.indexOf(itemtitle));
$(callbtn).text("Done!").addClass("done");
dgp_action_next();
} else if ( data && data.error ) {
if (data.error.code == "ratelimited")
{
$(callbtn).text("Rate limited. Will try again in a minute");
setTimeout(function () {
dgp_rm(itemtitle, callbtn, dgp_edit_token_encoded, subcat);
}, 60000);
} else if (data.error.code == "editconflict")
{
$(callbtn).text("Failed: Edit conflict.");
dgp_action_next();
} else {
alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
$(callbtn).text("Failed. :(");
dgp_action_next();
}
} else {
alert( 'Error: Unknown result from API.' );
$(callbtn).text("Failed. :(");
dgp_action_next();
}
}); //update
}); //get wikitext
}
function dgp_checkfile(filetitle, cattitle, callback)
{
if (dgp_parent_files.indexOf(filetitle) > -1)
{
files_found++;
$("#dgp_results").append("<div style='clear:left'>"
+ "<div style='float:left; width:50%'>"
+ dgp_makelink(filetitle)
+ "</div><div style='float:left; width:25%'>"
+ dgp_makelink(cattitle)
+ "</div><div style='float:left; width:25%'>"
+ "<button class='dgp_btn_rm' onclick=\"javascript:dgp_rm('"
+encodeURIComponent(filetitle).replace(/'/g, "%27")+"',this, '"
+encodeURIComponent(dgp_edit_token)+"','"
+encodeURIComponent(cattitle).replace(/'/g, "%27")+"')\">Remove from "+ parent_cat +"</button>"
+ "</div></div>");
}
files_checked++;
callback && callback();
}
function ishidden(cattitle, callback)
{
var retval=0;
$.get("/w/api.php?action=query&format=json&prop=categories&titles=" + cattitle, function(cc) {
for (var p in cc.query.pages)
{
for (var ccz in cc.query.pages[p].categories)
{
if (cc.query.pages[p].categories[ccz].title=="Category:Hidden categories" )
{
console.log("Hidden cat found in " + cattitle);
retval = 1;
}
}
}
callback(retval);
});
}
function dgp_checkcat(cattitle, depth, callback)
{
// first, check whether category is hidden. if it is, stop right now!
ishidden(cattitle, function(hiddencat) {
if (hiddencat ==1)
{
console.log (cattitle + " is a hidden category.");
callback && callback();
} else {
//get files in subcategory
dgp_filesincat(
cattitle,
"",
1,
[],
false,
function(files) {
$.each(files, function(index, file) {
files_checked = files_checked + 1;
if (dgp_mode == "single")
{
$("div#dgp_progress").html(files_checked
+ " files checked in " + cattitle
+ ". "
+ files_found + " shared with Category:" + $("#dgp_cat").val());
}
dgp_checkfile(file, cattitle);
}); //each file
}
);
if (depth < parseInt($("#dgp_depth").val()))
{
api_url = "/w/api.php?format=json&action=query&list=categorymembers&cmtype=subcat&cmtitle="
+cattitle
+"&cmlimit=500";
$.get(api_url,function(data) {
//each subcategory of parent category
$.each(data.query.categorymembers, function(index, cat) {
dgp_checkcat(cat.title, depth + 1, function() {
});
}); //each subcategory
});//get subcategories
}
cat_count++;
callback && callback();
}
});
}
function dgp_filesincat(cat_title, cont, iteration, files, parentcat, callback)
{
var params = {
format : "json",
action : "query",
list : "categorymembers",
cmtype : "file",
cmtitle : cat_title,
cmlimit: 500
};
if (cont ==="")
{
params.continue = "";
} else {
for (var x in cont)
{
params[x] = cont[x];
}
}
$.post( "/w/api.php",
params).done(function(data) {
$.each(data.query.categorymembers, function(index, file) {
files.push(file.title);
}); // each file in category
if ("continue" in data)
{
dgp_filesincat(cat_title, data.continue, iteration + 1, files, parentcat, callback);
if (parentcat) {
$("div#dgp_progress").html(files.length + " files found so far in " + cat_title);
} else {
$("div#dgp_progress").html("Generating list of files in " + cat_title);
}
} else
{
$("#dgp_progress").html(files_found + " of "
+ files_checked + " files in " + cat_count + " subcategories are also in " + parent_cat);
callback(files);
}
});
}
if (mw.config.get( 'wgPageName' ) == 'User:Waggers/degrandparent')
{
$(document).ready(degrandparent);
}
// to prevent unwanted cats (end) -->