User:Ingenuity/NeedingImprovement.js

const allWikiprojects = {}; const allColors = [ "#ff2424", "#ff8e24", "#d1d100", "#5c9e00", "#26b000", "#04b09c", "#005bd1", "#3d00bf", "#a000c4", "#6a00ff" ]; let currentColor = 0; let parsedData = []; const selectedProjects = []; const settings = { minQuality: 0, maxQuality: Infinity, minViews: 0, maxViews: Infinity };

let suggestedProjects, selectedProjectsDiv, tableDiv;

function maxSplit(str, max) { const split = str.split(" "); const first = split.slice(0, max); const last = split.slice(max);

return [...first, last.join(" ")]; }

function parseData(data) { const lines = data .split("\n") .filter(e => e.length > 2) .map(e => maxSplit(e, 3)) .filter(e => e.length === 4); lines.forEach(e => {			e[3]				.split(",")				.forEach(proj => { proj = proj.toLowerCase; if (!(proj in allWikiprojects) && proj.length > 0) { allWikiprojects[proj] = [ allColors[currentColor], 0 ]; currentColor = (currentColor + 1) % allColors.length; }

if (proj.length > 0) { allWikiprojects[proj][1] += 1; }				});		});

return lines; }

function renderSelectedPages(pages, container, limit=100) { container.innerHTML = ""; let allHTML = ` ";	container.innerHTML = allHTML; }

function findProjectsMatching(str) { const matchingProjects = Object.keys(allWikiprojects).filter(e => e.toLowerCase.includes(str.toLowerCase)); return matchingProjects; }

function matchingPages { return parsedData.filter(page => {		let matchesAll = true;		for (let proj of selectedProjects) {			if (!page[3].toLowerCase.includes(proj.replaceAll("_", " "))) {				matchesAll = false;				break;			}		}		if (page[1] < settings.minQuality || page[1] > settings.maxQuality) {			matchesAll = false;		}		if (page[2] * 30 < settings.minViews || page[2] * 30 > settings.maxViews) {			matchesAll = false;		}		return matchesAll;	}); }

function addProject(project) { project = project.replaceAll(" ", "_"); if (selectedProjects.includes(project)) { selectedProjects.splice(selectedProjects.indexOf(project), 1); } else { selectedProjects.push(project); }

selectedProjectsDiv.innerHTML = selectedProjects.map(e => `		${e.replaceAll("_", " ")} 	`).join(" "); renderSelectedPages(matchingPages, tableDiv); }

async function getPageContent(title) { const api = new mw.Api; const data = await api.get({		"action": "query",		"prop": "revisions",		"titles": title,		"rvslots": "*",		"rvprop": "content"	}); const page = Object.values(data.query.pages)[0]; return page.revisions[0].slots.main["*"]; }

function applyViews { const minViews = document.getElementById("minViews").value; const maxViews = document.getElementById("maxViews").value;

settings.minViews = minViews.length > 0 ? Number(minViews) : 0; settings.maxViews = maxViews.length > 0 ? Number(maxViews) : Infinity;

renderSelectedPages(matchingPages, tableDiv); }

function applyQuality { const minQuality = document.getElementById("minQuality").value; const maxQuality = document.getElementById("maxQuality").value;

settings.minQuality = minQuality.length > 0 ? Number(minQuality) : 0; settings.maxQuality = maxQuality.length > 0 ? Number(maxQuality) : Infinity;

renderSelectedPages(matchingPages, tableDiv); }

async function runNeedingImprovement { const body = document.getElementById("bodyContent");

const pagesToFetch = [ "000", "001", "002", "003", "004", "005", "006", "007", "008", "009",		"010", "011", "012", "013", "014", "015", "016", "017", "018", "019",		"020", "021", "022", "023", "024", "025", "026", "027", "028", "029",		"030", "031", "032", "033", "034", "035", "036", "037", "038", "039",		"040", "041", "042", "043", "044", "045", "046", "047", "048", "049",		"050", "051", "052", "053", "054", "055", "056", "057", "058", "059",		"060", "061", "062", "063", "064", "065", "066", "067", "068", "069",		"070", "071", "072", "073", "074", "075", "076", "077", "078", "079",		"080", "081", "082", "083", "084", "085", "086", "087", "088", "089",		"090", "091", "092", "093", "094", "095", "096", "097", "098", "099",	];	body.innerHTML = "Loading... ";

let numComplete = 0; const allData = []; for (let page of pagesToFetch) { allData.push(await getPageContent(`User:Ingenuity/ArticleData/${page}.txt`)); document.getElementById("complete").innerText = `${++numComplete} / ${pagesToFetch.length}`; }	parsedData = parseData(allData.join("\n"));

document.head.innerHTML += ` .wikiproject { padding: 2px 7px; border-radius: 5px; color: white; display: inline-block; margin: 3px 2px; }			td, th { padding: 5px; background: #eee; min-width: 100px; max-width: 800px; }			th { text-align: left; background: #ddd; }			#suggestedProjects, #selectedProjects { margin-top: 10px; white-space: nowrap; overflow-x: auto; }

#selectedProjects { margin: 0 !important; }			input { display: block; padding: 5px 10px; margin-top: 5px; outline: none !important; width: 250px; }

.titleHelp { cursor: help; text-decoration: dotted underline; }

.smallInput { width: 75px; }

.filterSection { margin: 5px; background: #eee; padding: 10px; }

.applyButton { margin-top: 5px; padding: 5px 10px; cursor: pointer; }	`;	body.innerHTML = ` Select projects:  Min. quality  Apply Max. quality  Min. views  Apply Max. views  Selected projects: `;

suggestedProjects = document.getElementById("suggestedProjects"); selectedProjectsDiv = document.getElementById("selectedProjects"); tableDiv = document.getElementById("tableDiv"); const input = document.getElementById("wikiprojectInput"); input.addEventListener("keyup", => {		const matches = findProjectsMatching(input.value)			.sort((a, b) => allWikiprojects[b][1] - allWikiprojects[a][1]);		window.inputval = input.value;		suggestedProjects.innerHTML = "";		for (const match of matches.splice(0, 10)) {			suggestedProjects.innerHTML += `				${match.replaceAll("_", " ")} 			`;		}	}); }

if (mw.config.values.wgPageName === "Special:BlankPage/NeedingImprovement") { runNeedingImprovement; } else { addPortletLink(		"p-tb",		`/wiki/Special:BlankPage/NeedingImprovement`,		"Needing improvement",		"ca-needing-improvement",		"Needing improvement",		"n"	); }