// Original Flickrreview script written by [[User:Patstuart]]
// Rewritten and extended by [[User:ZooFari]]
// Special thanks to [[User:Krinkle]] and [[User:DieBuche]] for assistance
// Large parts rewritten by [[User:Rillke]]
// Taken over by Majora in June 2018
// Moved to the MediaWiki namespace in March 2020
// See talk page for documentation
// <nowiki>
/* jshint multistr:true */
/* global AjaxQuickDelete, licenseReviewer */
$(function () {
'use strict';
var conf = mw.config.get(),
userName = conf.wgUserName;
if (conf.wgNamespaceNumber !== 6) return;
var cleanUp = function (input) {
return $.trim( input
.replace( /== ?Summary ?==/, '=={{int:filedesc}}==' )
.replace( /== ?Licensing ?==/, '=={{int:license-header}}==' )
// Remove problem since tags (X-To-DR string)
.replace( /\{\{\s*[Nn]o[ _](source|(OTRS[ _])?permission|license)([ _]since)?\s*(\|[^}\n]+)?\}\}\s?/g, '' )
// Remove Copyvio (X-To-DR string)
.replace( /\{\{\s*(Copyviol?|Copyright(?:ed)?|Screenshot|Icon|Logo|Logo-Germany|(?:Non-free video |DVD )?Cover|Db-f9|db-copyvio|Vio(?:lation)?)\s*(\|[^\n]+|[^}\n]*)\}\}\s?/i, '' )
// Remove Speedy (X-To-DR string)
.replace( /\{\{\s*(Speedy(?:[ -]?delet(?:e|ion))?|Speedilydelete|Noncommercial|Nonderivative|löschen|db|spd|qd|Sdelete|SLA|Spdel|Ek|Destruir)\s*(\|[^\n]+|[^}\n]*)\}\}\s?/i, '' )
.replace( /\{\{\s*SD\s*(\|[^\n]+|[^}\n]*)\}\}\s?/, '' ) ); // Remove SD (not Sd)
},
thxPatterns = { flickr: 'Thanks for licensing this image using a free license! \
Your choice of a free license has allowed us to add your image to <a href="http://commons.wikimedia.org/">Wikimedia Commons</a>. \
The image can now be used to illustrate <a href="http://commons.wikimedia.org/wiki/Special:GlobalUsage/%FILE%">pages</a> \
on <a href="http://en.wikipedia.org/">Wikipedia</a> and other free knowledge projects.' },
linkSanitizer = [
// Google+
// $1: userID; $2: albumID; $3: photoID
{
match: /\/\/plus\.google\.[^\/]+\/photos\/(\d+)\/albums\/(\d+)\/(\d+)/g, replace: '//picasaweb.google.com/lh/sredir?uname=$1&target=PHOTO&id=$3&noredirect=1'
}
],
sanitizeLinks = function (textIn) {
textIn = textIn || '';
$.each(linkSanitizer, function (i, el) {
textIn = textIn.replace(el.match, el.replace);
});
return textIn;
};
$.extend(thxPatterns, window.LRThxPatterns);
var licenseReviewMaybeSave = function (val, summary, minor, justsave, oldtext) {
document.editform.wpSummary.value = summary + ' ([[MediaWiki talk:Gadget-LicenseReview.js|script]])';
document.editform.wpMinoredit.checked = minor;
if (justsave) {
document.editform.submit();
return true;
}
if (!oldtext) oldtext = val;
// First Flickr-check
var gotResult,
$submitButton,
thxPattern,
match = oldtext.match(/\d{1,11}@\D\d{2}/);
if (!match) match = oldtext.match(/flickr\.com\/people\/(\S+?)\/? /);
if (!match) match = oldtext.match(/flickr\.com\/people\/(\S+)/);
if (!match) match = oldtext.match(/flickr\.com\/photos\/(\S+?)\//);
if (!match) match = oldtext.match(/flickr\.com\/photos\/(\S+)/);
if (match)
thxPattern = thxPatterns.flickr;
var checkBlacklistCB = function (isBad) {
if (!isBad) {
$submitButton.prop('disabled', false).removeClass('ui-state-disabled');
gotResult = true;
}
};
if (match) {
match = (match[1] || match[0]);
ajaxIsBadAuthor(match, checkBlacklistCB);
if (thxPattern) {
$('body').append('<div id="mw-licensereview-add" style="display:none" title="You may use this thank-you text">\
<textarea id="ProposalThankyoumessage" readonly="readonly" style="width:400px;height:130px;" rows="5" cols="50" onclick="select()">' +
mw.html.escape(thxPattern.replace(/\%FILE\%/g, conf.wgPageName.replace('File:', ''))) +
'</textarea>\
</div>'
);
$('#mw-licensereview-add').dialog({
buttons: { Ok: function () {
if (gotResult) document.editform.submit();
} },
modal: true,
width: 430
});
$submitButton = $('.ui-dialog-buttonpane').find('button:first');
$submitButton.prop('disabled', true).addClass('ui-state-disabled');
$('#ProposalThankyoumessage').keyup(function (e) {
if (((e.keyCode - 0) === 13)) $submitButton.click();
});
}
return;
} else {
document.editform.submit();
return true;
}
},
getSource = function (val) {
var ret,
r = val.match(/\|\s*Source\s*=(.+)/i);
if (r && r[1])
ret = $.trim(r[1]);
if (!ret) {
r = val.match(/http:\/\/photozou.jp[^\s\]\|]+/i);
if (r)
ret = r[0];
}
return ((ret || 'http://'));
},
lrw = window.licenseReviewer = {
promptForSource: function (prefill) {
return prompt('Link:', getSource(prefill));
},
// LRP - License review passed
LicenseReview_P: function () {
var tb1 = document.editform.wpTextbox1,
noChanges = tb1.value;
tb1.value = tb1.value.replace(/\{\{!}}/g, '|');
if (/\{\{Licen[cs]e ?review.*\}\}/i.test(noChanges)) {
var LRsite = lrw.promptForSource(tb1.value);
if (LRsite === null) return mw.notify('License-review: Aborted');
tb1.value = tb1.value.replace(/\{\{[Ll]icen[cs]e ?[Rr]eview ?(\|.*= ?|\| ?)*\}\}/g, '{{LicenseReview|site=' + LRsite + '|user=' + userName + '|date={{subst:#time:Y-m-d}}}}');
tb1.value = tb1.value.replace(/\[\[Category:((Tasnim|Moj|Fars|Mehr|Nasim)news|SNN|CSS|Khamenei\.ir) review needed\]\]/g, '');
tb1.value = tb1.value.replace(/\{\{ArrangedLicenseReview.*?\}\}/g, '');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
} else if (/\{\{(F|f)inna(R|r)eview\}\}/i.test(noChanges)) {
var LRsite2 = lrw.promptForSource(tb1.value);
if (LRsite2 === null) return mw.notify('License-review: Aborted');
tb1.value = tb1.value.replace(/\{\{(F|f)inna(R|r)eview\}\}/g, '{{FinnaReview|site=' + LRsite2 + '|user=' + userName + '|date={{subst:#time:Y-m-d}}}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
} else if (/\{\{GODL-India/i.test(noChanges)) {
var index = noChanges.search('GODL-India'),
substring1 = noChanges.substring(index + 10),
index2 = substring1.search('}}'),
GODLparams = substring1.substring(0, index2);
tb1.value = tb1.value.replace(/\{\{GODL-India(.+?|)}}/g, '{{GODL-India|status=confirmed|reviewer=~~~|date={{subst:#time:Y-m-d}}' + GODLparams + '}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
} else if (/\{\{(I|i)(n|N)aturalist(R|r)eview\}\}/i.test(noChanges)) {
var LRsite4 = lrw.promptForSource(tb1.value);
if (LRsite4 === null) return mw.notify('License-review: Aborted');
tb1.value = tb1.value.replace(/\{\{(I|i)(n|N)aturalist(R|r)eview\}\}/g, '{{subst:Inrw |site=' + LRsite4 + '|license= |author=}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
} else if (/\{\{[Pp]ixabay.*\}\}/i.test(noChanges)) {
var pbid;
// First attempt: get id from {{pixabay|xxx}}
var pbTemplateID = noChanges.match(/\{\{[Pp]ixabay.*[|=](\d+)}}/);
if (pbTemplateID) {
pbid = pbTemplateID[1];
} else {
var tryPbid = noChanges.match(/pixabay.com.*-(\d+)\/?/i);
if(tryPbid) pbid = tryPbid[1];
else pbid = lrw.promptForSource(tb1.value);
}
if (pbid === null) return mw.notify('License-review: Aborted');
var urlRemoved = pbid.match(/(\d+)\/?$/)[1];
tb1.value = tb1.value.replace(/\{\{[Pp]ixabay.*}}/, '{{subst:pblr|1=' + pbid +'}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
} else if (/\{\{YouTubeReview/i.test(noChanges)) {
var lineIndex = noChanges.search('YouTubeReview'),
youtubeSubstring = noChanges.substring(lineIndex + 13),
lineIndex2 = youtubeSubstring.search('}}'),
YouTubeparams = youtubeSubstring.substring(0,lineIndex2);
if (tb1.value.includes('|id=')) {
tb1.value = tb1.value.replace(/\{\{YouTubeReview(.*?|)}}/ig, '{{YouTubeReview' + YouTubeparams + '|reviewer=' + userName + '}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
}
else {
var LRsite3 = tb1.value;
if (LRsite3.includes('From YouTube')) {
var id;
var indexstart = LRsite3.substring(LRsite3.search('From YouTube'));
var index3 = indexstart.search('1=');
var substring2 = indexstart.substring(index3 + 2);
var index4 = substring2.search('2=');
if (index4 === -1) {
index4 = substring2.search('}');
}
id = substring2.substring(0, index4);
}
else {
var index5 = LRsite3.search('v=');
var idtemp = LRsite3.substring(index5 + 2);
var index6 = idtemp.indexOf('\n');
id = idtemp.substring(0, index6);
}
tb1.value = tb1.value.replace(/\{\{YouTubeReview(.*?|)}}/ig, '{{YouTubeReview|id=' + id + YouTubeparams + '|date={{subst:#time:Y-m-d}}|reviewer=' + userName + '}}');
if (noChanges === tb1.value) alert('RegExp did not match. Likely no changes. Please report to [[MediaWiki talk:Gadget-LicenseReview.js]]');
tb1.value = cleanUp(tb1.value);
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
}
}
else {
tb1.value = tb1.value
.replace(/({{User:Flickr Review Bot.*?}})|({{(F|f)lickr(R|r)?eview.*?}})|({{(F|f)lickr no source.*?}})|({{User:FlickreviewR.*?}})/g, '{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
.replace(/({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g, '{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}').replace(/{{(([^\}]*?))(P|p)icasareview}}/g, '{{$1}}{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}')
.replace(/({{\s*(?:Template:)?((C|c)c-by-3.0-(IndiaFM|BollywoodHungama)|(B|b)ollywoodHungama)}})/g, '{{Cc-by-3.0-BollywoodHungama|status=confirmed|reviewer=~~~~}}')
.replace(/({{\s*(?:Template:)?(C|c)c-by(?:-sa)?-3.0-FilmiTadka}})/g, '{{Cc-by-sa-3.0-FilmiTadka|passed|~~~~}}')
.replace(/({{\s*(?:Template:)?(I|i)pernity(R|r)eview}})/g, '{{Ipernityreview|' + userName + '|{{subst:#time:Y-m-d}}}}')
.replace(/({{\s*(?:Template:)?(I|i)ndafotó review}})/g, '{{Indafotó review|site=[http://indafoto.hu Indafotó]|user=' + userName + '|date={{subst:#time:Y-m-d}}}}')
.replace(/({{\s*(?:Template:)?(N|n)ROER}})/g, '{{NROER|status=confirmed|reviewer=' + userName + '|date={{subst:#time:Y-m-d}}}}')
.replace(/(\[\[(C|c)ategory:(P|d)D files for review\]\])/g, '');
// if no replacements
if (noChanges === tb1.value) {
$('body').append('<div id="mw-licensereview-add" style="display:none" title="No template detected">\
<label for="mw-licensereview-pick">No template found. Add template:</label>\
<select id="mw-licensereview-pick" name="mw-licensereview-pick">\
<option value="LR">LicenseReview</option>\
<option value="PIX">Pixabayreview</option>\
<option value="FR">Flickrreview</option>\
<option value="PICR">Picasareview</option>\
<option value="IR">Ipernityreview</option>\
<option value="INR">iNaturalistReview</option>\
</select>\
</div>');
$('#mw-licensereview-add').dialog({
buttons: { Ok: function () {
licenseReviewer.LicenseReview_A($('#mw-licensereview-pick').val());
$(this).dialog('close');
} },
modal: true
});
} else {
// if replacements
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]] passed', true, false, noChanges);
}
}
},
// Add a License-review template
LicenseReview_A: function (pick) {
var tb1 = document.editform.wpTextbox1;
if (pick) {
switch (pick) {
case 'FR' : tb1.value += '{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}}}';
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:Flickr files|Flickr review]]', false);
break;
case 'PICR' : tb1.value += '{{Picasareview|' + userName + '|{{subst:#time:Y-m-d}}}}';
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Picasa review]]', false);
break;
case 'IR' : tb1.value += '{{Ipernityreview|' + userName + '|{{subst:#time:Y-m-d}}}}';
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Ipernity review]]', false);
break;
case 'PIX' :
tb1.value = cleanUp(tb1.value);
var pixabayID = tb1.value.match(/pixabay.com.*-(\d+)\/?/i)[1];
if(!pixabayID) return mw.notify('License-review: Aborted, could not find ID');
tb1.value = tb1.value.replace(/\{\{[Pp]ixabay.*}}/, '{{subst:pblr|1=' + pixabayID +'}}');
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|Pixabay review]]', false);
break;
case 'INR' :
var site2 = lrw.promptForSource(tb1.value);
tb1.value += '{{subst:inrw|site=' + site2 + '}}';
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|iNaturalist review]]', false);
break;
case 'LR' : var site = lrw.promptForSource(tb1.value);
if (site === null) return mw.notify('License-review: Aborted');
tb1.value += '{{LicenseReview|site=' + site + '|user=' + userName + '|date={{subst:#time:Y-m-d}}}}';
tb1.value = cleanUp(tb1.value);
// submit
licenseReviewMaybeSave(tb1.value, '[[Commons:License review|License review]]', false);
break;
}
}
},
// LRF - License review failed
LicenseReview_F: function () {
var tb1 = document.editform.wpTextbox1,
isBollyWood = /({{\s*(?:Template:)?((C|c)c-by-3.0-(IndiaFM|BollywoodHungama)|(B|b)ollywoodHungama)}})/.test(tb1.value),
isFlickr = /[Ff]lickr/.test(tb1.value),
isPixabay = /[Pp]ixabay/.test(tb1.value),
options;
options = '<option value="NS">-- No source indicated --</option>';
if (isBollyWood) {
options += '<option value="BOLLY">Screenshot of Bollywood image</option>';
} else {
options += '<option value="ARR">All rights reserved</option>\
<option value="NC">Non-commercial</option>\
<option value="ND">Non-derivative</option>\
<option value="NCD">Non-commercial + Non-derivative</option>\
<option value="NCS">Non-commercial-ShareAlike</option>\
<option value="PICASA?">Picasa review unnecessary</option>';
}
if (isFlickr) {
options += '<option value="ARR?">ARR (Puf)(Flickr-only)</option>\
<option value="NC?">NC (Puf)(Flickr-only)</option>\
<option value="ND?">ND (Puf)(Flickr-only)</option>\
<option value="NCD?">NC+D (Puf)(Flickr-only)</option>\
<option value="NCS?">NC-SA (Puf)(Flickr-only)</option>\
<option value="PDMARK">PD-Mark</option>';
}
if (isPixabay) {
options += '<option value="pixabay19">Pixabay upload after 2019-01-09</option>';
}
$('body').append('<div id="mw-licensereview-selector" style="display:none" title="Pick a license">\
<label for="mw-licensereview-pick">Which License?</label>\
<select id="mw-licensereview-pick" name="mw-licensereview-pick">' +
options +
'</select>\
</div>');
$('#mw-licensereview-selector').dialog({
buttons: { Ok: function () {
licenseReviewer.LicenseReview_C($('#mw-licensereview-pick').val());
$(this).dialog('close');
} },
modal: true
});
},
// License review failed, got reason, processing
LicenseReview_C: function (pick) {
var tb1 = document.editform.wpTextbox1,
isFlickr = /[Ff]lickr/.test(tb1.value),
reFlickr = /({{User:Flickr Review Bot.*?}})|({{(F|f)lickrr?eview.*?}})|({{User:FlickreviewR.*?}})/g,
rePicasa = /({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g,
rePicasa2 = /{{(([^\}]*?))(P|p)icasareview}}/g,
reFlickr2 = /{{(([^\}]*?))(F|f)lickrreview}}/g,
reInat = /\{\{(I|i)(n|N)aturalist(R|r)eview\}\}/g,
rePixabay = /\{\{[Pp]ixabay.*}}/g,
reLR = /{{(L|l)icen[cs]e[ _]?(R|r)eview}}/g,
reLicenses = /\{\{(?:Template:)?(cc-by(?:-sa)?-\d\.\d|pd-self)\}\}/gi,
summary = '',
minor = false,
userTag = ''; // You can create new templates if you want and add them to the switch in order to notify the user with a default template
// First changing/ adding review-tags
if (pick) {
switch (pick) {
case 'ARR' :
if (isFlickr) {
tb1.value = '{{subst:Uffd|2=ARR}} \n' + tb1.value.replace(reFlickr, '');
userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
} else {
tb1.value = String(tb1.value.replace(reFlickr, '{{subst:Uffd|2=ARR}}')
.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}')
.replace(reLR, '{{copyvio|1=Posted to source as All Rights Reserved. Only free files are allowed on Commons.}}')
.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=ARR}}')
.replace(reInat, '{{subst:inrw|license=arr}}')
);
}
break;
case 'pixabay19':
tb1.value = tb1.value.replace(rePixabay, '{{copyvio|1=Posted on Pixabay after January 9, 2019, which is not under free license.}}');
userTag = '{{subst:image source|1=%FILE%}}';
break;
case 'NC' :
if (isFlickr) {
tb1.value = '{{subst:Uffd|2=NC}} \n' + tb1.value.replace(reFlickr, '');
userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
} else {
tb1.value = String(tb1.value.replace(reFlickr, '{{subst:Uffd|2=NC}}')
.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-3.0}}')
.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc. Non-commercial restriction is not allowed on Commons.}}')
.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NC}}')
.replace(reInat, '{{subst:inrw|license=cc-by-nc-4.0}}')
);
}
break;
case 'ND' :
if (isFlickr) {
tb1.value = '{{subst:Uffd|2=ND}} \n' + tb1.value.replace(reFlickr, '');
userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
} else {
tb1.value = String(tb1.value.replace(reFlickr, '{{subst:Uffd|2=ND}}')
.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-3.0}}')
.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nd. Non-derivative restriction is not allowed on Commons.}}')
.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=ND}}')
.replace(reInat, '{{subst:inrw|license=cc-by-nd-4.0}}')
);
}
break;
case 'NCD' :
if (isFlickr) {
tb1.value = '{{subst:Uffd|2=NCD}} \n' + tb1.value.replace(reFlickr, '');
userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
} else {
tb1.value = String(tb1.value.replace(reFlickr, '{{subst:Uffd|2=NCD}}')
.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-3.0}}')
.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc-nd. Non-derivative and non-commercial restriction are not allowed on Commons.}}')
.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NCD}}')
.replace(reInat, '{{subst:inrw|license=cc-by-nc-nd-4.0}}')
);
}
break;
case 'NCS' :
if (isFlickr) {
tb1.value = '{{subst:Uffd|2=NCS}} \n' + tb1.value.replace(reFlickr, '');
userTag = '{{subst:unfreeflickrnote|1=%FILE%}}';
} else {
tb1.value = String(tb1.value.replace(reFlickr, '{{subst:Uffd|2=NCS}}')
.replace(rePicasa, '{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
.replace(rePicasa2, '{{$1}}{{picasareview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-3.0}}')
.replace(reLR, '{{copyvio|1=Posted to source as cc-by-nc-sa. Non-commercial restriction is not allowed on Commons.}}')
.replace(reFlickr2, '{{$1}}{{subst:Uffd|2=NCS}}')
.replace(reInat, '{{subst:inrw|license=cc-by-nc-sa-4.0}}')
);
}
break;
case 'NS' :
tb1.value = '{{subst:nsd}} \n' + tb1.value
.replace(reFlickr, '{{Flickr no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
.replace(rePicasa, '{{$1}}{{Picasa no source|' + userName + '|{{subst:#time:Y-m-d}}}}')
.replace(reLR, '{{LicenseReview|site=?}}')
.replace(reFlickr2, '{{$1}}{{Flickr no source|' + userName + '|{{subst:#time:Y-m-d}}}}');
userTag = '{{subst:image source|1=%FILE%}}';
break;
case 'PICASA' : tb1.value = String(tb1.value.replace(/({{User:Picasa Review Bot.*?}})|({{(P|p)icasar?eview}})/g, '{{Picasareviewunnecessary}}'));
break;
case 'ARR?' : tb1.value = String(tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|All rights reserved}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|All Rights Reserved}}'));
break;
case 'NC?' : tb1.value = String(tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-2.0}}'));
break;
case 'ND?' : tb1.value = String(tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nd-2.0}}'));
break;
case 'NCD?' : tb1.value = String(tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-nd-2.0}}'));
break;
case 'NCS?' : tb1.value = String(tb1.value.replace(reFlickr, '{{flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-2.0}}').replace(/{{(([^\}]*?))(F|f)lickrreview}}/g, '{{$1}}{{Flickrreview|' + userName + '|{{subst:#time:Y-m-d}}|cc-by-nc-sa-2.0}}'));
break;
case 'BOLLY': tb1.value = '{{Copyvio|1=[[Commons:License review|License review]] of Bollywood Hungama failed: Image is a screenshot, wallpaper or promotional poster. See [[Template:Cc-by-3.0-BollywoodHungama]]. ~~~~}}' + tb1.value.replace(/({{\s*(?:Template:)?((C|c)c-by-3.0-(IndiaFM|BollywoodHungama)|(B|b)ollywoodHungama)}})/ig, '{{Cc-by-3.0-BollywoodHungama}}');
break;
case 'PDMARK':
tb1.value = '{{subst:Flickr-public domain mark/subst}}\n' + tb1.value
.replace(reFlickr, '')
.replace(reLR, '{{LicenseReview|site=?}}')
.replace(reFlickr2, '{{$1}}')
.replace(reLicenses, '');
break;
}
}
// Then, adding edit summary
if (pick) {
switch (pick) {
case 'NS' :
summary = '[[Commons:License review|License review]] failed: Source not found';
break;
case 'PICASA' :
summary = '[[Commons:Picasa Web Albums files|Picasa review]] not required';
break;
case 'PDMARK' :
summary = '[[Commons:License review|License review]]: Provide a specific reason for the public domain status, please.';
break;
default :
summary = '[[Commons:License review|License review]] failed';
}
}
if (userTag) {
ajaxNotifyUploader(userTag, licenseReviewMaybeSave, [tb1.value, summary, minor, true]);
} else {
// Finally, submit
licenseReviewMaybeSave(tb1.value, summary, minor, true);
}
},
// Change license
LicenseReviewChange: function () {
$('body').append('<div id="mw-licensereview-changer" style="display:none" title="Pick a license">\
<label for="mw-licensereviewc-pick">Change to:</label><br>\
<select id="mw-licensereviewc-pick" name="mw-licensereviewc-pick">\
<option value="BY2">cc-by-2.0</option>\
<option value="BY21jp">cc-by-2.1-jp</option>\
<option value="SA2">cc-by-sa-2.0</option>\
<option value="PD">No known restrictions (Flickr only)</option>\
<option value="PDMo">PDMark owner (Flickr only)</option>\
<option value="CCz">Cc-zero</option>\
<option value="BY3">cc-by-3.0</option>\
<option value="SA3">cc-by-sa-3.0</option>\
<option value="BY4">cc-by-4.0</option>\
<option value="SA4">cc-by-sa-4.0</option>\
</select>\
</div>');
$('#mw-licensereview-changer').dialog({
buttons: { Ok: function () {
licenseReviewer.LicenseReview_L($('#mw-licensereviewc-pick').val());
$(this).dialog('close');
} },
modal: true
});
},
LicenseReview_L: function (pick) {
var tb1 = document.editform.wpTextbox1;
if (pick) {
var pattern = /({{(C|c)c-by-(sa-|)(2|3|4)\.\d.*?}})|({{(C|c)c-zero}})|({{(F|f)lickr-no known copyright restrictions}})|({{(R|r)emove this line and insert a public domain copyright tag instead}})/g,
doReplacement = function (replace, summaryText) {
tb1.value = String(tb1.value.replace(pattern, replace));
document.editform.wpSummary.value = '[[Commons:License review|License review]]: Change to ' + summaryText + ' ([[MediaWiki talk:Gadget-LicenseReview.js|script]])';
document.editform.wpMinoredit.checked = false;
};
switch (pick) {
case 'BY2' :
doReplacement('{{cc-by-2.0}}', 'CC-BY-2.0');
break;
case 'BY21jp':
doReplacement('{{cc-by-2.1-jp}}', 'CC-BY-2.1-JP');
break;
case 'SA2' :
doReplacement('{{cc-by-sa-2.0}}', 'CC-BY-SA-2.0');
break;
case 'PD' :
doReplacement('{{Flickr-no known copyright restrictions}}', 'Flickr-no known copyright restrictions');
break;
case 'PDMo' :
doReplacement('{{PDMark-owner}}', 'Flickr-PDMark owner');
break;
case 'CCz' :
doReplacement('{{Cc-zero}}', 'Cc-zero');
break;
case 'BY3' :
doReplacement('{{cc-by-3.0}}', 'CC-BY-3.0');
break;
case 'SA3' :
doReplacement('{{cc-by-sa-3.0}}', 'CC-BY-SA-3.0');
break;
case 'BY4' :
doReplacement('{{cc-by-4.0}}', 'CC-BY-4.0');
break;
case 'SA4' :
doReplacement('{{cc-by-sa-4.0}}', 'CC-BY-SA-4.0');
break;
}
}
},
// License migration code (part 1) (GFDL --> Cc-by-sa-3.0)
installMig: function ($node) {
var $migDiv = $('div.LMR'),
$migIntro = $('<label>', { text: 'Migration Review:' }).attr({ 'for': 'lrwMigSel' }).appendTo($migDiv),
$migSelect = $('<select>').attr({
id: 'lrwMigSel', size: 1, style: 'vertical-align:middle'
}).appendTo($migDiv),
$migOptEmpty = $('<option>', {
text: ' ', value: ''
}).appendTo($migSelect),
$migOptRelicense = $('<option>', {
text: 'relicense', value: 'relicense'
}).appendTo($migSelect),
$migOptRedundant = $('<option>', {
text: 'redundant', value: 'redundant'
}).appendTo($migSelect),
$migOptInelibible = $('<option>', {
text: 'not eligible', value: 'not-eligible'
}).appendTo($migSelect),
$migOptReviewNeeded = $('<option>', {
text: 'needs review', value: 'needs-review'
}).appendTo($migSelect),
$migOptOut = $('<option>', {
text: 'opt-out', value: 'opt-out'
}).appendTo($migSelect),
$migReason = $('<input>').attr({
type: 'text', size: 60, value: '[[Template:License migration|License migration]]: '
}).appendTo($migDiv),
$saveButton = $('<button>', { text: 'Save' }).attr({
type: 'button', role: 'button'
}).button({ icons: { primary: 'ui-icon-disk' } }).appendTo($migDiv),
$editButton = $('<button>', { text: 'Edit' }).attr({
type: 'button', role: 'button'
}).button({ icons: { primary: 'ui-icon-pencil' } }).appendTo($migDiv);
$migSelect.change(function () {
$migReason.val('[[Template:License migration|License migration]]: ' + $migSelect.val());
});
var $nodeChild = $node.children('tbody');
if ($nodeChild.length)
$nodeChild.append($('<tr>').append($('<td>').attr({ colspan: 3 }).append($migDiv)));
else
$migDiv.prependTo($node);
var migReplace = function (wikiText, cb) {
mw.loader.using('ext.gadget.libWikiDOM', function () {
var nwe = mw.libs.wikiDOM.nowikiEscaper(wikiText),
nt;
// First try to replace the migration parameter
nwe.secureReplace(/\|\s*[Mm]igration\s*=\s*(?:needs[\- _]review|review)?\s*([\|\}])/, '|migration=' + $migSelect.val() + '$1');
nt = nwe.getText();
if (nt !== wikiText) return cb(nt);
// If nothing was replaced, then replace templates without params
nwe.secureReplace(/\{\{\s*(Bild\-GFDL|GFDL|GFDL\-1.3|Gfdl|GNU FDL|Eigenwerk|Gdfl|GFDL\-no\-disclaimers|GFDL\-with\-disclaimers|GNU|ГЛСД\-без\-одрицања|CopyrightGFDL|مجوز گنو|Јд\-јас|ГЛСД|ГЛСД\-без одрицања|GFDL\-lastno|GFDl|GFDL\-Self|GFDL\-user|GFDL\-user\-w|GNU[ _]Free[ _]Documentation[ _]License|GFDL-\D\D\D?|GFDL-user-\D\D\D?|YAM|OsborneFossils)\s*\}\}/i, '{{$1|migration=' + $migSelect.val() + '}}');
nt = nwe.getText();
if (nt !== wikiText) return cb(nt);
// If nothing was replaced, try with params
nwe.secureReplace(/\{\{\s*(Bild\-GFDL|GFDL|GFDL\-1.3|Gfdl|GNU FDL|Eigenwerk|Gdfl|GFDL\-no\-disclaimers|GFDL\-with \-disclaimers|GNU|ГЛСД\-без\-одрицања|CopyrightGFDL|مجوز گنو|Јд\-јас|ГЛСД|ГЛСД\-без одрицања|GFDL\-lastno|GFDl|GFDL\-Self|GFDL\-user|GFDL\-user\-w|GNU[ _]Free[ _]Documentation[ _]License|GFDL-\D\D\D?|GFDL-user-\D\D\D?)\s*(\|[^\}]*)?\}\}/i, '{{$1$2|migration=' + $migSelect.val() + '}}');
nt = nwe.getText();
if (nt !== wikiText) return cb(nt);
// If nothing was replaced, try {{self}}
nwe.secureReplace(/\{\{\s*self2?\s*\|(.*?\|?)(?:GFDL|GNU[ _]FDL|GNU[ _]Free[ _]Documentation[ _]License)(\s*\|.*?)?(.*)}}/i, '{{self|$1GFDL$2$3|migration=' + $migSelect.val() + '}}');
nt = nwe.getText();
if (nt !== wikiText) return cb(nt);
throw new Error('Could not migrate license because the template for license migration was not detected.');
});
};
$editButton.click(function (/* e*/) {
var onMigEdit = function () {
var $tb1 = $(document.editform.wpTextbox1),
$sum = $(document.editform.wpSummary);
migReplace($tb1.val(), function (nt) {
$tb1.val(nt);
$sum.val($migReason.val());
});
};
mw.loader.load('ext.gadget.libWikiDOM');
execEdit(onMigEdit);
});
$saveButton.click(function (/* e*/) {
mw.loader.using(['ext.gadget.AjaxQuickDelete', 'ext.gadget.libWikiDOM'], function () {
var aqd = AjaxQuickDelete;
aqd.initialize();
aqd.addTask('getMoveToken');
aqd.addTask('lrwTextModifyProxy');
aqd.addTask('reloadPage');
aqd.lrwTextModifyProxy = function () {
migReplace(aqd.pageContent, function (nc) {
var page = {
title: conf.wgPageName.replace(/_/g, ' '),
text: nc,
starttimestamp: aqd.starttimestamp,
timestamp: aqd.timestamp,
editType: 'text',
watchlist: 'nochange'
};
aqd.showProgress('Changing template parameter to ' + $migSelect.val());
aqd.savePage(page, $migReason.val(), 'nextTask');
});
};
aqd.nextTask();
});
});
},
// End license migration code (part 1)
//
installLLinks: function (undef) {
var $passHref = $(mw.libs.commons.ui.addEditLink('#', 'license +', 'lPlus', 'License-review: Pass file.', '+', undef, 'p-cactions')).find('a'),
$failHref = $(mw.libs.commons.ui.addEditLink('#', 'license -', 'lMinus', 'License-review: Review failed.', '-', undef, 'p-cactions')).find('a');
$passHref.click(function (e) {
e.preventDefault();
execEdit(licenseReviewer.LicenseReview_P);
});
$failHref.click(function (e) {
e.preventDefault();
execEdit(licenseReviewer.LicenseReview_F);
});
var $changeHref,
$lrNode = $('div.LR');
if ($lrNode.length) {
$lrNode.css('text-align', 'center');
$changeHref = $('<a>', {
href: '#', text: 'change license'
});
$changeHref.click(function (e) {
e.preventDefault();
execEdit(licenseReviewer.LicenseReviewChange);
});
$lrNode.append($('<span>', { id: 'lChange' }).append(' [', $changeHref, '] '));
$lrNode.append($('<span>', { id: 'lPlus2' }).append(' [', $passHref.clone(true).removeAttr('id'), '] '));
$lrNode.append($('<span>', { id: 'lMinus2' }).append(' [', $failHref.clone(true).removeAttr('id'), '] '));
// Sanitizing Google+ Links to PicasaWeb because no license info is displayed on G+
$('.hproduct').find('a[href^="http"]').each(function (i, el) {
var $el = $(el),
href = $el.attr('href');
$el.attr('href', sanitizeLinks(href));
});
}
if (document.editform && document.editform.wpTextbox1) document.editform.wpTextbox1.value = sanitizeLinks(document.editform.wpTextbox1.value);
// License migration review (part 2)
var $migImage = $('img[alt="Licensing update unknown"]'),
hasMigImage = !!$migImage.length;
if (hasMigImage) {
$('span.licensetpl_short').each(function (i, el) {
var $el = $(el);
if (['GFDL', 'GFDL 1.3'].indexOf($el.text()) > -1 && $('img[alt="Licensing update unknown"]').length) {
licenseReviewer.installMig($migImage.parents('.licensetpl'));
return false;
}
});
}
} // End of license migration review (part 2)
}, // End of Object (licenseReviewer)
execEdit = function (cb) {
if (['edit', 'submit'].indexOf(conf.wgAction) < 0) {
// scroll to top
$('html,body').animate({ scrollTop: 0 }, 1000);
// switch to pseudo-edit-mode
var gotEditHTML = function (html) {
$('#bodyContent').replaceWith($(html).find('#bodyContent'));
document.editform.wpTextbox1.value = sanitizeLinks(document.editform.wpTextbox1.value);
mw.config.set('wgAction', 'edit');
document.title = 'Editing ' + document.title;
$('#ca-edit').addClass('selected');
cb();
};
$('#bodyContent').prepend($('<h2>', { text: 'Loading ...' }));
$.get(mw.util.wikiScript('index'), {
action: 'edit', title: conf.wgPageName.replace(/ /g, '_')
}, gotEditHTML);
} else {
// execute
cb();
}
},
/**
* Notify the initial uploader about a non-free image upload.
*
* @example
* ajaxNotifyUploader('{{subst:unfreeflickrnote|%FILE%}}', someFunction, arguments to pass along);
*
* @param tag {String} Tag to add to the user's talk page
* @param callback {Function} Pointer to a callback function on ready or error.
*
* @context {window}
* @return n/d
*/
ajaxNotifyUploader = function (tag, callback, args) {
if (!tag) return;
var errDisplay = function (err) {
alert(err);
callback.apply(this, args);
},
didEdit = function (result) {
try {
if (result.edit.spamblacklist)
throw new Error('Spamblacklisted. Sorry.');
else if (result.error)
throw new Error('API returned error: ' + result.error.code + '\n' + result.error.info);
alert('User notified.');
callback.apply(this, args);
return;
} catch (err) {
errDisplay('Something went wrong while notifying the user.');
return;
}
},
doEdit = function (user) {
if (/(:?^[Bb]ot)|(:?[Bb]ot$)/.test(user)) {
errDisplay('User who created this page is very likely a bot and is NOT notified.');
return;
}
var page = {
action: 'edit',
format: 'json',
title: conf.wgFormattedNamespaces[3] + ':' + user,
summary: 'Notification of possible unfree file. ([[MediaWiki talk:Gadget-LicenseReview.js|script]])',
appendtext: '\n' + tag.replace('%FILE%', conf.wgPageName.replace(/_/g, ' ')) + ' ~~' + '~~',
token: mw.user.tokens.get('csrfToken')
};
jQuery.post(mw.util.wikiScript('api'), page, didEdit);
},
gotUser = function (result) {
try {
for (var id in result.query.pages) {
var pg = result.query.pages[id];
doEdit(pg.revisions[0].user);
}
} catch (err) {
errDisplay('Error notifying user. Do it yourself.');
return;
}
},
// query first revision (in Lupo-Style :D)
query = {
action: 'query',
format: 'json',
prop: 'revisions',
rvprop: 'user',
rvdir: 'newer',
rvlimit: 1,
titles: conf.wgPageName.replace(/_/g, ' ')
};
$.getJSON(mw.util.wikiScript('api'), query, gotUser);
},
/**
* Determine whether the flickr-user is a "bad-author".
*
* @example
* ajaxIsBadAuthor('11121189@N04', someFunction);
*
* @param author {String} The flckr-user's ID
* @param callback {Function} Pointer to a callback function on ready or error. Should take one argument.
*
* @context {window}
* @return n/d
*/
ajaxIsBadAuthor = function (author, callback) {
var gotList = function (result, useRx) {
pendingCalls--;
if (result) {
var rx = useRx ? (new RegExp('\\|\\s*' + mw.RegExp.escape(author) + '\\s*\\|', '')) :
(new RegExp(mw.RegExp.escape(author), ''));
if (rx.test(result)) {
isBad = isBad || true;
if (pendingCalls) return;
if (isBad) alert('Warning! The Flickr-Uploader is blacklisted.');
callback(isBad);
return;
} else {
if (pendingCalls) return;
if (isBad) alert('Warning! The Flickr-Uploader is blacklisted.');
callback(isBad);
return;
}
} else {
alert('Error retrieving bad-author-list from server.');
}
},
pendingCalls = 0,
isBad = false,
doCall = function (page, useRx) {
pendingCalls++;
$.ajax({
url: mw.util.wikiScript('index'),
data: {
title: page,
action: 'raw',
dataType: 'text',
// Allow caching for 1/4h
maxage: 900,
smaxage: 900
},
cache: true,
type: 'GET',
success: function (r) {
gotList(r, useRx);
},
error: function () {
gotList();
}
});
};
doCall('Commons:Questionable_Flickr_images/Users', true);
doCall('User:FlickreviewR/bad-authors', false);
};
// Install
mw.loader.using(['jquery.ui', 'ext.gadget.editDropdown'], function () {
licenseReviewer.installLLinks();
mw.loader.load(['mediawiki.user', 'mediawiki.util']);
});
});
// </nowiki>