/* If you want to use this script, simply add the following line to your [[Special:Mypage/common.js]]:
importScript('User:Anomie/unattributed-image-finder.js'); // Linkback: [[User:Anomie/unattributed-image-finder.js]]
* (Please keep the comment so I can see how many people use this). You will also want to
* add some CSS classes, such as those at [[User:Anomie/unattributed-image-finder.css]].
*/
/* If you want this to run "on demand" instead of on every page, set "UnattributedImageFinder=true" and
* use addPortletLink() or the like to add a button calling UnattributedImageFinder.onDemand().
*/
var UnattributedImageFinder = {
no_attribution_cats:[
// en
'Category:Cc-zero images',
'Category:All user-created public domain images',
'Category:Author died more than 100 years ago public domain images',
'Category:Author died more than 70 years ago public domain images',
'Category:Copyright holder released public domain images',
'Category:PD OpenClipart',
'Category:PD US no notice',
'Category:PD US not renewed',
'Category:PD chem',
'Category:PD other reasons',
'Category:PD script',
'Category:PD tag needs updating',
'Category:PD-link',
'Category:Pre 1978 without copyright notice US public domain images',
'Category:Public domain art',
'Category:Public domain images',
'Category:Public domain images ineligible for copyright',
'Category:Public domain images of currency',
'Category:Public domain images of fonts',
'Category:Public domain music images',
// commons
'Category:CC-Zero',
'Category:AIGA symbol signs',
'Category:Anonymous work',
'Category:CC-PD',
'Category:CC-PD-Mark',
'Category:CC-Zero',
'Category:Kopimi',
'Category:PD Flags',
'Category:PD cartoons',
'Category:PD coat of arms definitions',
'Category:PD ineligible',
'Category:PD other reasons',
'Category:PD patents',
'Category:PD-author',
'Category:PD-copyright holder',
'Category:PD-heirs',
'Category:PD-imf.org',
'Category:PD-link',
'Category:PD-scan',
'Category:PD-self',
'Category:PD-user',
'Category:Public domain',
'Category:Public domain due to copyright expiration',
'Category:Public domain images no longer eligible for claim of authorship',
'Category:Public domain images of fonts',
'Category:PD ancient script',
'Category:PD chem',
'Category:PD ineligible',
'Category:PD ineligible OpenGeoDB',
'Category:PD script',
'Category:PD shape',
'Category:PD signature',
'Category:PD text',
'Category:PD-Art (PD-ineligible)',
'Category:PD-Art (PD-shape)',
// Apparently this is ok
'Category:Copyright by Wikimedia',
'Category:Files copyrighted by the Wikimedia Foundation'
],
rqcount:0,
ncount:0,
decodeImageName:function(n){
return 'File:'+decodeURIComponent(n.replace(/_/g, ' '));
},
processImages:function(r,sts,xhr){
if(!r.query || !r.query.pages) {
if(typeof(window.console)=='undefined' || typeof(window.console.error)!='function')
throw new Error('Bad response');
window.console.error("Bad response", r);
return;
}
var imgok=this.imgok;
var imglist=this.imglist;
for(var k in r.query.pages){
var p=r.query.pages[k];
if(typeof(p.categories)=='undefined') continue;
var title=p.title;
if(imgok[title]) continue;
var cats=p.categories.map(function(c){ return c.title; });
for(var i=0; i<cats.length; i++){
if(UnattributedImageFinder.no_attribution_cats.indexOf(cats[i])>=0){
imgok[title]=true;
break;
}
}
}
if(r['query-continue']){
var cc=this.rawdata;
for(var k in r['query-continue']){
for(var k2 in r['query-continue'][k]){
cc[k2]=r['query-continue'][k][k2];
}
}
$.ajax({
url:this.url,
dataType:this.dataType,
type:'POST',
data:cc,
rawdata:cc,
imgok:imgok,
imglist:imglist,
success:arguments.callee,
error:function(xhr,textStatus,errorThrown){
UnattributedImageFinder.rqcount--;
UnattributedImageFinder.doAlert();
throw new Error('AJAX error: '+textStatus+' '+errorThrown);
}
});
return;
}
for(var i=imglist.length-1; i>=0; i--){
// Images, local or on Commons
var m=imglist[i].src.match(/\/\/upload.wikimedia.org\/wiki[mp]edia\/(en|commons)\/(thumb\/)?[0-9a-f]\/[0-9a-f][0-9a-f]\/([^\/]+)/);
if(!m) continue;
var name=UnattributedImageFinder.decodeImageName(m[3]);
if(typeof(imgok[name])=='undefined' || imgok[name]) continue;
$(imglist[i]).addClass('unattributed-image');
UnattributedImageFinder.ncount++;
}
UnattributedImageFinder.rqcount--;
UnattributedImageFinder.doAlert();
},
loadCats:function(api,images,imglist){
if(!api) api=mw.util.wikiScript('api');
while(images.length>0){
var imgs=images.splice(0,50);
var imgok={};
for(var i=0; i<imgs.length; i++){
imgok[imgs[i]]=false;
}
var q={
format:'json',
action:'query',
titles:imgs.join('|'),
prop:'categories',
cllimit:'max'
};
if(api != mw.util.wikiScript('api')){
// Set origin for CORS request
q.origin = location.protocol+'//'+location.host;
}
UnattributedImageFinder.rqcount++;
$.ajax({
url:api,
dataType:'json',
type:'POST',
data:q,
rawdata:q,
imgok:imgok,
imglist:imglist,
rawcontinue:'',
success:UnattributedImageFinder.processImages,
error:function(xhr,textStatus,errorThrown){
UnattributedImageFinder.rqcount--;
UnattributedImageFinder.doAlert();
throw new Error('AJAX error: '+textStatus+' '+errorThrown);
}
});
}
},
scanChildren:function(node){
mw.loader.using('mediawiki.util', function(){
var imgs=node.getElementsByTagName('IMG');
var checkimgs={ en:{}, commons:{} };
var imglist=[];
for(var i=imgs.length-1; i>=0; i--){
// Images, local or on Commons
var m=imgs[i].src.match(/\/\/upload.wikimedia.org\/wiki[mp]edia\/(en|commons)\/(thumb\/)?[0-9a-f]\/[0-9a-f][0-9a-f]\/([^\/]+)/);
if(!m) continue;
var source=m[1];
var name=UnattributedImageFinder.decodeImageName(m[3]);
// Skip uses of the image on its own image page
if(name == mw.config.get('wgPageName').replace(/_/g,' ')) continue;
// Skip if linked to the image description page
if(imgs[i].parentNode.nodeName=='A'){
var m2=imgs[i].parentNode.href.match(/\/\/en.wikipedia.org\/wiki\/File:(.*)/);
if(m2 && UnattributedImageFinder.decodeImageName(m2[1])==name) continue;
}
checkimgs[source][name]=1;
imglist.push(imgs[i]);
}
UnattributedImageFinder.rqcount++;
// Now we must load the categories for the images.
imgs=[];
for(var k in checkimgs.en) imgs.push(k);
UnattributedImageFinder.loadCats(null, imgs, imglist);
imgs=[];
for(var k in checkimgs.commons) imgs.push(k);
UnattributedImageFinder.loadCats('//commons.wikimedia.org/w/api.php', imgs, imglist);
UnattributedImageFinder.rqcount--;
UnattributedImageFinder.doAlert();
});
},
onLoad:function(){
if(window.UnattributedImageFinderOnDemand) return;
if(window.AJAXPreview) window.AJAXPreview.AddOnLoadHook(UnattributedImageFinder.scanChildren);
UnattributedImageFinder.onDemand();
},
onDemand:function(){
var node=document.getElementById('wikiPreview');
if(!node) node=document.getElementById('bodyContent');
if(node) UnattributedImageFinder.scanChildren(node);
},
doAlert:function(){
if(!window.UnattributedImageFinderAlert) return;
if(UnattributedImageFinder.rqcount>0 || UnattributedImageFinder.ncount<=0) return;
var d=document.createElement('DIV');
d.className='unattributed-image-finder-notification';
if(UnattributedImageFinder.ncount==1){
d.appendChild(document.createTextNode("Found 1 image that appears to be unlinked but requires attribution"));
} else {
d.appendChild(document.createTextNode("Found "+UnattributedImageFinder.ncount+" images that appear to be unlinked but require attribution"));
}
d.appendChild(document.createTextNode(" "));
var hide=document.createElement('SPAN');
hide.appendChild(document.createTextNode('[hide]'));
hide.style.cursor='pointer';
$(hide).click(function(){
d.parentNode.removeChild(d);
});
d.appendChild(hide);
document.body.appendChild(d);
}
};
if(!window.UnattributedImageFinderOnDemand) $(document).ready(UnattributedImageFinder.onLoad);