Jump to content

User:Ahechtbot/wikiprojects.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Ahechtbot (talk | contribs) at 17:27, 29 October 2021 (Update with better error handling). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//Set up parameters
try {
	var credentials = require('../../credentials.js').credentials.enwiki;
} catch {
	console.error("Credentials file not found!");
	return;
} finally {
	if (!credentials) { 
		console.error("Credentials not found in credentials file!")
		return;
	}
}

var templateList = "User:Ahechtbot/WikiProject templates.json";
var templateIncludelistName = "Wikipedia:WikiProject Articles for creation/WikiProject templates.json/includelist.json";
var templateBlocklistName = "Wikipedia:WikiProject Articles for creation/WikiProject templates.json/blocklist.json";
var wikiProjectMainCategory = "Category:WikiProject banner wrapper templates";
var wikiProjectCategories = [ // other WikiProject categories not included in wikiProjectMainCategory
	"Category:WikiProject banners with quality assessment",
	"Category:WikiProject banners without quality assessment",
	"Category:WikiProject banner templates not based on WPBannerMeta",
	"Category:Inactive WikiProject banners",
	"Category:WikiProject banner wrapper templates",
];

//Define globals
require('jsdom-global')(undefined, {"url": credentials.wikiUrl});
require('mock-mediawiki');
var wikiprojects = {}, templateBlockList;
var apiUrl = credentials.wikiUrl+mw.util.wikiScript('api')
var api = new mw.Api({ ajax: { url: apiUrl} });

//Log in
api.login( credentials.username, credentials.password )
	.done (function (data) {
		console.log("Logged in as "+data.login.lgusername);
		templateBlockList = fetchJSONList(templateBlocklistName);
		getTemplateCategories();
	} ).fail (function(error) {
		console.error("Error logging in:");
		console.error(error);
		return;
	} );

function fetchJSONList(listName) {
	var parsedList = {};
	console.log("Attempting to fetch " + listName + "...");
	var listData = JSON.parse($.ajax({
		url: apiUrl, async:false,
		error: function (jsondata) {
			console.warn("Unable to fetch contents of " + listName + ":");
			console.log(jsondata);
			return {};				
		}, data: {action:'parse', format:'json', prop:'wikitext', page: listName, formatversion: '2', origin: '*' }
	}).responseText).parse;
	console.log("Attempting to parse " + listName + "...");
	if (listData && listData.wikitext) {
		try {
			parsedList = JSON.parse(listData.wikitext);
		} catch (jsonerror) {
			console.warn("Error parsing JSON list " + listName + ":");
			console.log(jsonerror);
		}
	}

	return parsedList;
}

function getTemplateCategories(cont) { // Recursively call API
	var query = {
		action: "query",
		list: "categorymembers",
		cmtitle: wikiProjectMainCategory,
		cmtype: "subcat",
		cmlimit: "max",
		origin: '*'
	};
	if (cont) {
		query = Object.assign(query, cont);
	}
	console.log("Fetching subcategories of " + query.cmtitle + "...");
	api.get( query )
		.done (function (data) {
			if (data && data.query && data.query.categorymembers) { //API query returned members
				Object.entries(data.query.categorymembers).forEach( function(item) {
					wikiProjectCategories.push(item[1].title);
				} );
			}
			if (data && data.continue) { //More results are available
				getTemplateCategories(data.continue);
			} else {
				getTemplatesFromCategories();
			}
		} ).fail (function(error) {
			console.warn("Error getting list of categories:");
			console.log(error);
		} );
	return;
}

function getTemplatesFromCategories(catTitle, cont) { // Recursively call API
	if (typeof catTitle === 'undefined') { // Grab next item in wikiProjectCategories
		catTitle = wikiProjectCategories.pop();
	}
	if (typeof catTitle === 'undefined') { // No remaining entries in wikiProjectCategories
		// Manually add Wikiprojects with /s in their title
		jQuery.extend( wikiprojects, fetchJSONList(templateIncludelistName) );
		writeList();
	} else {
		
		var query = {
			action: "query",
			list: "categorymembers",
			cmtitle: catTitle,
			cmtype: "page",
			cmnamespace: "10",
			cmlimit: "max",
			origin: '*'
		};
		console.log("Fetching contents of " + query.cmtitle + "...");
		if (cont) {
			query = Object.assign(query, cont);
		}
		api.get( query )
			.done (function (data) {
				if (data && data.query && data.query.categorymembers) { //API query returned members
					Object.entries(data.query.categorymembers).forEach( function(item) {
						var title = item[1].title.match(/^Template:WikiProject\s(.*)$/);
						if ( (title && title[1] && title[1] !== "") && ( title[1].indexOf("/") == -1 || title[1].match(/ task ?force$/i) ) ) { //Valid page name format
							title[1] = title[1].replace(/ task ?force$/i,"");
							if( !(templateBlockList[ title[1] ]) ) { //Not on blocklist
								wikiprojects[ title[1] ] = item[1].title.replace("Template:", "");
							}
						}
					} );
				}
				if (data && data.continue) { //More results are available
					getTemplatesFromCategories(catTitle, data.continue);
				} else {
					getTemplatesFromCategories();
				}
			} ).fail (function(error) {
				console.warn("Error getting list of templates:");
				console.log(error);
			} );
		return;
	}
}

function writeList() {
	wikiprojects = Object.keys(wikiprojects).sort().reduce(
		(obj, key) => { 
			obj[key] = wikiprojects[key]; 
			return obj;
		}, 
		{}
	);
	
	var params = {
		action: 'edit',
		title: templateList,
		text: JSON.stringify(wikiprojects),
		summary: "Update WikiProject list",
		watchlist:"unwatch"
	}
	console.log("Writing to " + params.title + "...");
	api.postWithToken("csrf", params ).done( function(reslt) {
		console.log(templateList + " updated:");
		console.log(reslt);
	} ).fail( function(reslt) {
		console.warn("Error updating " + templateList + ":");
		console.log(reslt);
	} );
}