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 res = dataBindings.map(item => {
      var keys = Object.keys(item);
+
    var keys = Object.keys(item);
      var obj = {};
+
    var obj = {};
      for(var i=0;i<keys.length;i++){
+
    for (var i = 0; i < keys.length; i++) {
          var key = keys[i],
+
      var key = keys[i],
              val = item[key].value;
+
        val = item[key].value;
          obj[key]=val;
+
      obj[key] = val;
      }
+
    }
      return obj  
+
    return obj
    });
+
  });
    return res;
+
  return res;
 
}
 
}
 
/* *************************************************************** */
 
/* *************************************************************** */
 
// Merge data by common property
 
// Merge data by common property
var merge2ArraysBySameId = function(arr1,arr2,id1){
+
var mergeTwoArraysById = function(arr1, arr2, id1) {
return arr1.map( item1 => {  
+
  return arr1.map(item1 => {
  var identical = arr2.find(obj => obj[id1] === item1[id1]);  
+
    var identical = arr2.find(obj => obj[id1] === item1[id1]) || '';
  return Object.assign(identical, item1)  
+
    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>${lang.label} (${lang.iso||lang.qid})</h2>
+
  languageLabel = lang.languageLabel,//
         <span>Recordings: ${lang.recordsF+lang.recordsM} (${lang.recordsF}|${lang.recordsM})</span>
+
    wikidata = lang.wikidata,  //
         <span>Speakers: ${lang.speakersF+lang.speakersM} (${lang.speakersF}|${lang.speakersM})</span>
+
    iso = lang.iso,//
         <span>Population: ${lang.population.toLocaleString()}</span>         
+
    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 ) {
+
  constructor(prefix, suffix) {
this.prefix = prefix || 'https://lingualibre.org/index.php?title=';
+
    this.prefix = prefix || 'https://lingualibre.org/index.php?title=';
this.suffix = suffix || '&action=raw&ctype=text/json';
+
    this.suffix = suffix || '&action=raw&ctype=text/json';
}
+
  }
page( page ) {
+
  page(page) {
page = encodeURIComponent( 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 = '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 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' };
+
    const headers = {
return fetch( fullUrl, { headers } ).then( response => response.text() )
+
      'Accept': 'text/javascript,text/json,text/xml,text/csv,application/javascript,application/json,application/xml,application/csv'
            .catch(function(err){ console.error(`Error in API call on ${page}:\n${err}`)});
+
    };
}
+
    return fetch(fullUrl, {
 +
        headers
 +
      }).then(response => response.text())
 +
      .catch(function(err) {
 +
        console.error(`Error in API call on ${page}:\n${err}`)
 +
      });
 +
  }
 
}
 
}
  
/* *************************************************************** */
 
/* DATA ********************************************************** */
 
// Sources
 
var sources = [
 
    { page: 'LanguagesGalleryData.js'},
 
    { page: 'LanguagesSpeakersData.js'}, /*
 
    { page: 'LanguageSpeakersFemaleData.js'},
 
    { page: 'LanguageSpeakersMaleData.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 resources (json data)
 
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));
 
 
// Note: When all the expected objects are in stored, then the dataviz code is ran.
 
  
 
/* *************************************************************** */
 
/* *************************************************************** */
Line 120: Line 117:
 
*/
 
*/
  
//Temporary fake data, clean:
+
/* *************************************************************** */
const languages = [{ qid: 'Q209', label: 'Breton', iso:'bre' }, { qid: 'Q21', label: 'French', iso: 'fra' }],
+
/* DATA ********************************************************** */
    speakersFemales = [{ qid: 'Q209', speakersF: 3, recordsF: 60 }, { qid: 'Q21', speakersF: 21, recordsF:15046 }],
+
// Sources
    speakersMales = [{ qid: 'Q209', speakersM: 7, recordsM: 112 }, { qid: 'Q21', speakersM: 85, recordsM:82964 }],
+
var sources = [
     natives = [{ qid: 'Q209', population: 300000 }, { qid: 'Q21', population:80000000 }];
+
  { 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));
  
// Mergings
+
// Note: When all the expected objects are stored, then the dataviz code is ran.
var merge1 = merge2ArraysBySameId(languages,speakersFemales,'qid');
 
var merge2 = merge2ArraysBySameId(merge1,speakersMales,'qid');
 
var final = merge2ArraysBySameId(merge2,natives,'qid');
 
console.log(JSON.stringify(final))
 
  
  
 
/* *************************************************************** */
 
/* *************************************************************** */
/* INJECTIONS **************************************************** */
+
/* MAIN RUN ****************************************************** */
var _10k = final.filter(item => item.recordsF+item.recordsM > 9999);
+
var waitDataThenFire = setInterval(function() {
console.log('_10k: ', _10k)
+
  console.log('ping');
_10k.forEach(item => $('#lg-10k').append(tpl(item)) )
+
  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')
  
var _1k = final.filter(item => item.recordsF+item.recordsM > 999 && item.recordsF+item.recordsM <10000);
 
console.log('_1k: ', _1k)
 
_1k.forEach(item => $('#lg-1k').append(tpl(item)) )
 
  
var _1 = final.filter(item => item.recordsF+item.recordsM > 0 && item.recordsF+item.recordsM <1000);
+
    console.log(datas);
console.log('_1: ', _1)
+
    console.log(final);
_1.forEach(item => $('#lg-1').append(tpl(item)) )
+
    //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);
  
/* *************************************************************** */
 
/* 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){
 
    // pings
 
    console.log(pings);
 
    // Data merging
 
var final = merge2ArraysBySameId(datas[sources[0].page],datas[sources[1].page],'wikidata'),
 
final = merge2ArraysBySameId(final,datas[sources[2].page],'wikidata');
 
//var merge2 = merge2ArraysBySameId(merge1,speakersMales,'qid');
 
//var final = merge2ArraysBySameId(merge2,natives,'qid');
 
    console.log(JSON.stringify(datas));
 
console.log(JSON.stringify(final))
 
//Dataviz
 
    console.log('run dataviz');
 
    clearInterval(waitDataThenFire);
 
    }
 
  }, 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