User:Sreejithk2000/duplicateFiles.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/*jshint jquery:true, curly:false*/
/*global mw:false*/
//<nowiki>
(function() {
    "use strict";
    var sree = sree || {};
    var validImages = [];
    var imagesToGet = 50;
    var imageListLimit = 499;
    var lastImage = "";

    sree.duplicateFiles = {

        printDupes: function(summary) {
            var firstLine = "This is a gallery of duplicate files created automatically by the script [[User:Sreejithk2000/duplicateFiles.js]] on " + new Date()
                .toString() + ". ";
            var secondLine = "See https://commons.wikimedia.org/w/api.php?action=query&generator=allimages&prop=duplicatefiles&format=xml for sample output.";

            var gallery = $('<gallery>')
                .attr({
                    "caption": "File List",
                    "lastImage": lastImage
                });
            validImages.sort();
            $(gallery).append("\n");
            $.each(validImages, function(i, item) {
                $(gallery)
                    .append(item + "|[" + "[:" + item + "]]\n");
            });

            var modifiedContent = firstLine + "\n\n" + secondLine + "\n\n" + $(gallery)[0].outerHTML;

            var wpEditToken = mw.user.tokens.get('csrfToken');

            var query = {
                action: 'edit',
                title: mw.config.get('wgPageName'),
                summary: summary || firstLine,
                text: modifiedContent,
                token: wpEditToken,
                format: 'json',
                continue : ''
            };

            $.post(mw.util.wikiScript('api'), query, function(response) {
                location.reload(true);	// Force reload
            });
        },

        getDupes: function() {
            var currentCount = validImages.length;
            if (currentCount >= imagesToGet || imageListLimit <= 0) {
                sree.duplicateFiles.printDupes();
                location.reload();
                return;
            }

            var message = 'Duplicates: ' + currentCount + '. Reading from ' + lastImage;
            console.log(message);
            AjaxQuickDelete.showProgress(message);

            var query = {
                action: 'query',
                generator: 'allimages',
                prop: 'duplicatefiles',
                gaifrom: lastImage,
                gailimit: imageListLimit,
                format: 'json',
                continue: ''
            };

            $.getJSON(mw.util.wikiScript('api'), query, function(dupeResult) {
					if((dupeResult["continue"] || null ) === null) {
						imageListLimit = parseInt(imageListLimit / 2);
                    	sree.duplicateFiles.getDupes(lastImage);
                    	return;
					}
                    var newLastImage = dupeResult["continue"].gaicontinue || dupeResult["continue"].dfcontinue;
                    newLastImage = newLastImage
                    	.replace(/\)/g, '\\)')
                    	.replace(/\(/g, '\\(')    // Remove open and close brackets so that RegEx will not break.
                    	.replace(/\?/g, '\\?')	  // Escape question marks in the file name.
                    	.replace(/\+/g, '\\+');	  // Escape plus in the file name.
                    if(new RegExp(newLastImage).test(lastImage)) {	
                    	// The dfContinue list has the same image. If we continue using this string, it will go into an infinite loop.
                    	// Increment the second character in the lastImage to the next character and try again.
                    	var charCodeForSecondCharInLastImage = lastImage.charCodeAt(1);
                    	var nextChar = String.fromCharCode(++charCodeForSecondCharInLastImage);
                    	newLastImage = lastImage.slice(0, 1) + nextChar + lastImage.slice(2);
                    	console.log("Changed '" + lastImage + "' to '" + newLastImage + "' to escape infinite loop");
                    }
                    lastImage = newLastImage.split('|')[0];	// Remove "|" if any in the string.
                    
                    var pages = dupeResult.query.pages;

                    for (var id in pages) {
                        if (pages.hasOwnProperty(id)) {
                            var dupe = pages[id].duplicatefiles;
                            var image = pages[id].title;
                            if (dupe && validImages.indexOf(image) < 0) {
                                validImages.push(image);
                            }
                        }
                    }
                    imageListLimit = 499;
                    sree.duplicateFiles.getDupes();
                })
                .fail(function() {
                    imageListLimit = parseInt(imageListLimit / 2);
                    sree.duplicateFiles.getDupes(lastImage);
                });
        },

        checkDupe: function(imageList) {
            imageList = imageList.filter(function(n) {
                return n !== '';
            }); // Remove empty entries
            var count = imageList.length;

            if (count === 0) {
                imagesToGet = prompt("How many images do you want to fetch?", 50);
                if (imagesToGet) sree.duplicateFiles.getDupes('');
            }
            $.each(imageList, function(i, item) {
                var image = item.split('|')[0];
                if($.trim(image) === '') return;
                AjaxQuickDelete.showProgress('Checking ' + image);

                var query = {
                    action: 'query',
                    prop: 'duplicatefiles',
                    titles: image,
                    format: 'json',
                    continue: ''
                };

                $.getJSON(mw.util.wikiScript('api'), query, function(dupeResult) {

                    var pages = dupeResult === "" ? [] : dupeResult.query.pages;
                    for (var id in pages) { // there should be only one, but we don't know its ID
                        if (pages.hasOwnProperty(id)) {
                            var dupe = pages[id].duplicatefiles;
                            if (dupe && validImages.indexOf(image) < 0) {
                                validImages.push(image);
                            }
                        }
                    }
                    if (i === (count - 1)) {
                        imagesToGet = prompt("How many images do you want to fetch?", 50);
                        if(validImages.length >= imagesToGet) {
                          alert('No new duplicates found. Reloading page.');
                          location.reload();
                        }
                        else if (imagesToGet) sree.duplicateFiles.getDupes();
                    }
                });
            });
        },

        start: function() {
            if (mw.config.get('wgArticleId') === 0) {
                sree.duplicateFiles.checkDupe([]);
                return;
            }
            var query = {
                action: 'query',
                prop: 'revisions',
                titles: mw.config.get('wgPageName'),
                rvprop: 'content',
                rvslots: 'main',
                format: 'json',
                continue: ''
            };

            $.getJSON(mw.util.wikiScript('api'), query, function(result) {
                var content = result.query.pages[mw.config.get('wgArticleId')].revisions[0].slots.main['*'];
                var gallery = /<gallery[\s\S]*<\/gallery>/gm.exec(content);
                if(gallery) {
                	var $gallery = $(gallery[0]);
                	lastImage = $gallery.attr('lastImage') || '';
                
	                var imageList = $gallery
	                    .text()
	                    .split('\n');
	                    
	                sree.duplicateFiles.checkDupe(imageList);
                }
            });
        },

        removeDupe: function(index, summary) {
            var imageList = [];
            var query = {
                action: 'query',
                prop: 'revisions',
                titles: mw.config.get('wgPageName'),
                rvprop: 'content',
                rvslots: 'main',
                continue: ''
            };

            $.getJSON(mw.util.wikiScript('api'), query, function(result) {
                var content = result.query.pages[mw.config.get('wgArticleId')].revisions[0].slots.main['*'];
                var gallery = /<gallery[\s\S]*<\/gallery>/gm.exec(content);
                if(gallery) {
                	var $gallery = $(gallery[0]);
                	lastImage = $gallery.attr('lastImage');
                
	                var imageList = $gallery
	                    .text()
	                    .split('\n');
	                
                	validImages = [];

                	$.each(imageList, function(i, item) {
                    	var image = item.split('|')[0];
                    	if (i !== index && image !== '') validImages.push(image);
                	});

                	sree.duplicateFiles.printDupes(summary);
                }
            });


        },

        install: function() {
            if (mw.config.get('wgPageName') == "User:Sreejithk2000/Duplicates") {
                var refreshLink = $('<img>').attr({
                    'id': 'duplicateFilesRefresh',
                    'src': '//upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Refresh_font_awesome.svg/15px-Refresh_font_awesome.svg.png'
                });
                $(refreshLink).css('cursor', 'pointer');
                $('h1.firstHeading').append(' ').append(refreshLink);
                $(refreshLink).click(function(e) {
                    e.preventDefault();
                    sree.duplicateFiles.start();
                });

            }

            $.each($('.gallerytext a'), function(i) {
                $(this).after('  <a class="sree-remove-dupe" data-index="' + (i + 1) + '" data-file-name="' + $(this).html() + '"><sup>[x]<sup></a>');
            });
            $('a.sree-remove-dupe').on('click', function(e) {
                e.preventDefault();
                var index = $(this).data('index');
                var fileName = $(this).data('fileName');
                AjaxQuickDelete.showProgress('Removing ' + fileName + ' from the list');
                sree.duplicateFiles.removeDupe(index, '(Script) Removing ' + fileName + ' from the list');
            });
        }
    };
    
    sree.duplicateFiles.install();
})();