Jump to content

User:RCSDevs/category.js

From Wikipedia, the free encyclopedia
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.
Array.prototype.includesAny = function(arrayToSearch)
{
	return this.some(function(element)
	{
        return arrayToSearch.indexOf(element) >= 0;
    });	
};

Date.prototype.getFormatted = function()
{
    var yyyy = this.getFullYear().toString(),
    	mm = (this.getMonth() + 101).toString().slice(-2),
    	dd = (this.getDate() + 100).toString().slice(-2);
    	
    return yyyy + mm + dd;
};

function requestPages(pages, params, callback)
{
	$.getJSON('https://en.wikipedia.org/w/api.php', params, function(json)
	{
		json.query.pages.forEach(function(page)
		{
			if(page.title && page.pageprops && page.pageprops.wikibase_item)
			{
				pages.push( { title: page.title, wikidataID: page.pageprops.wikibase_item } );
			}
		});
		
		if(json.continue && json.continue.gcmcontinue)
		{
			params.gcmcontinue = json.continue.gcmcontinue;
			requestPages(pages, params, callback);
		}
		else
		{
			callback();
		}
	});
}

function findPage(page)
{
	return this.id === page.wikidataID;
}

function getWikidataDescriptions(pages, pagesLeft, index, callback)
{
	if(pagesLeft > 0)
	{
		var titles = '';
		
		for(var i = 0; i < Math.min(pagesLeft, 50); i++)
		{
			titles += (pages[(index * 50) + i].title + '|');
		}
		
		titles = titles.slice(0, -1);
		var params = {
			'action': 'wbgetentities',
			'format': 'json',
			'formatversion': 2,
			'origin': 'https://en.wikipedia.org',
			'sites': 'enwiki',
			'titles': titles,
			'languages': 'en',
			'props': 'descriptions'
		};
		
		//This line increased efficiency from previous "complete" version by ~5000%? (well, a big percent with a '5' in it somewhere...)
		$.getJSON('https://www.wikidata.org/w/api.php', params, function(json)
		{
			//var arr = $.map(json.entities, function(value, index) { return [value]; });
			
			for(var key in json.entities) //I could map it to an array, but then I'd have to deal with shifting indicies due to page moves and redirects... so meh
			{
				if(json.entities.hasOwnProperty(key))
				{
					var item = json.entities[key];

					if(item.id && item.descriptions && item.descriptions.en)
					{
						pages.find(findPage, item).desc = item.descriptions.en.value.toLowerCase().replace(/[\[\(].*?[\]\)]/g, '').trim();
					}
				}
			}
			
			getWikidataDescriptions(pages, Math.max(0, pagesLeft - 50), index + 1, callback);
		});
	}
	else
	{
		callback();
	}
}

function getPageViews(pages, pagesComplete, dates, callback)
{
	if(pagesComplete < pages.length)
	{
		//AHHH WHY ISN'T THERE A BATCH REQUEST!!!!!!!!!!!!!
		$.getJSON('/media/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/' + pages[pagesComplete].title + '/daily/' + dates[1] + '/' + dates[0], function(json)
		{
			json.items.forEach(function(item)
			{
				pages[pagesComplete].views += item.views;
			});
			
			getPageViews(pages, pagesComplete + 1, dates, callback);
		});
	}
	else
	{
		callback();
	}
}

$(document).ready(function()
{
	var tab = $('#ca-nstab-category');
	
	if(tab.length && tab.attr('class') === 'selected')
	{
		var currentURL = decodeURIComponent(tab.find('span a').eq(0).attr('href')),
			title = currentURL.substring(currentURL.indexOf('/wiki/') + 6),
			categoryTitle = $('#Pages_in_category').parent().text().slice(19, -1),
			categoryWords = categoryTitle.toLowerCase().split(' '),
			pages = [];

		console.warn('Starting category fix. This will take some time, depending on the size of the category...');
		requestPages(pages,
		{
			'action': 'query',
			'format': 'json',
			'formatversion': 2,
			'generator': 'categorymembers',
			'gcmtitle': title,
			'gcmnamespace': 0,
			'gcmlimit': 'max',
			'gcmprop': 'title',
			'prop': 'pageprops',
			'ppprop': 'wikibase_item',
			'continue': ''
		},
		function()
		{
			pages = pages.filter(function(page) { return page.wikidataID !== undefined });
			getWikidataDescriptions(pages, pages.length, 0, function()
			{
				var dates = [], //(not the fruit)
					date = new Date();

				date.setDate(date.getDate() - 1);
				dates.push(date.getFormatted());
				date.setDate(date.getDate() - 7);
				dates.push(date.getFormatted());
				pages = pages.filter(function(page) { return page.desc && page.desc.split(' ').includesAny(categoryWords); });

				getPageViews(pages, 0, dates, function()
				{
					console.info("Sorting list by page view...");
					pages = pages.sort(function(pageA, pageB) { return pageB.views - pageA.views });
										
					console.info("Adding list to page...");
					$('.mw-category-generated').eq(0).prepend('<div id="mw-popularpages" style="clear: both"><h2>Popular pages in category "' + categoryTitle + '"</h2><p>The following ' + pages.length + ' pages are sorted by computer-predicted popularity.</p><div lang="en" dir="ltr" class="mw-content-ltr"><div class="mw-category"><ul id="pageSection"></ul></div></div></div>');
					$('#mw-pages').children().eq(0).text('').append('<span id="Pages_in_category"></span>Total pages in category "' + categoryTitle + '"');
				
					var list = $('#pageSection');
										
					pages.forEach(function(page)
					{
						list.append('<li><a href="/wiki/' + page.title + '" title="' + page.title + '">' + page.title + '</a></li>');
					});
				});
			});	
		});
	}
});