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();
});
});