User:Gary/automatic article lead image.js

// AUTOMATIC ARTICLE LEAD IMAGE

//

// Description: Adds a lead image to biographies that don't have lead images.

$(() => {

// Check if ran.

if (window.autoLeadImage) {

return;

}

// Set running.

window.autoLeadImage = true;

// This API key is IP-restricted, so this script won't work for other people.

const googleApiKey = 'AIzaSyBuXFJn7vNI1JYqe1GQx2i-JhH4sI7JGKk';

// eslint-disable-next-line complexity

function init() {

const enableAutomaticLeadImage = () => {

if (

window.mw.config.get('wgCanonicalNamespace') === '' &&

window.mw.config.get('wgAction') === 'view' &&

window.mw.util.getParamValue('disable') !== 'leadimage'

) {

return true;

}

return false;

};

const isPrintable = Boolean(window.location.href.match(/&printable=yes/));

if (!enableAutomaticLeadImage() || isPrintable) {

return false;

}

let isAPerson = false;

// eslint-disable-next-line no-restricted-syntax

for (const category of window.mw.config.get('wgCategories')) {

const cat = category.replace(/_/g, ' ');

if (

cat.indexOf('Living people') === 0 ||

cat.indexOf(' births') !== -1 ||

cat.indexOf(' deaths') !== -1

) {

isAPerson = true;

break;

}

}

if (!isAPerson || findLeadImages() === 1) {

return false;

}

const personName = window.mw.config.get('wgTitle');

const url =

`https://www.googleapis.com/customsearch/v1?q=${personName}` +

'&cx=004227430873773175363:j7_jwozfw80&imgType=face&num=1&' +

`searchType=image&key=${googleApiKey}`;

// Get the search results.

return $.get(url, (json) => {

// Get the first item's info.

const imageTitle = json.items[0].title;

const imageLink = json.items[0].link;

const imageThumbnail = json.items[0].image.thumbnailLink;

// If image does not exist, then show the Google-cached thumbnail instead.

return $.ajax({

url: imageLink,

error: () => imageResults([imageTitle, imageThumbnail]),

success: () => imageResults([imageTitle, imageLink]),

});

// We failed to get an image, so just show a placeholder.

}).fail(() =>

imageResults([

'Example',

'https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png',

]),

);

}

// eslint-disable-next-line complexity, max-statements

function imageResults(results) {

let addAfter;

let colSpan;

let jumpToNav;

let newNode;

let newNodeDiv;

let parentNode;

const defaultLeadImageSize = 200;

// The title of the infobox, if there is one.

const fn = $('.fn').first();

const infobox = findLeadImages();

const imageUrl = decodeURI(results[1]);

// there is no infobox and no lead image

if (infobox === -1) {

// insert an image after the "difference" box

if ($('#difference').length) {

jumpToNav = $('#diffHeading').next();

// insert an image into the lead

} else {

jumpToNav = $('.mw-content-ltr:eq(0)')

.children()

.first();

// eslint-disable-next-line max-depth

if (jumpToNav[0].nodeName !== 'P') {

jumpToNav = jumpToNav.nextAll('p').first();

}

}

// everything else after here has parentNode as a TR

// in the infobox, there is no name formatted with microformats

} else if (!fn.length) {

parentNode = infobox

.children()

.first()

.children()

.first();

colSpan = parentNode

.children()

.first()

.attr('colspan');

addAfter = parentNode;

// there is a name formatted with microformats, in either TH or TD

} else if (fn[0].nodeName === 'TH' || fn[0].nodeName === 'TD') {

parentNode = fn.parent();

colSpan = fn.attr('colspan');

addAfter = parentNode;

// there is a name formatted with microformats, in a CAPTION

} else if (fn[0].nodeName === 'CAPTION') {

parentNode = fn

.siblings()

.last()

.children()

.first();

colSpan = parentNode

.children()

.first()

.attr('colspan');

addAfter = parentNode.prev();

if (colSpan <= 1) {

colSpan = 2;

}

// similar to the above, but it is the parent node

} else if (fn.parent()[0].nodeName === 'CAPTION') {

const table = fn.closest('table');

parentNode = table.find('tr').first();

colSpan = table

.find('th')

.first()

.attr('colspan');

addAfter = $();

// standard infobox with no microformats

} else {

parentNode = fn.parent().parent();

if (parentNode[0].nodeName !== 'TR') {

parentNode = parentNode.parent();

}

colSpan = fn.parent().attr('colspan');

addAfter = parentNode;

}

const newNodeImage = $(

`${</p>
<p>results[0]</p>
<p>}`,

);

const newNodePreLink = $('From ');

const newNodeLink = $(

`Google Images`,

);

// there is no infobox and no lead image

if (infobox === -1) {

const imagePath =

'http://bits.wikimedia.org/skins-1.5/common/images/magnify-clip.png';

const magnify = $(

'

`,

);

const newNodeCaption = $('

')

.append(magnify)

.append(newNodePreLink)

.append(newNodeLink);

newNodeImage.addClass('thumbimage');

newNodeDiv = $(

`

`,

)

.append(newNodeImage)

.append(newNodeCaption);

newNode = $('

').append(newNodeDiv);

return jumpToNav.before(newNode);

// there is an infobox with no image

}

const newNodeSpan = $('')

.append(newNodePreLink)

.append(newNodeLink);

newNodeDiv = $('

')

.append(newNodeImage)

.append('
')

.append(newNodeSpan);

const newNodeChild = $(

``,

).append(newNodeDiv);

newNode = $('').append(newNodeChild);

if (addAfter.length) {

return addAfter.after(newNode);

}

return parentNode.before(newNode);

}

// eslint-disable-next-line complexity

function findLeadImages() {

const defaultImageNames = [

'File:Replace_this_image_male.svg',

'File:Replace_this_image_female.svg',

];

const infoboxes = $('.infobox');

const tocColors = $('.toccolours');

let infoboxImages = false;

// get images in infoboxes

if (infoboxes.length) {

const $images = $('.image', infoboxes.first());

// Remove default images.

$images.each((index, element) => {

const $image = $(element);

if (defaultImageNames.indexOf($image.attr('href')) > -1) {

$image.remove();

}

});

// Running this again because we may have removed some images.

infoboxImages = $('.image', infoboxes.first());

} else if (tocColors.length) {

infoboxImages = $('.image', tocColors.first());

}

// there is more than one image in infoboxes

if (infoboxImages.length) {

return 1;

}

// there is an infobox with no image

if (infoboxImages.length === 0) {

return infoboxes.first();

}

// There are no infoboxes. Check if we are viewing a diff first

let node;

if ($('table.diff').length) {

node = $('h2.diff-currentversion-title:eq(0)').next();

} else {

node = $('.mw-content-ltr:eq(0)')

.children()

.first();

}

while (

node.length &&

node.attr('id') !== 'section-1' &&

!node.hasClass('printfooter')

) {

// there is a lead image

if (

(node[0].nodeName === 'P' || node[0].nodeName === 'DIV') &&

(node

.children()

.first()

.hasClass('image') ||

(node.children().eq(1) &&

node

.children()

.first()

.hasClass('thumbinner')))

) {

return 1;

}

node = node.next();

}

// there are no lead images

return -1;

}

init();

});