Jump to content

User:RCSDevs/category.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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>');
					});
				});
			});	
		});
	}
});