MediaWiki
Difference between revisions of "LanguagesGallery.js"
m |
m |
||
(12 intermediate revisions by the same user not shown) | |||
Line 7: | Line 7: | ||
// Documentations: | // Documentations: | ||
// Author: Yug | // Author: Yug | ||
− | + | ||
/* *************************************************************** */ | /* *************************************************************** */ | ||
/* TOOLS ********************************************************* */ | /* TOOLS ********************************************************* */ | ||
/* *************************************************************** */ | /* *************************************************************** */ | ||
// Clean data | // Clean data | ||
− | var cleanResponseDataBindings = function(dataBindings){ | + | var cleanResponseDataBindings = function(dataBindings) { |
− | + | var res = dataBindings.map(item => { | |
− | + | var keys = Object.keys(item); | |
− | + | var obj = {}; | |
− | + | for (var i = 0; i < keys.length; i++) { | |
− | + | var key = keys[i], | |
− | + | val = item[key].value; | |
− | + | obj[key] = val; | |
− | + | } | |
− | + | return obj | |
− | + | }); | |
− | + | return res; | |
} | } | ||
/* *************************************************************** */ | /* *************************************************************** */ | ||
// Merge data by common property | // Merge data by common property | ||
− | var | + | var mergeTwoArraysById = function(arr1, arr2, id1) { |
− | + | return arr1.map(item1 => { | |
− | + | var identical = arr2.find(obj => obj[id1] === item1[id1]) || ''; | |
− | + | return identical ? Object.assign(identical, item1): item1; | |
− | } ); | + | }); |
} | } | ||
Line 44: | Line 44: | ||
// Template | // Template | ||
− | var tpl = function(lang){ | + | var tpl = function(lang) { |
− | return `<div> | + | var language = lang.language.split('entity/')[1], |
− | <h2>${ | + | languageLabel = lang.languageLabel,// |
− | <span>Recordings: ${ | + | wikidata = lang.wikidata, // |
− | <span> | + | iso = lang.iso,// |
− | <span>Population: ${ | + | wiki = lang.wiki, |
+ | records = Number(lang.records), | ||
+ | words = Number(lang.words).toLocaleString(), | ||
+ | speakers = Number(lang.speakers), | ||
+ | //speakersMales = Number(lang.speakersMales), | ||
+ | //speakersOthers = Number(lang.speakersOthers), | ||
+ | malesSpeakers = Number(lang.malesSpeakers || 0), | ||
+ | femalesSpeakers = Number(lang.femalesSpeakers || 0), | ||
+ | othersSpeakers = speakers - (malesSpeakers + femalesSpeakers), | ||
+ | malesRecords = Number(lang.malesRecords || 0), | ||
+ | femalesRecords = Number(lang.femalesRecords || 0), | ||
+ | othersRecords = records - (malesRecords + femalesRecords), | ||
+ | percentFemalesRecords = Number(femalesSpeakers/speakers), | ||
+ | population = Number(lang.population || 'n.a.'), | ||
+ | populationQualifier = lang.populationQualifier; | ||
+ | |||
+ | return `<div> | ||
+ | <h2>${languageLabel} (${iso||language})</h2> | ||
+ | <span>Recordings: ${records.toLocaleString()} (f:${femalesRecords||0}|m:${malesRecords||0}${othersRecords?'|o:'+othersRecords:''})</span> | ||
+ | <span>Voices: ${speakers.toLocaleString()} (f:${femalesSpeakers||0}|m:${malesSpeakers||0}${othersSpeakers?'|o:'+othersSpeakers:''})</span> | ||
+ | <span>Population: ${population.toLocaleString()}</span> | ||
<div>` | <div>` | ||
} | } | ||
− | |||
Line 59: | Line 78: | ||
// CREATES CLASS for API fetching, returns text to decode and parse | // CREATES CLASS for API fetching, returns text to decode and parse | ||
class apiContentFetcher { | class apiContentFetcher { | ||
− | + | constructor(prefix, suffix) { | |
− | + | this.prefix = prefix || 'https://lingualibre.org/index.php?title='; | |
− | + | this.suffix = suffix || '&action=raw&ctype=text/json'; | |
− | + | } | |
− | + | page(page) { | |
− | + | page = encodeURIComponent(page); | |
− | + | //const fullUrl = 'https://lingualibre.org/api.php?action=query&list=users&ususers=yug&usprop=groups|editcount|registration&format=json&origin=*'; | |
− | + | const fullUrl = this.prefix + page + this.suffix + '&origin=*'; | |
− | + | const headers = { | |
− | + | 'Accept': 'text/javascript,text/json,text/xml,text/csv,application/javascript,application/json,application/xml,application/csv' | |
− | + | }; | |
− | + | return fetch(fullUrl, { | |
+ | headers | ||
+ | }).then(response => response.text()) | ||
+ | .catch(function(err) { | ||
+ | console.error(`Error in API call on ${page}:\n${err}`) | ||
+ | }); | ||
+ | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
/* *************************************************************** */ | /* *************************************************************** */ | ||
Line 120: | Line 117: | ||
*/ | */ | ||
− | // | + | /* *************************************************************** */ |
− | + | /* DATA ********************************************************** */ | |
− | + | // Sources | |
− | + | var sources = [ | |
− | + | { page: 'LanguagesRecordsData.js' }, | |
+ | { page: 'LanguagesGenderData.js' }, | ||
+ | { page: 'LanguagesSpeakersData.js' }, | ||
+ | { page: 'LanguagesPopulationData.js' } | ||
+ | ]; | ||
+ | var datas = {}; // final object containing consolidated result | ||
+ | var pings = []; | ||
+ | var removeJsComments = function(text) { | ||
+ | return text.replace(/\n*(\/\*.+)+(\n.+)+\*\/(\n)*/g, '') | ||
+ | } | ||
+ | var storeData = function(store, key, text) { | ||
+ | console.log(`Response text from ${key}: ${text}`); | ||
+ | console.log(`Without comments ${key}: ${removeJsComments(text)}`); | ||
+ | store[key] = JSON.parse(removeJsComments(text)); | ||
+ | }; | ||
+ | // Fetch json resources, store into var `datas={}` | ||
+ | const rawPageFetcher = new apiContentFetcher(); | ||
+ | rawPageFetcher.page('MediaWiki:' + sources[0].page) | ||
+ | .then(d => storeData(datas, sources[0].page, d)); | ||
+ | rawPageFetcher.page('MediaWiki:' + sources[1].page) | ||
+ | .then(d => storeData(datas, sources[1].page, d)); | ||
+ | rawPageFetcher.page('MediaWiki:' + sources[2].page) | ||
+ | .then(d => storeData(datas, sources[2].page, d)); | ||
+ | rawPageFetcher.page('MediaWiki:' + sources[3].page) | ||
+ | .then(d => storeData(datas, sources[3].page, d)); | ||
− | // | + | // Note: When all the expected objects are stored, then the dataviz code is ran. |
− | |||
− | |||
− | |||
− | |||
/* *************************************************************** */ | /* *************************************************************** */ | ||
− | /* | + | /* MAIN RUN ****************************************************** */ |
− | var | + | var waitDataThenFire = setInterval(function() { |
− | console.log(' | + | console.log('ping'); |
− | + | pings.push('pong'); | |
+ | console.log(datas) | ||
+ | if (Object.keys(datas).length == sources.length || pings.length == 20) { | ||
+ | clearInterval(waitDataThenFire); | ||
+ | // pings | ||
+ | console.log(pings); | ||
+ | // Data merging | ||
+ | var final = datas[sources[0].page]; | ||
+ | final = mergeTwoArraysById(final, datas[sources[1].page], 'wikidata') | ||
+ | final = mergeTwoArraysById(final, datas[sources[2].page], 'wikidata') | ||
+ | final = mergeTwoArraysById(final, datas[sources[3].page], 'wikidata') | ||
− | |||
− | |||
− | |||
− | + | console.log(datas); | |
− | console.log( | + | console.log(final); |
− | + | //Dataviz | |
+ | console.log('run dataviz'); | ||
+ | /* *************************************************************** */ | ||
+ | /* INJECTIONS **************************************************** */ | ||
+ | var injection = function(consolidatedData, min, max, htmlHook) { | ||
+ | // | ||
+ | }; | ||
+ | var _10k = final.filter(item => item.records > 9999 && item.records < 10000000); | ||
+ | var _1k = final.filter(item => item.records > 999 && item.records < 10000); | ||
+ | var _1 = final.filter(item => item.records > 0 && item.records < 1000); | ||
+ | console.log('_10k: ', _10k) | ||
+ | console.log('_1k: ', _1k) | ||
+ | console.log('_1: ', _1) | ||
+ | _10k.forEach(item => $('#lg-10k').append(tpl(item))) | ||
+ | _1k.forEach(item => $('#lg-1k').append(tpl(item))) | ||
+ | _1.forEach(item => $('#lg-1').append(tpl(item))) | ||
+ | |||
+ | } | ||
+ | }, 500); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
/* *************************************************************** */ | /* *************************************************************** */ | ||
/* PAGE INTERACTIONS ********************************************* */ | /* PAGE INTERACTIONS ********************************************* */ | ||
// Show more/less cards for this section | // Show more/less cards for this section | ||
// Show more/less infor overall | // Show more/less infor overall |
Latest revision as of 17:26, 25 January 2022
/* *************************************************************** */
/* LanguageGallery script **************************************** */
// Description: given json data provided in MediaWiki pages, merge those data, project language cards.
// Usage: [[Template:LanguagesGallery]]
// Usage: open [[Template:LanguagesGallery]] > Open, loads > Click for more.
// Hack pad:https://jsfiddle.net/hugolpz/vnz238xq/
// Documentations:
// Author: Yug
/* *************************************************************** */
/* TOOLS ********************************************************* */
/* *************************************************************** */
// Clean data
var cleanResponseDataBindings = function(dataBindings) {
var res = dataBindings.map(item => {
var keys = Object.keys(item);
var obj = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i],
val = item[key].value;
obj[key] = val;
}
return obj
});
return res;
}
/* *************************************************************** */
// Merge data by common property
var mergeTwoArraysById = function(arr1, arr2, id1) {
return arr1.map(item1 => {
var identical = arr2.find(obj => obj[id1] === item1[id1]) || '';
return identical ? Object.assign(identical, item1): item1;
});
}
/* *************************************************************** */
// SORT ?
/* *************************************************************** */
/* HTML TEMPLATE ************************************************* */
// Beautity numbers
//console.log(10000.toLocaleString()); // "10,000"
// Template
var tpl = function(lang) {
var language = lang.language.split('entity/')[1],
languageLabel = lang.languageLabel,//
wikidata = lang.wikidata, //
iso = lang.iso,//
wiki = lang.wiki,
records = Number(lang.records),
words = Number(lang.words).toLocaleString(),
speakers = Number(lang.speakers),
//speakersMales = Number(lang.speakersMales),
//speakersOthers = Number(lang.speakersOthers),
malesSpeakers = Number(lang.malesSpeakers || 0),
femalesSpeakers = Number(lang.femalesSpeakers || 0),
othersSpeakers = speakers - (malesSpeakers + femalesSpeakers),
malesRecords = Number(lang.malesRecords || 0),
femalesRecords = Number(lang.femalesRecords || 0),
othersRecords = records - (malesRecords + femalesRecords),
percentFemalesRecords = Number(femalesSpeakers/speakers),
population = Number(lang.population || 'n.a.'),
populationQualifier = lang.populationQualifier;
return `<div>
<h2>${languageLabel} (${iso||language})</h2>
<span>Recordings: ${records.toLocaleString()} (f:${femalesRecords||0}|m:${malesRecords||0}${othersRecords?'|o:'+othersRecords:''})</span>
<span>Voices: ${speakers.toLocaleString()} (f:${femalesSpeakers||0}|m:${malesSpeakers||0}${othersSpeakers?'|o:'+othersSpeakers:''})</span>
<span>Population: ${population.toLocaleString()}</span>
<div>`
}
/* *************************************************************** */
// Native Javascript
// CREATES CLASS for API fetching, returns text to decode and parse
class apiContentFetcher {
constructor(prefix, suffix) {
this.prefix = prefix || 'https://lingualibre.org/index.php?title=';
this.suffix = suffix || '&action=raw&ctype=text/json';
}
page(page) {
page = encodeURIComponent(page);
//const fullUrl = 'https://lingualibre.org/api.php?action=query&list=users&ususers=yug&usprop=groups|editcount|registration&format=json&origin=*';
const fullUrl = this.prefix + page + this.suffix + '&origin=*';
const headers = {
'Accept': 'text/javascript,text/json,text/xml,text/csv,application/javascript,application/json,application/xml,application/csv'
};
return fetch(fullUrl, {
headers
}).then(response => response.text())
.catch(function(err) {
console.error(`Error in API call on ${page}:\n${err}`)
});
}
}
/* *************************************************************** */
/* ALTERNATIVE FETCH ******************************************** * /
// Note: I used the class creation above to learn it, but alternatives below work too.
// Native Javascript (on mediawiki : works)
var url = 'https://lingualibre.org/api.php?action=query&list=users&ususers=yug&usprop=groups|editcount|registration&format=json&origin=*';
fetch(url)
.then(d=> d.json())
.then(d=> storeData(d,'Fetchy 1') )
.catch(function(err){ console.error('Error in API call, fetch 1: '+err);
});
// JQuery Javascript (on mediawiki: not tested)
$.getJSON(url,
{ format: 'json', origin: '*' },
function(data){ console.log('JQuery: ',data)}
);
*/
/* *************************************************************** */
/* DATA ********************************************************** */
// Sources
var sources = [
{ page: 'LanguagesRecordsData.js' },
{ page: 'LanguagesGenderData.js' },
{ page: 'LanguagesSpeakersData.js' },
{ page: 'LanguagesPopulationData.js' }
];
var datas = {}; // final object containing consolidated result
var pings = [];
var removeJsComments = function(text) {
return text.replace(/\n*(\/\*.+)+(\n.+)+\*\/(\n)*/g, '')
}
var storeData = function(store, key, text) {
console.log(`Response text from ${key}: ${text}`);
console.log(`Without comments ${key}: ${removeJsComments(text)}`);
store[key] = JSON.parse(removeJsComments(text));
};
// Fetch json resources, store into var `datas={}`
const rawPageFetcher = new apiContentFetcher();
rawPageFetcher.page('MediaWiki:' + sources[0].page)
.then(d => storeData(datas, sources[0].page, d));
rawPageFetcher.page('MediaWiki:' + sources[1].page)
.then(d => storeData(datas, sources[1].page, d));
rawPageFetcher.page('MediaWiki:' + sources[2].page)
.then(d => storeData(datas, sources[2].page, d));
rawPageFetcher.page('MediaWiki:' + sources[3].page)
.then(d => storeData(datas, sources[3].page, d));
// Note: When all the expected objects are stored, then the dataviz code is ran.
/* *************************************************************** */
/* MAIN RUN ****************************************************** */
var waitDataThenFire = setInterval(function() {
console.log('ping');
pings.push('pong');
console.log(datas)
if (Object.keys(datas).length == sources.length || pings.length == 20) {
clearInterval(waitDataThenFire);
// pings
console.log(pings);
// Data merging
var final = datas[sources[0].page];
final = mergeTwoArraysById(final, datas[sources[1].page], 'wikidata')
final = mergeTwoArraysById(final, datas[sources[2].page], 'wikidata')
final = mergeTwoArraysById(final, datas[sources[3].page], 'wikidata')
console.log(datas);
console.log(final);
//Dataviz
console.log('run dataviz');
/* *************************************************************** */
/* INJECTIONS **************************************************** */
var injection = function(consolidatedData, min, max, htmlHook) {
//
};
var _10k = final.filter(item => item.records > 9999 && item.records < 10000000);
var _1k = final.filter(item => item.records > 999 && item.records < 10000);
var _1 = final.filter(item => item.records > 0 && item.records < 1000);
console.log('_10k: ', _10k)
console.log('_1k: ', _1k)
console.log('_1: ', _1)
_10k.forEach(item => $('#lg-10k').append(tpl(item)))
_1k.forEach(item => $('#lg-1k').append(tpl(item)))
_1.forEach(item => $('#lg-1').append(tpl(item)))
}
}, 500);
/* *************************************************************** */
/* PAGE INTERACTIONS ********************************************* */
// Show more/less cards for this section
// Show more/less infor overall