MediaWiki

Sparql2data.js

Revision as of 16:17, 20 January 2022 by Yug (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* ************************************************************************** */
/* Sparql2data script ******************************************* */
// Description: given a sparql query,a wikipage, a sparql enpoints, a format, will formatt the data on that wikipage.
// Usage: [[Template:Sparql2data]]
// Usage: open [[Template:Sparql2data]] > fill the form > click "Fectch data", review if it looks normal, then click "Update data !"
// Hack pad: https://jsfiddle.net/hugolpz/x4qmcudj/
// Documentations:  https://www.mediawiki.org/wiki/API:Edit#MediaWiki_JS
// Author: Yug
 
/* ********************************************************************** */
/* OOJS / OOUI ********************************************************** */
// Data & options
var formatArray = [
    { data: 'json', label: 'json' },
    { data: 'xml', label: 'xml' },/*
    { data: 'csv', label: 'csv' },
    { data: 'tsv', label: 'tsv' }, */
  ].map(o => new OO.ui.MenuOptionWidget({ data: o.data, label: o.label })),
  endpointsArray = [
    { data: 'https://lingualibre.org/sparql', label: 'LinguaLibre'},
    { data: 'https://query.wikidata.org/sparql', label: 'Wikidata'},
  ];

// Elements
var wikipage = new OO.ui.TextInputWidget({
  id: 's2d-wikipage',
  icon: 'specialPages',
  placeholder: 'MediaWiki:*.js',
  value: 'MediaWiki:SandboxData.js',
      label: 'Data hosting page',
}),
format = new OO.ui.DropdownWidget( {
  id: 's2d-format',
  icon: 'code',
      label: 'Data format',
      menu: { items: formatArray }
  }),
endpoints = new OO.ui.RadioSelectInputWidget( { 
  id: 's2d-endpoints',
    label: 'Radios buttons',
  options: endpointsArray,
} ),
limit = new OO.ui.CheckboxInputWidget({ id: 's2d-limit', selected: true, }),
limitLabel = new OO.ui.LabelWidget( { label: 'Limit to 100 (faster)' }),
queryDisplay = new OO.ui.MultilineTextInputWidget( { 
  id: 's2d-queryDisplay',
      //value: `# Query will appear here.\n\n\n\n\n\n`,
  placeholder: `# SPARQL query here.\n\n\n\n\n\n`,
  value: `SELECT ?item ?itemLabel WHERE {
SERVICE wikibase:label {
  bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" .
} 
?item prop:P2 entity:Q5
} `,
      multiline: true,
      autosize: true,
  minRows: 10,
      maxRows: 20
  } ),
fetchData = new OO.ui.ButtonWidget({ 
    id: 's2d-fetchData', 
  label: 'Fetch data',
}),
dataDisplay = new OO.ui.MultilineTextInputWidget( { 
  id: 's2d-dataDisplay',
  placeholder: `# Data will appear here after a while.\n\n\n\n\n\n`,
      multiline: true,
      autosize: true,
  minRows: 10,
      maxRows: 20
  } ),
postData = new OO.ui.ButtonWidget({ 
  id: 's2d-postData',
  label:'Save data !',
}),
clean = new OO.ui.CheckboxInputWidget({ id: 's2d-clean', selected: false, }),
cleanLabel = new OO.ui.LabelWidget( { label: 'Clean it' }),
prettify = new OO.ui.CheckboxInputWidget({ id: 's2d-prettify', selected: true, }),
prettifyLabel = new OO.ui.LabelWidget( { label: 'Prettify it' });

// An example of a fieldset with horizontal layout.
var fieldset = new OO.ui.FieldsetLayout( {
      label: "Save SPARQL results"
  } );
fieldset.addItems( [ 
new OO.ui.FieldLayout(
  new OO.ui.Widget( {
    content: [ 
      new OO.ui.HorizontalLayout( { items: [
        wikipage,
        format,
      ]}),
      new OO.ui.HorizontalLayout( { items: [
          queryDisplay,
      ]}),
      new OO.ui.HorizontalLayout( { items: [
        fetchData,
        limit,
        limitLabel,
        endpoints,
      ]}),
      new OO.ui.HorizontalLayout( { items: [ 
        dataDisplay,
      ]}),
      new OO.ui.HorizontalLayout( { items: [ 
        postData,
        clean,
        cleanLabel,
        prettify,
        prettifyLabel,
      ]}),
    ]
  }),{
          label: 'Given one heavy SPARQL query, save its responded raw data into a target wikipage.',
          align: 'top'
      })
  ]
);
$( "#s2d" ).html( fieldset.$element );

// Check data
var checkAvailableData = function(identity,element){
  // console.log('2',languages)
  console.log(identity+'a getElementId(): ',element.getElementId())
  console.log(identity+'b getData(): ',element.getData())
  console.log(identity+'c getValue(): ',element.getValue())
}

$('#s2d-wikipage').on('focusout',function() {checkAvailableData(1,wikipage);})


/* ********************************************************************** */
/* SPARQL QUERIES & WIKI EDIT ******************************************* */
// 
//var endpoint = 'https://lingualibre.org/sparql';
//var sparql = 'SELECT ?item WHERE { ?item prop:P2 entity:Q5 } LIMIT 10';
//var format = 'json';
//var wikipage = 'MediaWiki:Mydata.js';

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

var sparql2data = function(sparql,endpoint,responseFormat) {
  console.log(sparql,endpoint,responseFormat)
  responseFormat = responseFormat || 'json';
  endpoint = endpoint || 'https://lingualibre.org/sparql';
  console.log({ 
      "SPARQL endpoint: ":endpoint,
      "Response format requested: ": responseFormat,
      "SPARQL query: ":`${sparql}`})
  $.getJSON(
      endpoint,
      { query: sparql, format: responseFormat },
      function(data){ 
             console.log("SPARQL query's response: ",data);
          // Inject query
          dataDisplay.setValue(JSON.stringify(data.results.bindings));
      }
  );
}

var data2wikipage = function(data, wikipage, sparql) {
    sparql = sparql || '';
    // String to object + optional clean
    var response = clean.isSelected()? 
        cleanResponseDataBindings(JSON.parse(data))
        :JSON.parse(data);
    // object to string + optional prettify
    response = prettify.isSelected() ?
        JSON.stringify(response, null, 2)
        : JSON.stringify(response);

    var content = `
/* **************
${sparql}
************** */
${response}`
  var params = {
          action: 'edit',
          title: wikipage.replace(/^.+\:/,'MediaWiki:'), // Namespace to MediaWiki:
          text: content,
          format: 'json'
      },
  api = new mw.Api();
  api.postWithToken( 'csrf', params )
      .done( function ( data ) { console.log('d2w: ', data ); } );
}


/* ********************************************************************** */
/* FETCHDATA QUERY STRING ************************************************ */
// getData from elements
var fetchQuery = function () {
 // getData from elements
 var selectedDropdown = function (group){
  var items = group.getMenu().items.filter(item=> item.selected===true );
  return items[0]?items[0].data:null;
 }
 var selectedRadio = function (group){
  var items = group.getMenu().items.filter(item=> item.selected===true );
  return items[0]?items[0].data:null;
 }
 var form = {
     wikipage: wikipage.getValue(),	//string
     format: selectedDropdown(format),	//string of value
     //formatLabel: qid2value(formatArray,selectedDropdown(format)),	//noun
     limit: limit.isSelected(),	//boolean
     endpoint: endpoints.getValue(),	// url
     sparql: queryDisplay.getValue(),	//string
 };
     dataDisplay.setValue('');
  sparql2data(form.sparql,form.endpoint,form.format); 
}

var setLimit = function () {
  var query = queryDisplay.getValue()
      .replace(`\nLIMIT 100`,'')
      .concat(limit.isSelected()?`\nLIMIT 100`:'');
  queryDisplay.setValue(query);
}

/* ********************************************************************** */
/* OPENS EXTERNAL QUERY SERVICE ***************************************** */
// Current: Wikidata, Dbnary. Broken: lingualibre.
var postQuery = function () {
  var data = dataDisplay.getValue();
  var targetPage = wikipage.getValue();
  var sparql = queryDisplay.getValue();
  //var queryEncoded = encodeURIComponent(queryText);
 if (dataDisplay) {
         data2wikipage(data, targetPage, sparql);
    // window.open(baseEndpointUrl.concat(queryEncoded), '_blank');
 }
}
$('#s2d-limit').on('click',function(){ setLimit(); });
$('#s2d-fetchData').on('click',function(){ fetchQuery(); });
$('#s2d-postData').on('click',function(){ postQuery(); });