User:Anomie/unattributed-image-finder.js

/* 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 /* 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. */
 * (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.

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=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);