User
Difference between revisions of "Nicolas NALLET/bluell.js"
< User:Nicolas NALLET
(vrsion de Seb35) |
(nouvelle version avec restriction des sélecteurs) |
||
Line 10: | Line 10: | ||
mw.loader.using( ['oojs', 'oojs-ui'], function () { | mw.loader.using( ['oojs', 'oojs-ui'], function () { | ||
− | var | + | var oouiSelectors = { |
+ | 'speaker': null, | ||
+ | 'gender': null, | ||
+ | 'language': null, | ||
+ | 'proficiency': null, | ||
+ | }; | ||
+ | var sparqlGlobal = { | ||
+ | 'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel', | ||
+ | 'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender', | ||
+ | 'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel', | ||
+ | 'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency', | ||
+ | }; | ||
+ | var placeholders = { | ||
+ | 'speaker': '👤 Speaker', | ||
+ | 'gender': '♀️ ♂️ Speaker\'s gender', | ||
+ | 'language': '🏳️ Language', | ||
+ | 'proficiency': '🥇 Level of proficiency', | ||
+ | }; | ||
+ | var htmlElements = { | ||
+ | 'speaker': '#filteruser', | ||
+ | 'gender': '#filtergender', | ||
+ | 'language': '#filterlanguage', | ||
+ | 'proficiency': '#filterlevelofproficiency', | ||
+ | }; | ||
+ | var lastRequest = { | ||
+ | 'speaker': '', | ||
+ | 'gender': '', | ||
+ | 'language': '', | ||
+ | 'proficiency': '', | ||
+ | }; | ||
− | + | function updateSelector( type ) { | |
− | + | return function( values ) { | |
− | + | console.log( lastRequest ); | |
− | + | console.log( oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '' ); | |
− | + | console.log( oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '' ); | |
− | + | console.log( oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '' ); | |
− | + | console.log( oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '' ); | |
− | + | if( ( oouiSelectors['speaker'] && oouiSelectors['speaker'].getValue() != lastRequest['speaker'] ) || | |
− | + | ( oouiSelectors['gender'] && oouiSelectors['gender'].getValue() != lastRequest['gender'] ) || | |
− | + | ( oouiSelectors['language'] && oouiSelectors['language'].getValue() != lastRequest['language'] ) || | |
− | + | ( oouiSelectors['proficiency'] && oouiSelectors['proficiency'].getValue() != lastRequest['proficiency'] ) ) { | |
− | + | return; | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
− | $( ' | + | oouiSelectors[type] = new OO.ui.ComboBoxInputWidget( { |
− | + | placeholder: placeholders[type], | |
− | + | menu: { | |
+ | filterFromInput: true, | ||
+ | items: values.results.bindings.map( function( x ) { | ||
+ | return new OO.ui.MenuOptionWidget( { | ||
+ | data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")", | ||
+ | label: x[ type + 'Label' ].value | ||
+ | } ); | ||
+ | } ) | ||
+ | } | ||
+ | } ); | ||
+ | |||
+ | $( htmlElements[type] ).html('').append( | ||
+ | oouiSelectors[type].$element | ||
+ | ); | ||
− | + | oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } ); | |
− | } | + | }; |
+ | } | ||
$.getJSON( | $.getJSON( | ||
'https://lingualibre.org/bigdata/namespace/wdq/sparql', | 'https://lingualibre.org/bigdata/namespace/wdq/sparql', | ||
{ | { | ||
− | query: ' | + | query: sparqlGlobal['speaker'] |
} | } | ||
− | ).done( | + | ).done( updateSelector( 'speaker' ) ); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | $.getJSON( | |
− | + | 'https://lingualibre.org/bigdata/namespace/wdq/sparql', | |
− | + | { | |
− | + | query: sparqlGlobal['gender'] | |
− | + | } | |
− | + | ).done( updateSelector( 'gender' ) ); | |
− | |||
$.getJSON( | $.getJSON( | ||
'https://lingualibre.org/bigdata/namespace/wdq/sparql', | 'https://lingualibre.org/bigdata/namespace/wdq/sparql', | ||
{ | { | ||
− | query: ' | + | query: sparqlGlobal['language'] |
} | } | ||
− | ).done( | + | ).done( updateSelector( 'language' ) ); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
$.getJSON( | $.getJSON( | ||
'https://lingualibre.org/bigdata/namespace/wdq/sparql', | 'https://lingualibre.org/bigdata/namespace/wdq/sparql', | ||
{ | { | ||
− | query: ' | + | query: sparqlGlobal['proficiency'] |
} | } | ||
− | ).done( | + | ).done( updateSelector( 'proficiency' ) ); |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
// Display results | // Display results | ||
Line 130: | Line 115: | ||
return; | return; | ||
} | } | ||
− | for (var i = 0; i < | + | var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100; |
+ | $( '#audioresults' ).html( '' ); | ||
+ | for (var i = 0; i < length; i++) { | ||
var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' ); | var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' ); | ||
var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box ); | var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box ); | ||
Line 137: | Line 124: | ||
//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>'); | //$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>'); | ||
} | } | ||
− | |||
− | |||
} | } | ||
// Do SPARQL request from filters | // Do SPARQL request from filters | ||
− | function doQuery(){ | + | function doQuery( variable ){ |
− | + | ||
− | function getQ( text ) | + | // Do not modify a selector where there is a value |
+ | if( variable && oouiSelectors[variable] && oouiSelectors[variable].getValue() ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | function getQ( type ) { | ||
+ | if( variable === type ) { | ||
+ | return '?' + type; | ||
+ | } | ||
+ | var text = oouiSelectors[type] ? oouiSelectors[type].getValue() : ''; | ||
if( !text ) { | if( !text ) { | ||
return ''; | return ''; | ||
Line 150: | Line 144: | ||
text = text.trim(); | text = text.trim(); | ||
if( /^Q[0-9]+$/.test( text ) ) { | if( /^Q[0-9]+$/.test( text ) ) { | ||
− | return text; | + | return 'entity:' + text; |
} else if( /\((Q[0-9]+)\)$/.test( text ) ) { | } else if( /\((Q[0-9]+)\)$/.test( text ) ) { | ||
− | return text.replace( /.*\((Q[0-9]+)\)$/, '$1' ); | + | return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' ); |
} else { | } else { | ||
console.warn( 'Bad input “' + text + '”' ); | console.warn( 'Bad input “' + text + '”' ); | ||
Line 159: | Line 153: | ||
} | } | ||
− | var speaker = getQ( | + | var speaker = getQ( 'speaker' ), |
− | gender = getQ( | + | gender = getQ( 'gender' ), |
− | language = getQ( | + | language = getQ( 'language' ), |
− | proficiency = getQ( | + | proficiency = getQ( 'proficiency' ), |
somevalue = false; | somevalue = false; | ||
+ | if( ! variable ) { | ||
+ | lastRequest = { | ||
+ | 'speaker': oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '', | ||
+ | 'gender': oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '', | ||
+ | 'language': oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '', | ||
+ | 'proficiency': oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '', | ||
+ | }; | ||
+ | } | ||
− | var query = "SELECT ?record WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . "; | + | var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . "; |
if( speaker ) { | if( speaker ) { | ||
− | query += "?record prop:P5 | + | query += "?record prop:P5 " + speaker + " . "; |
somevalue = true; | somevalue = true; | ||
} | } | ||
if( gender ) { | if( gender ) { | ||
− | query += "?record prop:P5 [ prop:P8 | + | query += "?record prop:P5 [ prop:P8 " + gender + " ] . "; |
somevalue = true; | somevalue = true; | ||
} | } | ||
if( language ) { | if( language ) { | ||
− | query += "?record prop:P4 | + | query += "?record prop:P4 " + language + " . "; |
somevalue = true; | somevalue = true; | ||
} | } | ||
if( proficiency ) { | if( proficiency ) { | ||
− | query += "?speaker llp:P4 [ llv:P4 ?language ; llq: | + | query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . "; |
somevalue = true; | somevalue = true; | ||
} | } | ||
− | query += "SERVICE wikibase:label { bd:serviceParam wikibase:language ' | + | query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100"; |
− | + | if( variable ) { | |
− | + | if( !somevalue ) { | |
− | if( !somevalue ) { | + | query = sparqlGlobal[variable]; |
− | + | } | |
+ | } else { | ||
+ | if( !variable && !somevalue ) { | ||
+ | return; | ||
+ | } | ||
+ | $( '#audioresults' ).html( '' ); // TODO replace by a spinner | ||
} | } | ||
− | $.getJSON( | + | // Execute the request |
+ | var result = $.getJSON( | ||
'https://lingualibre.org/bigdata/namespace/wdq/sparql', | 'https://lingualibre.org/bigdata/namespace/wdq/sparql', | ||
{ | { | ||
Line 196: | Line 204: | ||
//Accept: 'application/sparql-results+json' | //Accept: 'application/sparql-results+json' | ||
} | } | ||
− | ).then( createAudioBoxesForSearch, displayError ); | + | ); |
+ | |||
+ | // Depending if we want the whole results or update on selector | ||
+ | if( variable ) { | ||
+ | result.then( updateSelector( variable ), displayError ); | ||
+ | } else { | ||
+ | result.then( createAudioBoxesForSearch, displayError ); | ||
+ | } | ||
} | } | ||
Revision as of 19:34, 6 August 2021
$( function (){
var userLanguage = mw.config.get( 'wgUserLanguage' );
var messages = {
'no-results': {
en: 'No results.',
de: 'Keine Ergebnisse.',
fr: 'Pas de résultat.',
}
};
mw.loader.using( ['oojs', 'oojs-ui'], function () {
var oouiSelectors = {
'speaker': null,
'gender': null,
'language': null,
'proficiency': null,
};
var sparqlGlobal = {
'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel',
'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender',
'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel',
'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency',
};
var placeholders = {
'speaker': '👤 Speaker',
'gender': '♀️ ♂️ Speaker\'s gender',
'language': '🏳️ Language',
'proficiency': '🥇 Level of proficiency',
};
var htmlElements = {
'speaker': '#filteruser',
'gender': '#filtergender',
'language': '#filterlanguage',
'proficiency': '#filterlevelofproficiency',
};
var lastRequest = {
'speaker': '',
'gender': '',
'language': '',
'proficiency': '',
};
function updateSelector( type ) {
return function( values ) {
console.log( lastRequest );
console.log( oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '' );
console.log( oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '' );
console.log( oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '' );
console.log( oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '' );
if( ( oouiSelectors['speaker'] && oouiSelectors['speaker'].getValue() != lastRequest['speaker'] ) ||
( oouiSelectors['gender'] && oouiSelectors['gender'].getValue() != lastRequest['gender'] ) ||
( oouiSelectors['language'] && oouiSelectors['language'].getValue() != lastRequest['language'] ) ||
( oouiSelectors['proficiency'] && oouiSelectors['proficiency'].getValue() != lastRequest['proficiency'] ) ) {
return;
}
oouiSelectors[type] = new OO.ui.ComboBoxInputWidget( {
placeholder: placeholders[type],
menu: {
filterFromInput: true,
items: values.results.bindings.map( function( x ) {
return new OO.ui.MenuOptionWidget( {
data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")",
label: x[ type + 'Label' ].value
} );
} )
}
} );
$( htmlElements[type] ).html('').append(
oouiSelectors[type].$element
);
oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } );
};
}
$.getJSON(
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
{
query: sparqlGlobal['speaker']
}
).done( updateSelector( 'speaker' ) );
$.getJSON(
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
{
query: sparqlGlobal['gender']
}
).done( updateSelector( 'gender' ) );
$.getJSON(
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
{
query: sparqlGlobal['language']
}
).done( updateSelector( 'language' ) );
$.getJSON(
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
{
query: sparqlGlobal['proficiency']
}
).done( updateSelector( 'proficiency' ) );
// Display results
function createAudioBoxesForSearch( data ) {
if ( data.results === undefined || data.results.bindings === undefined ) {
displayError( 'error: no result from SPARQL' );
return;
}
if ( data.results.bindings.length < 1 ) {
$( '#audioresults' ).html( messages['no-results'][userLanguage] ? messages['no-results'][userLanguage] : messages['no-results']['en'] );
return;
}
var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100;
$( '#audioresults' ).html( '' );
for (var i = 0; i < length; i++) {
var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' );
var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box );
$( '#audioresults' ).append( box );
//ab1 = new AudioBox( data.query.rwrecords[ i ], $( '.audiobox' ).eq( i ) );
//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>');
}
}
// Do SPARQL request from filters
function doQuery( variable ){
// Do not modify a selector where there is a value
if( variable && oouiSelectors[variable] && oouiSelectors[variable].getValue() ) {
return;
}
function getQ( type ) {
if( variable === type ) {
return '?' + type;
}
var text = oouiSelectors[type] ? oouiSelectors[type].getValue() : '';
if( !text ) {
return '';
}
text = text.trim();
if( /^Q[0-9]+$/.test( text ) ) {
return 'entity:' + text;
} else if( /\((Q[0-9]+)\)$/.test( text ) ) {
return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' );
} else {
console.warn( 'Bad input “' + text + '”' );
return '';
}
}
var speaker = getQ( 'speaker' ),
gender = getQ( 'gender' ),
language = getQ( 'language' ),
proficiency = getQ( 'proficiency' ),
somevalue = false;
if( ! variable ) {
lastRequest = {
'speaker': oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '',
'gender': oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '',
'language': oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '',
'proficiency': oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '',
};
}
var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . ";
if( speaker ) {
query += "?record prop:P5 " + speaker + " . ";
somevalue = true;
}
if( gender ) {
query += "?record prop:P5 [ prop:P8 " + gender + " ] . ";
somevalue = true;
}
if( language ) {
query += "?record prop:P4 " + language + " . ";
somevalue = true;
}
if( proficiency ) {
query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . ";
somevalue = true;
}
query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100";
if( variable ) {
if( !somevalue ) {
query = sparqlGlobal[variable];
}
} else {
if( !variable && !somevalue ) {
return;
}
$( '#audioresults' ).html( '' ); // TODO replace by a spinner
}
// Execute the request
var result = $.getJSON(
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
{
query: query,
//Accept: 'application/sparql-results+json'
}
);
// Depending if we want the whole results or update on selector
if( variable ) {
result.then( updateSelector( variable ), displayError );
} else {
result.then( createAudioBoxesForSearch, displayError );
}
}
} );
} );