User:Habst/roadTo.js
let out = '{{mw-datatable}}\n==2024 Olympians==\n';
const eventId = '10229509';
const disciplineName = `Women's 100 Metres`;
window.cache ??= {};
window.q ??= {};
const getRoad = async (disciplineName, eventId) => {
return window.q[disciplineName] ??= await (await fetch("https://graphql-prod-4607.prod.aws.worldathletics.org/graphql", {
headers: { "x-api-key": "da2-xevhjbj7ybgcnjzrwiad2u6qqq" },
body: JSON.stringify({
operationName: "GetChampionshipQualifications",
variables: { competitionId: "7153115", eventId },
query: `query GetChampionshipQualifications($competitionId: Int!, $eventId: Int, $country: String, $qualificationType: String) {
getChampionshipQualifications(competitionId: $competitionId, eventId: $eventId, country: $country, qualificationType: $qualificationType) {
eventId
groupByCountry
entryNumber
entryStandard
alternativeEntryStandards {
entryStandard
event
__typename
}
disciplineName
maxCompetitorsByCoutnry
firstQualificationDay
lastQualificationDay
firstRankingDay
lastRankingDay
rankDate
numberOfCompetitorsQualifiedByEntryStandard
numberOfCompetitorsQualifiedByTopList
numberOfCompetitorsFilledUpByWorldRankings
numberOfCompetitorsQualifiedByUniversalityPlaces
numberOfCompetitorsQualifiedByDesignatedCompetition
qualifications {
qualifiedBy
qualified
qualificationPosition
countryPosition
name
urlSlug
iaafId
birthDate
competitorIaafId
result
wind
venue
date
countryCode
place
score
calculationId
label
__typename
}
events {
genderCode
eventId
disciplineName
__typename
}
countries {
shortname
name
__typename
}
qualificationTypes {
id
name
__typename
}
__typename
}
}`
}),
method: "POST",
})).json();
};
if (typeof nameFixer === 'undefined') {
const script = Object.assign(document.createElement('script'), { src: 'https://unpkg.com/name-fixer@1.0.0' });
document.body.appendChild(script);
await new Promise(res => script.addEventListener('load', res));
}
titleExists=async (name)=>{
const enLabelTitleMatch = await fetch(`https://xtools.wmcloud.org/api/page/articleinfo/en.wikipedia.org/${name.replace('|', '')}?format=json&uselang=en`);
return enLabelTitleMatch.status === 200;
}
getSuffix=async (name, evt, year) => {
const el = evt?.toLowerCase() ?? '';
const parens = evt?.includes('mH') || el.includes('metres hurdles') ? 'hurdler' : el.includes('high jump') ? 'high jumper' : el.includes('long jump') ? 'long jumper' : el.includes('pole vault') ? 'pole vaulter' : el.includes('triple jump') ? 'triple jumper' : el.includes('shot put') ? 'shot putter' : el.includes('discus') ? 'discus thrower' : el.includes('hammer') ? 'hammer thrower' : el.includes('javelin') ? 'javelin thrower' : el.includes('steeplchase') ? 'steeplechase runner' : el.includes('walk') ? 'racewalker' : el.includes('heptathlon') ? 'heptathlete' : el.includes('decathlon') ? 'decathlete' : ['60m', '60 m', '100m', '100 m', '200m', '200 m', '400m', '400 m'].some(d => el.includes(d)) ? 'sprinter' : 'runner';
name += ` (${parens})`;
if (await titleExists(name)) name = name.replace(`(${parens})`, `(${parens}, born ${year})`);
return name;
}
getTitle=async (id,name,evt,year)=>{
const words = name.split(' ');
const lnameStart = words.findIndex(w => w.toUpperCase() === w);
const fname = words.slice(0, lnameStart).join(' ');
const lname = words.slice(lnameStart).join(' ');
name = fname + ' ' + nameFixer.nameFixer(lname);
name = name.replace('LI', 'Li').replace('XI', 'Xi');
if (cache[id]) return cache[id];
const pages = await (await fetch('https://www.wikidata.org/w/api.php?' + new URLSearchParams({
action: 'query',
format: 'json',
list: 'search',
srsearch: `haswbstatement:P1146=${id}`,
}))).json();
const qid = pages.query.search[0]?.title;
if (qid) {
const entity = await (await fetch('https://www.wikidata.org/w/api.php?' + new URLSearchParams({
action: 'wbgetentities',
format: 'json',
ids: qid,
}))).json();
const sitelinks = entity.entities[qid].sitelinks;
const enTitle = sitelinks.enwiki?.title;
if (enTitle) {
cache[id] = `' : ''}`;
return cache[id];
}
let enLabel = entity.entities[qid].labels.en?.value ?? name;
const enLabelNoParens = enLabel;
if (await titleExists(enLabel)) enLabel = await getSuffix(enLabel, evt, year);
const otherWikis = Object.keys(sitelinks).filter(key => !key.startsWith('commons') && key.endsWith('wiki'));
if (otherWikis.length) {
const positionals = otherWikis.map(ow => `|${ow.replace('wiki', )}|${sitelinks[ow].title}`).join();
cache[id] = `{{ill|${enLabel}${positionals}${enLabel.includes('(') ? `|lt=${enLabelNoParens}` : ''}}}`;
return cache[id];
}
cache[id] = `{{ill|${enLabel}|qid=${qid}|s=1${enLabel.includes('(') ? `|lt=${enLabelNoParens}` : ''}}}`;
return cache[id];
}
if (await titleExists(name)) name = await getSuffix(name, evt, year);
cache[id] = `' : ''}`;
return cache[id];
}
await getRoad(disciplineName, eventId);
const ocq = q[disciplineName].data.getChampionshipQualifications;
for (const { disciplineName, eventId } of ocq.events) {
if (disciplineName.includes('Relay')) continue;
if (disciplineName.includes('Men')) continue;
await getRoad(disciplineName, eventId);
const cq = q[disciplineName].data.getChampionshipQualifications;
console.log(disciplineName);
const evt = disciplineName.split(' ').slice(1).join(' ');
out += `===${disciplineName}===\n
class="wikitable sortable mw-datatable"
|+ ${disciplineName} (${cq.entryNumber} spots; standard ${cq.entryStandard}) ! # !! Athlete !! Country !! WA !! Qualified By | ||||
\n`;
for (const aq of q[disciplineName].data.getChampionshipQualifications.qualifications) { let id = aq.urlSlug.split('-').at(-1); if (id.startsWith('0')) id = id.slice(1); const yob = aq.birthDate.split(' ').at(-1); const title = await getTitle(id, aq.name, evt, yob); out += `| ${aq.qualificationPosition ?? 'Alt'} | ${title} | {{flagg|cncie|${aq.countryCode}}} | [https://worldathletics.org/athletes/_/${id}] | ${aq.qualifiedBy}\n |
\n`;
} out += ' |
}
console.log(out);