User:Edgars2007/tokyo2020.js

var api;

var category = '';

var stopThis = false;

const mapping = {

'Archery': 'Category:Archers at the 2024 Summer Olympics',

'Athletics': 'Category:Athletes (track and field) at the 2024 Summer Olympics',

'Badminton': 'Category:Badminton players at the 2024 Summer Olympics',

'Basketball': 'Category:Basketball players at the 2024 Summer Olympics',

'Breaking': 'Category:Breakdancers at the 2024 Summer Olympics',

'Beach volleyball': 'Category:Beach volleyball players at the 2024 Summer Olympics',

'Boxing': 'Category:Boxers at the 2024 Summer Olympics',

'Canoeing': 'Category:Canoeists at the 2024 Summer Olympics',

'Cycling': 'Category:Cyclists at the 2024 Summer Olympics',

'Diving': 'Category:Divers at the 2024 Summer Olympics',

'Equestrian': 'Category:Equestrians at the 2024 Summer Olympics',

'Fencing': 'Category:Fencers at the 2024 Summer Olympics',

'Field hockey': 'Category:Field hockey players at the 2024 Summer Olympics',

'Football': 'Category:Footballers at the 2024 Summer Olympics',

'Golf': 'Category:Golfers at the 2024 Summer Olympics',

'Gymnastics': 'Category:Gymnasts at the 2024 Summer Olympics',

'Handball': 'Category:Handball players at the 2024 Summer Olympics',

'Judo': 'Category:Judoka at the 2024 Summer Olympics',

'Modern pentathlon': 'Category:Modern pentathletes at the 2024 Summer Olympics',

'Rowing': 'Category:Rowers at the 2024 Summer Olympics',

'Sailing': 'Category:Sailors at the 2024 Summer Olympics',

'Shooting': 'Category:Shooters at the 2024 Summer Olympics',

'Swimming': 'Category:Swimmers at the 2024 Summer Olympics',

'Artistic swimming': 'Category:Artistic swimmers at the 2024 Summer Olympics',

'Table tennis': 'Category:Table tennis players at the 2024 Summer Olympics',

'Taekwondo': 'Category:Taekwondo practitioners at the 2024 Summer Olympics',

'Tennis': 'Category:Tennis players at the 2024 Summer Olympics',

'Triathlon': 'Category:Triathletes at the 2024 Summer Olympics',

'Volleyball': 'Category:Volleyball players at the 2024 Summer Olympics',

'Water polo': 'Category:Water polo players at the 2024 Summer Olympics',

'Weightlifting': 'Category:Weightlifters at the 2024 Summer Olympics',

'Wrestling': 'Category:Wrestlers at the 2024 Summer Olympics',

'Rugby sevens': 'Category:Rugby sevens players at the 2024 Summer Olympics',

'Surfing': 'Category:Surfers at the 2024 Summer Olympics',

'Skateboarding': 'Category:Skateboarders at the 2024 Summer Olympics',

'Baseball': 'Category:Baseball players at the 2024 Summer Olympics',

'Karate': 'Category:Karateka at the 2024 Summer Olympics',

'Softball': 'Category:Softball players at the 2024 Summer Olympics',

'Sport climbing': 'Category:Sport climbers at the 2024 Summer Olympics',

};

const addCategory = (wikitext, category) => {

if (wikitext.includes(category)) {

return null;

}

const re = /\[\Cc]ategory\s*:\s*[^\+\]\]/g;

let m;

let lastMatch;

while ((m = re.exec(wikitext))) {

lastMatch = m[0];

}

// console.log('lastMatch', lastMatch)

if (!lastMatch) {

return `${wikitext}${category}`;

}

return wikitext.replace(lastMatch, `${lastMatch}\n${category}`);

};

const handleRedirects = (titles) => {

return api

.get({

formatversion: 2,

titles: titles,

redirects: true,

})

.then(function (data) {

const { redirects } = data.query;

let mapping = {};

redirects.forEach((entry) => {

const { from, to } = entry;

mapping[from] = to;

});

return mapping;

});

};

const getCategoryMembers = (category, cmContinue = null) => {

if (stopThis) {

return;

}

let params = {

list: 'categorymembers',

redirects: 1,

formatversion: '2',

cmtitle: category,

cmnamespace: '0',

cmlimit: '500',

};

if (cmContinue) {

params = {

...params,

...cmContinue,

};

}

console.log('MADE API', params);

return api.get(params).then(function (data) {

return data;

});

};

const handleMembers = async (category) => {

let flag = true;

let cmContinue;

const pageResults = [];

let counter = 0;

while (flag) {

counter++;

if (counter === 15) {

alert('Too many API requests, maybe something is broken');

}

const resp = await getCategoryMembers(category, cmContinue);

if ('continue' in resp) {

cmContinue = resp.continue;

} else {

flag = false;

}

console.log(resp);

const currpages = resp.query.categorymembers.map((entry) => entry.title);

pageResults.push(...currpages);

}

console.log(pageResults);

return pageResults;

};

const getCategoryMembers_OLD = (category) => {

return api

.get({

list: 'categorymembers',

redirects: 1,

formatversion: '2',

cmtitle: category,

cmnamespace: '0',

cmlimit: '5',

})

.then(function (data) {

console.log(data);

const { categorymembers } = data.query;

return categorymembers.map((entry) => entry.title);

});

};

const getData = async (category, redirects) => {

const members = await handleMembers(category);

const redirs = redirects.length > 0 ? await handleRedirects(redirects) : {};

return {

members,

redirects: redirs,

};

};

const handlePageEdit = (ev) => {

const element = ev.target;

const canonical = element.getAttribute('data-canonical');

console.log(element, canonical);

new mw.Api()

.edit(canonical, function (revision) {

const newText = addCategory(revision.content, category);

if (!newText) {

return Promise.reject('ALREADY');

}

return {

text: newText,

summary: `add ${category}`,

minor: true,

};

})

.then(function () {

console.log('Saved!');

var allButtons = document.getElementsByClassName('add-cat');

[...allButtons].forEach((btn) => {

const currCanonical = btn.getAttribute('data-canonical');

if (currCanonical === canonical) {

btn.parentNode.removeChild(btn);

}

});

});

};

const checker = (pageData, pageLinks) => {

const { members, redirects } = pageData;

console.log({ members, redirects });

for (const link of pageLinks) {

const href = link.getAttribute('href');

if (!href || !href.startsWith('/wiki/')) {

continue;

}

const title = decodeURIComponent(href.replaceAll('/wiki/', '').replaceAll('_', ' '));

if (title?.endsWith(' at the 2024 Summer Olympics')) {

continue;

}

const canonicalTitle = redirects[title] ?? title;

const included = members.includes(canonicalTitle);

// console.log(title, included)

if (!included) {

// link.setAttribute("data-canonical", canonicalTitle);

link.outerHTML += ` `;

}

}

};

function init() {

api = new mw.Api({

ajax: {

// Use a user agent, so that sysadmins can find you and tell you to fix your tool

headers: { 'Api-User-Agent': 'w:en:User:Edgars2007/tokyo2020.js' },

},

});

var allLinks = document.getElementsByTagName('a');

var redirects = [].filter

.call(allLinks, (el) => el.classList.contains('mw-redirect'))

.map((element) => decodeURIComponent(element.getAttribute('href').replaceAll('/wiki/', '')));

var redirectNames = [...new Set(redirects)];

console.log(redirectNames);

getData(category, redirectNames).then((resp) => checker(resp, allLinks));

$(document).on('click', '.add-cat', (event) => {

handlePageEdit(event);

});

}

const getCompetitorsName = () => {

const pagetitle = mw.config.get('wgPageName').replace('_', ' ');

Object.keys(mapping).forEach(title => {

if (pagetitle.startsWith(title)) {

category = mapping[title];

return;

}

})

}

// mw.loader.using(['mediawiki.api', 'mediawiki.util'], init);

mw.loader.using(['mediawiki.api', 'mediawiki.util'], async () => {

mw.util.addPortletLink('p-cactions', '#', 'tokyo', 'ca-tokyo', 'Add participation category to articles', '5');

$(document).on('click', '#ca-tokyo', () => {

getCompetitorsName();

//category = prompt('Set category name');

init();

});

});