MediaWiki

Difference between revisions of "Sparql2data.js"

m
m
 
(10 intermediate revisions by the same user not shown)
Line 12: Line 12:
 
// Data & options
 
// Data & options
 
var formatArray = [
 
var formatArray = [
      { data: 'json', label: 'json' },
+
    { data: 'json', label: 'json' },
      { data: 'xml', label: 'xml' },
+
    { data: 'xml', label: 'xml' },/*
      { data: 'csv', label: 'csv' },
+
    { data: 'csv', label: 'csv' },
      { data: 'tsv', label: 'tsv' },
+
    { data: 'tsv', label: 'tsv' }, */
    ].map(o => new OO.ui.MenuOptionWidget({ data: o.data, label: o.label })),
+
  ].map(o => new OO.ui.MenuOptionWidget({ data: o.data, label: o.label })),
    endpointsArray = [
+
  endpointsArray = [
      { data: 'https://lingualibre.org/sparql', label: 'LinguaLibre'},
+
    { data: 'https://lingualibre.org/sparql', label: 'LinguaLibre'},
      { data: 'https://query.wikidata.org/sparql', label: 'Wikidata'},
+
    { data: 'https://query.wikidata.org/sparql', label: 'Wikidata'},
    ];
+
  ];
  
 
// Elements
 
// Elements
 
var wikipage = new OO.ui.TextInputWidget({
 
var wikipage = new OO.ui.TextInputWidget({
    id: 's2d-wikipage',
+
  id: 's2d-wikipage',
    icon: 'specialPages',
+
  icon: 'specialPages',
    placeholder: 'Sandbox',
+
  placeholder: 'MediaWiki:*.js',
    value: 'Sandbox',
+
  value: 'MediaWiki:SandboxData.js',
label: 'Data hosting page',
+
      label: 'Data hosting page',
 +
}),
 +
format = new OO.ui.DropdownWidget( {
 +
  id: 's2d-format',
 +
  icon: 'code',
 +
      label: 'Data format',
 +
      menu: { items: formatArray }
 
   }),
 
   }),
  format = new OO.ui.DropdownWidget( {
+
endpoints = new OO.ui.RadioSelectInputWidget( {  
    id: 's2d-format',
+
  id: 's2d-endpoints',
    icon: 'code',
+
    label: 'Radios buttons',
label: 'Data format',
+
  options: endpointsArray,
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, }),
+
limit = new OO.ui.CheckboxInputWidget({ id: 's2d-limit', selected: true, }),
  limitLabel = new OO.ui.LabelWidget( { label: 'Limit to 100 (faster)' }),
+
limitLabel = new OO.ui.LabelWidget( { label: 'Limit to 100 (faster)' }),
  queryDisplay = new OO.ui.MultilineTextInputWidget( {  
+
queryDisplay = new OO.ui.MultilineTextInputWidget( {  
    id: 's2d-queryDisplay',
+
  id: 's2d-queryDisplay',
//value: `# Query will appear here.\n\n\n\n\n\n`,
+
      //value: `# Query will appear here.\n\n\n\n\n\n`,
    placeholder: `# SPARQL query here.\n\n\n\n\n\n`,
+
  placeholder: `# SPARQL query here.\n\n\n\n\n\n`,
    value: `SELECT ?item ?itemLabel WHERE {
+
  value: `SELECT ?item ?itemLabel WHERE {
  SERVICE wikibase:label {
+
SERVICE wikibase:label {
    bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" .
+
  bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" .
  }  
+
}  
  ?item prop:P2 entity:Q5
+
?item prop:P2 entity:Q5
 
} `,
 
} `,
multiline: true,
+
      multiline: true,
autosize: true,
+
      autosize: true,
    minRows: 10,
+
  minRows: 10,
maxRows: 20
+
      maxRows: 20
} ),
+
  } ),
  fetchData = new OO.ui.ButtonWidget({  
+
fetchData = new OO.ui.ButtonWidget({  
  id: 's2d-fetchData',  
+
    id: 's2d-fetchData',  
    label: 'Fetch data',
+
  label: 'Fetch data',
  }),
+
}),
  dataDisplay = new OO.ui.MultilineTextInputWidget( {  
+
dataDisplay = new OO.ui.MultilineTextInputWidget( {  
    id: 's2d-dataDisplay',
+
  id: 's2d-dataDisplay',
    placeholder: `# Data will appear here after a while.\n\n\n\n\n\n`,
+
  placeholder: `# Data will appear here after a while.\n\n\n\n\n\n`,
multiline: true,
+
      multiline: true,
autosize: true,
+
      autosize: true,
    minRows: 10,
+
  minRows: 10,
maxRows: 20
+
      maxRows: 20
} ),
+
  } ),
  postData = new OO.ui.ButtonWidget({  
+
postData = new OO.ui.ButtonWidget({  
    id: 's2d-postData',
+
  id: 's2d-postData',
    label:'Update data !',
+
  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.
 
// An example of a fieldset with horizontal layout.
 
var fieldset = new OO.ui.FieldsetLayout( {
 
var fieldset = new OO.ui.FieldsetLayout( {
label: 'Sparql to stored data tool'
+
      label: "Save SPARQL results"
} );
+
  } );
 
fieldset.addItems( [  
 
fieldset.addItems( [  
  new OO.ui.FieldLayout(
+
new OO.ui.FieldLayout(
    new OO.ui.Widget( {
+
  new OO.ui.Widget( {
      content: [  
+
    content: [  
        new OO.ui.HorizontalLayout( { items: [
+
      new OO.ui.HorizontalLayout( { items: [
          wikipage,
+
        wikipage,
          format,
+
        format,
        ]}),
+
      ]}),
        new OO.ui.HorizontalLayout( { items: [
+
      new OO.ui.HorizontalLayout( { items: [
        queryDisplay,
+
          queryDisplay,
        ]}),
+
      ]}),
        new OO.ui.HorizontalLayout( { items: [
+
      new OO.ui.HorizontalLayout( { items: [
          fetchData,
+
        fetchData,
          limit,
+
        limit,
          limitLabel,
+
        limitLabel,
          endpoints,
+
        endpoints,
        ]}),
+
      ]}),
      new OO.ui.HorizontalLayout( { items: [  
+
      new OO.ui.HorizontalLayout( { items: [  
        dataDisplay,
+
        dataDisplay,
        ]}),
+
      ]}),
      new OO.ui.HorizontalLayout( { items: [  
+
      new OO.ui.HorizontalLayout( { items: [  
        postData,
+
        postData,
      ]}),
+
        clean,
      ]
+
        cleanLabel,
    }),{
+
        prettify,
label: 'Based on heavy SPARQL query, update the raw data of the target wikipage',
+
        prettifyLabel,
align: 'top'
+
      ]}),
})
+
    ]
]
+
  }),{
 +
          label: 'Given one heavy SPARQL query, save its responded raw data into a target wikipage.',
 +
          align: 'top'
 +
      })
 +
  ]
 
);
 
);
 
$( "#s2d" ).html( fieldset.$element );
 
$( "#s2d" ).html( fieldset.$element );
Line 113: Line 121:
 
// Check data
 
// Check data
 
var checkAvailableData = function(identity,element){
 
var checkAvailableData = function(identity,element){
// console.log('2',languages)
+
  // console.log('2',languages)
console.log(identity+'a getElementId(): ',element.getElementId())
+
  console.log(identity+'a getElementId(): ',element.getElementId())
console.log(identity+'b getData(): ',element.getData())
+
  console.log(identity+'b getData(): ',element.getData())
    console.log(identity+'c getValue(): ',element.getValue())
+
  console.log(identity+'c getValue(): ',element.getValue())
 
}
 
}
  
Line 131: Line 139:
  
 
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;
 
}
 
}
  
 
var sparql2data = function(sparql,endpoint,responseFormat) {
 
var sparql2data = function(sparql,endpoint,responseFormat) {
    console.log(sparql,endpoint,responseFormat)
+
  console.log(sparql,endpoint,responseFormat)
    responseFormat = responseFormat || 'json';
+
  responseFormat = responseFormat || 'json';
    endpoint = endpoint || 'https://lingualibre.org/sparql';
+
  endpoint = endpoint || 'https://lingualibre.org/sparql';
    console.log({  
+
  console.log({  
        "SPARQL endpoint: ":endpoint,
+
      "SPARQL endpoint: ":endpoint,
        "Response format requested: ": responseFormat,
+
      "Response format requested: ": responseFormat,
        "SPARQL query: ":`${sparql}`})
+
      "SPARQL query: ":`${sparql}`})
    $.getJSON(
+
  $.getJSON(
        endpoint,
+
      endpoint,
        { query: sparql, format: responseFormat },
+
      { query: sparql, format: responseFormat },
        function(data){  
+
      function(data){  
      console.log("SPARQL query's response: ",data);
+
            console.log("SPARQL query's response: ",data);
        // Inject query
+
          // Inject query
        dataDisplay.setValue(JSON.stringify(data.results.bindings));
+
          dataDisplay.setValue(JSON.stringify(data.results.bindings));
    }
+
      }
    );
+
  );
 
}
 
}
  
var data2wikipage = function(data, wikipage) {
+
var data2wikipage = function(data, wikipage, sparql) {
     var params = {
+
     sparql = sparql || '';
            action: 'edit',
+
    // String to object + optional clean
            title: wikipage,
+
    var response = clean.isSelected()?
            text: data,
+
        cleanResponseDataBindings(JSON.parse(data))
            format: 'json'
+
        :JSON.parse(data);
        },
+
    // object to string + optional prettify
    api = new mw.Api();
+
    response = prettify.isSelected() ?
    api.postWithToken( 'csrf', params )
+
        JSON.stringify(response, null, 2)
    .done( function ( data ) { console.log('d2w: ', data ); } );
+
        : 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 ); } );
 
}
 
}
  
Line 179: Line 202:
 
// getData from elements
 
// getData from elements
 
var fetchQuery = function () {
 
var fetchQuery = function () {
  // getData from elements
+
// getData from elements
  var selectedDropdown = function (group){
+
var selectedDropdown = function (group){
    var items = group.getMenu().items.filter(item=> item.selected==true )
+
  var items = group.getMenu().items.filter(item=> item.selected===true );
    return items[0]?items[0].data:null;
+
  return items[0]?items[0].data:null;
  }
+
}
  var selectedRadio = function (group){
+
var selectedRadio = function (group){
    var items = group.getMenu().items.filter(item=> item.selected==true )
+
  var items = group.getMenu().items.filter(item=> item.selected===true );
    return items[0]?items[0].data:null;
+
  return items[0]?items[0].data:null;
  }
+
}
  var form = {
+
var form = {
      wikipage: wikipage.getValue(), //string
+
    wikipage: wikipage.getValue(), //string
      format: selectedDropdown(format), //string of value
+
    format: selectedDropdown(format), //string of value
      //formatLabel: qid2value(formatArray,selectedDropdown(format)), //noun
+
    //formatLabel: qid2value(formatArray,selectedDropdown(format)), //noun
      limit: limit.isSelected(), //boolean
+
    limit: limit.isSelected(), //boolean
      endpoint: endpoints.getValue(), // url
+
    endpoint: endpoints.getValue(), // url
      sparql: queryDisplay.getValue(), //string
+
    sparql: queryDisplay.getValue(), //string
  };
+
};
  dataDisplay.setValue('');
+
    dataDisplay.setValue('');
    sparql2data(form.sparql,form.endpoint,form.format);  
+
  sparql2data(form.sparql,form.endpoint,form.format);  
 
}
 
}
  
 
var setLimit = function () {
 
var setLimit = function () {
    var query = queryDisplay.getValue()
+
  var query = queryDisplay.getValue()
    .replace(`\nLIMIT 100`,'')
+
      .replace(`\nLIMIT 100`,'')
    .concat(limit.isSelected()?`\nLIMIT 100`:'');
+
      .concat(limit.isSelected()?`\nLIMIT 100`:'');
    queryDisplay.setValue(query);
+
  queryDisplay.setValue(query);
 
}
 
}
  
Line 211: Line 234:
 
// Current: Wikidata, Dbnary. Broken: lingualibre.
 
// Current: Wikidata, Dbnary. Broken: lingualibre.
 
var postQuery = function () {
 
var postQuery = function () {
var data = dataDisplay.getValue();
+
  var data = dataDisplay.getValue();
    var targetPage = wikipage.getValue();
+
  var targetPage = wikipage.getValue();
    //var queryEncoded = encodeURIComponent(queryText);
+
  var sparql = queryDisplay.getValue();
  if (dataDisplay) {
+
  //var queryEncoded = encodeURIComponent(queryText);
  data2wikipage(data, targetPage);
+
if (dataDisplay) {
      // window.open(baseEndpointUrl.concat(queryEncoded), '_blank');
+
        data2wikipage(data, targetPage, sparql);
  }
+
    // window.open(baseEndpointUrl.concat(queryEncoded), '_blank');
 
  }
 
  }
$('#s2d-limit').on('click',function(){ setLimit(); });
+
}
$('#s2d-fetchData').on('click',function(){ fetchQuery(); });
+
$('#s2d-limit').on('click',function(){ setLimit(); });
$('#s2d-postData').on('click',function(){ postQuery(); });
+
$('#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(); });