User:Waggers/degrandparent dev.js

From Wikimedia Commons, the free media repository
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.
// <!-- 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) -->