User:CristianCantoro/missing props.js
Jump to navigation
Jump to search
Note: After publishing, 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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/*
(c) 2013 Magnus Manske, GPL V2+
Usage: Add
importScript( 'User:Magnus_Manske/missing_props.js' );
to your "common.js" User subpage
Feel free to expand the types and expected properties lists!
*/
var wd_missing_props = {
q_prefix : 'Q' ,
p_prefix : 'P' ,
api : '/w/api.php' ,
id_cnt : 0 ,
types : { // P/Q indicators
'book' : [ [31,571] ] ,
'species' : [ [105,7432] ] ,
'human' : [ [31, 5] ],
'geographical' : [ [107, 618123] ],
'village' : [ [31,532] ]
} ,
expected : { // Potential properties
'book' : [357,392,364,50,98,136,135,393,291,123,577,179,110,212,243,166,155,156,144] ,
'species' : [107,225,74,373] ,
'human' : [21, 27, 569, 570, 19, 20, 513, 106, 101, 108, 69, 512, 26, 40, 25, 22, 9, 7, 463, 102, 39, 373, 43, 45, 140],
'geographical' : [373, 131, 625] ,
'village' : [107, 131, 132, 625]
} ,
init : function () {
var self = this ;
var portletLink = mw.util.addPortletLink( 'p-tb', 'javascript:;', 'Missing props','t-wd_mp');
$(portletLink).click ( function () {
self.run(true) ;
return false ;
} ) ;
self.run(false);
} ,
run : function ( do_alert ) {
var self = this ;
self.determineType ( function () {
if ( undefined === self.type ) {
if ( do_alert ) alert ( 'Could not determine item type' ) ;
return ;
}
var loadLabels = [] ;
$('div.wd_mp').remove() ;
$.each ( self.expected[self.type] , function ( k , v ) {
if ( undefined !== self.claims[self.p_prefix+v] ) return ; // Has that prop
var h = "<div class='wd_mp' style='border:1px solid #DDDDDD;padding:2px;margin-top:5px' id='wd_mp"+v+"'>" ;
h += "<a href='javascript:;' class='wd_mp_ap' prop='"+v+"'>Add \"<span class='" + self.p_prefix + v + "'>P" + v + "</span>\"</a>" ;
h += "</div>" ;
$('div.wb-claimlistview :last').after ( h ) ;
loadLabels.push ( self.p_prefix+v ) ;
} ) ;
self.showLabels ( loadLabels ) ;
$('a.wd_mp_ap').click ( function(){self.addProp($(this).attr('prop'));return false} ) ;
self.autofill() ;
} ) ;
} ,
autofill : function () {
var self = this ;
$.each ( ['en','de','es','fr','it','pt'] , function ( dummy , lang ) {
var page = $('td.wb-sitelinks-link-'+lang+' a').text() ;
if ( page === undefined || page == '' ) return ;
$.getJSON ( '//'+lang+'.wikipedia.org/w/api.php?callback=?' , {
action:'query',
prop:'links',
pllimit:500,
plnamespace:0,
titles:page,
format:'json'
} , function ( d_wp ) {
var titles = [] ;
$.each ( (d_wp.query.pages||{}) , function ( k , v ) {
if ( k < 0 ) return ; // Paranoia
$.each ( (v.links||[]) , function ( k2 , v2 ) {
titles.push ( v2.title ) ;
} ) ;
} ) ;
self.doPostDance ( titles , [] , lang ) ;
} ) ;
return false ;
} ) ;
} ,
doPostDance : function ( titles , candidates , lang ) {
var self = this ;
var t = [] ;
while ( t.length < 50 && titles.length > 0 ) {
t.push ( titles.shift() ) ;
}
$.post ( self.api , {
action:'wbgetentities',
sites:lang+'wiki',
titles:t.join('|'),
languages:'en',
format:'json'
} , function ( d ) {
$.each ( (d.entities||{}) , function ( q , v ) {
if ( q < 0 ) return ;
var o = { q : q ,
label : ( typeof v.labels === 'undefined' || typeof v.labels.en === 'undefined' ) ? q : v.labels.en.value ,
page : v.sitelinks[lang+'wiki'].title ,
desc : ( undefined === v.descriptions || undefined === v.descriptions.en ) ? '' : v.descriptions.en.value ,
}
candidates.push ( o ) ;
} ) ;
if ( titles.length > 0 ) {
self.doPostDance ( titles , candidates , lang ) ;
return ;
}
var h = "<span> or prefilled <form class='wp_mp_quickadd' style='display:inline-block'><select class='wd_mp_select'>" ;
$.each ( candidates , function ( dummy , v ) {
h += "<option value='" + v.q + "'>" ;
h += (v.label==v.q?v.page:v.label) ;
if ( v.desc != '' ) h += ' : ' + v.desc.substr(0,20) ;
h += "</option>" ;
} ) ;
h += "</select>" ;
h += "<input type='submit' onclick='' value='+' /></form></span>" ;
$(h).insertAfter ( 'a.wd_mp_ap' ) ;
$('form.wp_mp_quickadd input').click ( function ( o ) {
o.preventDefault() ;
var p = $($($(this).parents('div.wd_mp').get(0)).find('a.wd_mp_ap')).attr('prop') ;
var q = $($($(this).parents('div.wd_mp').get(0)).find('select.wd_mp_select')).val() ;
var val = '{"entity-type":"item","numeric-id":' + q.replace(/\D/g,'') + '}' ;
self.createClaim ( p , val ) ;
return false ;
} ) ;
} ) ;
} ,
addProp : function ( p ) {
var self = wd_missing_props ;
$('#wd_mp'+p).remove() ;
$('span.wb-addtoolbar :last a').click() ;
$('div.wb-snak-property input.ui-entityselector-input').val ( self.p_prefix+p ) ;
var e = $.Event("keydown") ;
e.which = 40 ;
$("div.wb-snak-property input.ui-entityselector-input").trigger(e) ;
self.clickit() ;
return false ;
} ,
clickit : function () {
/* var self = wd_missing_props ;
var a = $('a.ui-entityselector-section-container') ;
if ( a.length == 0 ) {
setTimeout ( self.clickit , 100 ) ;
return ;
}
// THIS DOES NOT WORK! NEITHER DOES .click() on first dropbox element!
setTimeout ( function () {
var e = $.Event("keydown");
e.which = 9;
$("div.wb-claim-new input.ui-entityselector-input").trigger(e);
} , 1000 ) ;*/
} ,
showLabels : function ( props ) {
var self = this ;
$.post ( self.api , {
action:'wbgetentities',
ids:props.join('|'),
props:'labels',
format:'json'
} , function ( d ) {
var lang = mw.config.get('wgUserLanguage') ;
$.each ( d.entities , function ( k , v ) {
if ( typeof v.labels !== 'undefined' && typeof v.labels[lang] !== 'undefined' ) {
$('span.'+k).html ( v.labels[lang].value ) ;
}
} ) ;
} , 'json' ) ;
} ,
determineType : function ( callback ) {
var self = this ;
var entity = mw.config.get('wgTitle').toUpperCase() ;
$.post ( self.api , {
action:'wbgetentities',
ids:entity,
props:'claims',
format:'json'
} , function ( d ) {
self.claims = d.entities[entity].claims ;
$.each ( self.types , function ( type , tl ) {
$.each ( tl , function ( dummy , tp ) {
if ( undefined === self.claims[self.p_prefix+tp[0]] ) return ;
$.each ( self.claims[self.p_prefix+tp[0]] , function ( k2 , v2 ) {
if ( v2.mainsnak.datavalue.value['numeric-id'] != tp[1] ) return ;
self.type = type ;
return false ;
} ) ;
if ( undefined !== self.type ) return false ;
} ) ;
if ( undefined !== self.type ) return false ;
} ) ;
callback() ;
} , 'json' ) ;
} ,
// BEGIN from wikidata_useful.js
createClaim : function ( property , value ) {
var entity = mw.config.get('wgPageName').toUpperCase() ;
var self = this ;
entity = self.q_prefix + entity.replace ( /\D/g , '' ) ;
property = property.replace ( /\D/g , '' ) ;
$.post ( self.api , {
action : 'query' ,
prop : 'info' ,
intoken : 'edit' ,
titles : entity ,
format : 'json'
} , function ( data ) {
var token , lastrevid ;
$.each ( (data.query.pages||[]) , function ( k , v ) {
token = v.edittoken ;
lastrevid = v.lastrevid ;
} ) ;
if ( undefined === token ) {
console.log ( "Cannot get edit token for " + entity ) ;
return ;
}
property = property.replace(/\D/g,'') ;
entity = entity.replace(/\D/g,'') ;
var vo = JSON.parse ( value ) ;
var is_item_target = vo['numeric-id'] !== undefined ;
var value_id = is_item_target ? vo['numeric-id']+'' : vo ;
var other_entity = ( entity.replace(/\D/g,'') != entity.replace(/\D/g,'') ) ;
$.post ( self.api , {
action : 'wbcreateclaim' ,
entity : self.q_prefix+entity ,
snaktype : 'value' ,
property : self.p_prefix+property ,
value : value ,
token : token ,
baserevid : lastrevid ,
format : 'json'
} , function ( data ) {
var id = 'wd_mp_added_' + self.id_cnt ;
self.id_cnt++ ;
var h = "<div id='" + id + "'>" ;
h += "Added " ;
h += "<span class='added_entity_p'>" + property + "</span>" ;
h += " ↠ " ;
h += "<span class='added_entity_q'>" + value_id + "</span>" ;
if ( other_entity ) h += " to entity <span class='added_entity_x'>" + entity + "</span>" ;
h += ".</div>" ;
$($('div.wb-claims').get(0)).append ( h ) ;
self.updateEntity ( id , property , self.p_prefix ) ;
if ( is_item_target ) self.updateEntity ( id , value_id , self.q_prefix ) ;
if ( is_item_target && other_entity ) self.updateEntity ( id , entity.replace(/\D/g,'') , 'x' ) ;
} , 'json' ) ;
} , 'json' ) ;
} ,
updateEntity : function ( id , value , prefix ) {
var self = this ;
var q = prefix+value ;
if ( prefix == 'x' ) q = self.q_prefix + value ;
$.getJSON ( self.api , {
action : 'wbgetentities' ,
ids : q ,
format : 'json'
} , function ( data ) {
var labels = data.entities[q].labels ;
var title = q ;
if ( undefined !== labels ) {
$.each ( ['en','de','fr'] , function ( k , v ) {
if ( undefined === labels[v] ) return ;
title = labels[v].value ;
return false ;
} ) ;
}
var h = "<a href='/wiki/" + q + "'>" + title + "</a>" ;
$('#'+id+' span.added_entity_'+prefix).html ( h ) ;
} ) ;
} ,
// END wikidata_useful.js
dummy : ''
} ;
$ ( function() {
if ( mw.config.get('wgNamespaceNumber') != 0 ) return ;
if ( mw.config.get('wgAction') != 'view' ) return ;
wd_missing_props.init () ;
});