MediaWiki

Difference between revisions of "Sparql2data.js"

(Created page with "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....")
 
m
 
(17 intermediate revisions by the same user not shown)
Line 1: Line 1:
var endpoint = 'https://lingualibre.org/sparql';
+
/* ************************************************************************** */
var sparql = 'SELECT ?item WHERE { ?item prop:P2 entity:Q5 } LIMIT 10';
+
/* Sparql2data script ******************************************* */
var format = 'json';
+
// Description: given a sparql query,a wikipage, a sparql enpoints, a format, will formatt the data on that wikipage.
var wikipage = 'MediaWiki:Mydata.js';
+
// 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' });
  
var data2wikipage = function(data,wikipage) {
+
// An example of a fieldset with horizontal layout.
     var params = {
+
var fieldset = new OO.ui.FieldsetLayout( {
            action: 'edit',
+
      label: "Save SPARQL results"
            title: wikipage,
+
  } );
            text: "Yug test!",
+
fieldset.addItems( [
            format: 'json'
+
new OO.ui.FieldLayout(
         },
+
  new OO.ui.Widget( {
     api = new mw.Api();
+
     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 );
  
    api.postWithToken( 'csrf', params ).done( function ( data ) {
+
// Check data
        console.log( 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())
 
}
 
}
  
var sparql2data = async function(sparql, wikipage, format, endpoint) {
+
$('#s2d-wikipage').on('focusout',function() {checkAvailableData(1,wikipage);})
wikipage = wikipage || 'Sandbox';
+
 
format = format || 'json';
+
 
    endpoint = endpoint || 'https://lingualibre.org/sparql';
+
/* ********************************************************************** */
    var res = await $.getJSON(endpoint,
+
/* SPARQL QUERIES & WIKI EDIT ******************************************* */
        { query: sparql, format: format },
+
//
        function(data, wikipage){  
+
//var endpoint = 'https://lingualibre.org/sparql';
        console.log('JQuery: ',data)
+
//var sparql = 'SELECT ?item WHERE { ?item prop:P2 entity:Q5 } LIMIT 10';
        data2wikipage(data,wikipage);
+
//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(); });

Latest revision as of 16:17, 20 January 2022

/* ************************************************************************** */
/* 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(); });