User:Habst/matchWdWa.js

window.wd ??= {}; window.wa ??= {}; window.wp ??= {}; window.redirs ??= {};

const wdEdit = async (qid, prop, val, cmt, refs = [], rank = 'normal') => { return await (await fetch(`https://www.wikidata.org/w/rest.php/wikibase/v0/entities/items/${qid}/statements`, { headers: { 'Content-type': 'application/json' }, method: 'POST', body: JSON.stringify({     statement: {        rank,        property: { id: prop },        value: { type: 'value', content: val },        qualifiers: [], references: refs,      },      tags: [], bot: false,      comment: cmt,    }), })).json; }; wikiJsonP = async (props) => { let wpResult; window.cb = res => wpResult = res; const script = Object.assign(document.createElement('script'), {   src: 'https://en.wikipedia.org/w/api.php?' + new URLSearchParams({ action: 'query', format: 'json', callback: 'cb', ...props, }) });  document.body.appendChild(script); await new Promise(res => script.addEventListener('load', res)); return wpResult; }; makeWaDate = dt => { const words = dt.toLocaleString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', timeZone: 'UTC' }).toUpperCase.split(' '); words.splice(1, 1, words.at(1).slice(0, 3)); return words.join(' '); } normalize = s => s.replaceAll('_', ' ').replaceAll('-', ' ').split('(')[0].normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase.trim;

for (const p of ps['*'][0].a['*']) { if (p.waid) continue; const name = normalize(p.title); console.log(name, p.q); wd[p.q] ??= await (await fetch(`https://www.wikidata.org/wiki/Special:EntityData/${p.q}.json`)).json; let dobs = wd[p.q].entities[p.q].claims.P569?.map(c => ({ v: new Date(c.mainsnak.datavalue.value.time.replace('+', '').split('T')[0]), precision: c.mainsnak.datavalue.value.precision, })).filter(dob => dob.precision == 11).map(d => makeWaDate(d.v)) ?? []; redirs[p.q] ??= await wikiJsonP({ prop: 'redirects', generator: 'redirects', formatversion: '2', titles: p.title }); const aliases = wd[p.q].entities[p.q].aliases.en?.map(a => normalize(a.value)) ?? []; aliases.push(...(redirs[p.q].query?.pages.map(pg => normalize(pg.title)) ?? []));

if (!dobs.length) { //console.log('no dobs', `https://en.wikipedia.org/wiki/${p.title}`);

wp[p.title] ??= await wikiJsonP({ prop: 'extracts', exchars: '1000', titles: p.title });

const ex = Object.values(wp[p.title].query.pages)[0].extract; const born = ex.replace(' in ', ')').match(/\(born ([^)]+)\)/)?.[1]; if (born && born.split(' ').length === 3) { const dt = new Date(born); if (!p.addedDob) await wdEdit(p.q, 'P569', { time: `+${dt.toLocaleDateString('sv')}T00:00:00Z`, precision: 11, calendarmodel: 'http://www.wikidata.org/entity/Q1985727' }, 'Adding date of birth from enwiki', [{ parts: [{       property: { id: 'P143' },        value: { type: 'value', content: 'Q328' },      }] }], 'preferred'); p.addedDob = true; dobs = [makeWaDate(dt)]; } else { console.log('no dob, no born in lede'); continue; } }  wa[name] ??= await (await fetch("https://graphql-prod-4607.prod.aws.worldathletics.org/graphql", { headers: { "x-api-key": "da2-xevhjbj7ybgcnjzrwiad2u6qqq" }, // intentionally public body: JSON.stringify({     operationName: "SearchCompetitors",      variables: { query: name },      query: `query SearchCompetitors($query: String, $gender: GenderType, $disciplineCode: String, $environment: String, $countryCode: String) {  searchCompetitors(query: $query, gender: $gender, disciplineCode: $disciplineCode, environment: $environment, countryCode: $countryCode) {    aaAthleteId    familyName    givenName    birthDate    disciplines    iaafId    gender    country    urlSlug    __typename  } }`    }), method: "POST", })).json; let matchingName; const easternOrder = ['CHN', 'TPE', 'KOR']; const matches = wa[name].data.searchCompetitors.filter(sc => {   if (!sc.birthDate) return false;    const waNames = [normalize(`${sc.givenName} ${sc.familyName}`)];    if (easternOrder.includes(sc.country)) waNames.push(normalize(`${sc.familyName} ${sc.givenName}`));    const nameMatch = [name, ...aliases].find(n => waNames.includes(n));    if (nameMatch) {      if (dobs.some(dob => sc.birthDate === dob || sc.birthDate === dob.split(' ').at(-1))) {        // allow matching year        matchingName = nameMatch;        return true;      }    }    return false;  }); if (!matches.length) { console.log('no matches'); continue; } if (matches.length > 1) { console.log('many matches'); continue; } console.log('*** found match', matches[0].aaAthleteId); await wdEdit(p.q, 'P1146', matches[0].aaAthleteId, `Adding World Athletics ID with matching name (${matchingName}) and date of birth`); p.waid = matches[0].aaAthleteId; } const todos = ps['*'][0].a['*'].filter(p => !p.waid).map(p => `* ${p.title}`); console.log(todos.length); todos.join('\n');