MediaWiki:Gadget-CacheCheck.js: Difference between revisions

From NPOWiki
Jump to navigation Jump to search
(create - latest version from wikia dev wiki, edited to suit vanilla MW)
 
(don't waste resources running on large lists. Also style changes)
Line 2: Line 2:
  * Crosses out resolved entries on the cached special pages to save time checking them.
  * Crosses out resolved entries on the cached special pages to save time checking them.
  * Note: these pages have a much shorter cache here, but the script also helps at-a-glance on SpecialPages.
  * Note: these pages have a much shorter cache here, but the script also helps at-a-glance on SpecialPages.
*  Therefore, the script will only run on a report page if ten or fewer items are listed.
*  Use window.cacheCheckAlways = true; to disable this.
  * Originally by Bobogoobo, edited by KockaAdmiralac and others, then ported off Wikia by Bobogoobo.
  * Originally by Bobogoobo, edited by KockaAdmiralac and others, then ported off Wikia by Bobogoobo.
  * For full documentation and contribution history (other than changes before publishing), please see:
  * For full documentation and contribution history (other than changes before publishing), please see:
Line 9: Line 11:


mw.loader.using('mediawiki.util').done(function() {
mw.loader.using('mediawiki.util').done(function() {
     if (window.CacheCheckLoaded) {
     if (window.cacheCheckLoaded || mw.config.get('wgCanonicalNamespace') !== 'Special') {
         return;
         return;
     }
     }
     window.CacheCheckLoaded = true;
     window.cacheCheckLoaded = true;


     var removeIfFalse = false,
     var removeIfFalse = false,
         skips = window.cacheSkip || [],
         skips = window.cacheSkip || [],
         skipLimit = Number(window.cacheSkipLimit) || 1000,
         skipLimit = Number(window.cacheSkipLimit) || 1000,
        throttle = !window.cacheCheckAlways;
         $list = $('ol.special').length ? $('ol.special > li') : $('ul.gallery > li'),
         $list = $('ol.special').length ? $('ol.special > li') : $('ul.gallery > li'),
         isgallery = $('ol.special').length ? false : true,
         isgallery = $('ol.special').length ? false : true,
Line 40: Line 43:
         ];
         ];


     function takeAction($el) {
     // Only on "Wanted" reports, entries are resolved if the query result is empty.
        if (window.CacheCheckRemove) {
    if (page.substring(0, 6) === 'Wanted') {
            $el.remove();
        removeIfFalse = true;
        } else {
            var $gallery = $el.find('.gallerytext a:first');
            if ($gallery.length) {
                if ($gallery.find('img')) {
                    // The link is actually on the image.
                    $el.remove();
                } else {
                    $gallery.wrap('<s></s>');
                }
            } else {
                $el.wrapInner('<s></s>');
            }
        }
     }
     }


Line 64: Line 54:
         skips.indexOf(page) !== -1 ||
         skips.indexOf(page) !== -1 ||
         ($list.length === 0 && page !== 'Specialpages') ||
         ($list.length === 0 && page !== 'Specialpages') ||
        (throttle && $list.length > 10 && page !== 'Specialpages') ||
         skipLimit < (Number(mw.util.getParamValue('limit')) || 0)
         skipLimit < (Number(mw.util.getParamValue('limit')) || 0)
     ) {
     ) {
Line 103: Line 94:
         return;
         return;
     }
     }
 
   
     // Only on "Wanted" reports, entries are resolved if the query result is empty.
     // Handles marking the given element as resolved.
     if (page.substring(0, 6) === 'Wanted') {
     function takeAction($el) {
         removeIfFalse = true;
        if (window.cacheCheckRemove) {
            $el.remove();
        } else {
            var $gallery = $el.find('.gallerytext a:first');
            if ($gallery.length) {
                if ($gallery.find('img')) {
                    // The link is actually on the image.
                    $el.remove();
                } else {
                    $gallery.wrap('<s></s>');
                }
            } else {
                $el.wrapInner('<s></s>');
            }
         }
     }
     }



Revision as of 11:14, 26 July 2021

/* CacheCheck.js
 * Crosses out resolved entries on the cached special pages to save time checking them.
 * Note: these pages have a much shorter cache here, but the script also helps at-a-glance on SpecialPages.
 *   Therefore, the script will only run on a report page if ten or fewer items are listed.
 *   Use window.cacheCheckAlways = true; to disable this.
 * Originally by Bobogoobo, edited by KockaAdmiralac and others, then ported off Wikia by Bobogoobo.
 * For full documentation and contribution history (other than changes before publishing), please see:
 *   https://dev.fandom.com/wiki/CacheCheck
 */
window.topLevelCat = 'Category:Contents';

mw.loader.using('mediawiki.util').done(function() {
    if (window.cacheCheckLoaded || mw.config.get('wgCanonicalNamespace') !== 'Special') {
        return;
    }
    window.cacheCheckLoaded = true;

    var removeIfFalse = false,
        skips = window.cacheSkip || [],
        skipLimit = Number(window.cacheSkipLimit) || 1000,
        throttle = !window.cacheCheckAlways;
        $list = $('ol.special').length ? $('ol.special > li') : $('ul.gallery > li'),
        isgallery = $('ol.special').length ? false : true,
        pending = $list.length,
        qstr = mw.util.wikiScript('api') + '?action=query&format=json&',
        structure = ['query'],
        page = mw.config.get('wgCanonicalSpecialPageName'),
        pages = [
            'Specialpages',
            'Deadendpages',
            'Lonelypages', 
            'Uncategorizedcategories',
            'Uncategorizedpages',
            'Uncategorizedimages',
            'Uncategorizedtemplates',
            'Unusedcategories',
            'Unusedimages',
            'Unusedtemplates',
            'Wantedcategories',
            'Wantedpages',
            'Wantedfiles',
            'Wantedtemplates'
        ];

    // Only on "Wanted" reports, entries are resolved if the query result is empty.
    if (page.substring(0, 6) === 'Wanted') {
        removeIfFalse = true;
    }

    // Skip execution if not on a relevant page, page is skipped by user, 
    // or list on page is empty. Else, check for empty listings on SpecialPages.
    if (
        pages.indexOf(page) === -1 ||
        skips.indexOf(page) !== -1 ||
        ($list.length === 0 && page !== 'Specialpages') ||
        (throttle && $list.length > 10 && page !== 'Specialpages') ||
        skipLimit < (Number(mw.util.getParamValue('limit')) || 0)
    ) {
        return;
    } else if (page === 'Specialpages') {
        pages.push('BrokenRedirects', 'DoubleRedirects');
        $('#mw-specialpagesgroup-maintenance + .mw-specialpages-list li').each(function() {
            var $this = $(this),
                exceptions = {
                    'Uncategorizedfiles': 'Uncategorizedimages', 
                    'Unusedfiles': 'Unusedimages',
                    'Brokenredirects': 'BrokenRedirects',
                    'Doubleredirects': 'DoubleRedirects'
                },
                link = $this.children('a').attr('title').substring(8);
            link = link.charAt(0) + link.slice(1).toLowerCase();

            if (link in exceptions) {
                link = exceptions[link];
            }
            if (pages.indexOf(link) === -1) {
                return;
            }

            $.getJSON(qstr + 'list=querypage&qppage=' + link, function(data) {
                var results = data.query.querypage.results;
                if (results.length === 0) {
                    takeAction($this);
                }
                if (
                    link === 'Uncategorizedcategories' &&
                    results.length === 1 &&
                    results[0].title === window.topLevelCat
                ) {
                    takeAction($this);
                }
            });
        });
        return;
    }
    
    // Handles marking the given element as resolved.
    function takeAction($el) {
        if (window.cacheCheckRemove) {
            $el.remove();
        } else {
            var $gallery = $el.find('.gallerytext a:first');
            if ($gallery.length) {
                if ($gallery.find('img')) {
                    // The link is actually on the image.
                    $el.remove();
                } else {
                    $gallery.wrap('<s></s>');
                }
            } else {
                $el.wrapInner('<s></s>');
            }
        }
    }

    // Takes list element, returns generated API query string.
    // Foo is 0 or 1 for lonelypages section.
    function getQS($this, foo) {
        var qs = qstr,
            select = isgallery ? '.gallerytext a:first' : 'a:first',
            url = $this.find(select).attr('href');

        if (page === 'Lonelypages') {
            qs += foo ? 'list=embeddedin&eititle=' : 'list=backlinks&bltitle=';
        }
        qs += encodeURIComponent(mw.util.getParamValue('title', url));

        return qs;
    }

    // Takes a JSON request result, returns array relevant to current page.
    function getData(data) {
        for (var i = 0; i < structure.length; i++) {
            if (structure[i] === 'placeholder') {
                //shortcut/hack thanks to https://archive.is/RwvEn
                for (var first in data) break;
                data = data[first];
            } else {
                data = data[structure[i]];
            }
            if (data === undefined) {
                return [];
            }
        }
        return data;
    }

    // Takes element in list, marks script as complete if it is the last list element.
    function checkComplete() {
        pending -= 1;
        if (pending <= 0) {
            $('#CacheCheck').text('CacheCheck completed!');
        } else {
            $('#CacheCheck').text('CacheCheck is running... (' + pending + ' remaining)');
        }
    }

    // Note: all desired data is in the format of an array,
    // which in the case of "prop=" queries is missing when there is no data,
    // and otherwise is empty.
    switch (page) {
        case 'Unusedtemplates':
        case 'Wantedtemplates':
            qstr += 'list=embeddedin&eititle=';
            structure.push('embeddedin');
            break;
        case 'Uncategorizedcategories':
        case 'Uncategorizedpages':
        case 'Uncategorizedtemplates':
        case 'Uncategorizedimages':
            qstr += 'prop=categories&titles=';
            structure.push('pages', 'placeholder', 'categories');
            break;
        case 'Unusedimages':
        case 'Wantedfiles':
            qstr += 'list=imageusage&iutitle=';
            structure.push('imageusage');
            break;
        case 'Unusedcategories':
        case 'Wantedcategories':
            qstr += 'list=categorymembers&cmtitle=';
            structure.push('categorymembers');
            break;
        case 'Wantedpages':
            qstr += 'list=backlinks&bltitle=';
            structure.push('backlinks');
            break;
        case 'Deadendpages':
            qstr += 'prop=links&titles=';
            structure.push('pages', 'placeholder', 'links');
            break;
        default:
            break;
    }

    function init() {
        $('.mw-spcontent').append(
            $('<p>', {
                id: 'CacheCheck',
                text: 'CacheCheck is running... (' + pending + ' remaining)'
            })
        );
        $list.each(function() {
            var $this = $(this);
            if (isgallery) {
                // Uncategorizedimages, Unusedimages
                if ($this.find('img').length) {
                    $.getJSON(getQS($this), function(data) {
                        data = getData(data);
                        if (data.length !== 0) {
                            takeAction($this);
                        }
                        checkComplete();
                    });
                } else {
                    takeAction($this);
                    checkComplete();
                }
            } else if (page === 'Lonelypages') {
                // The only one that needs two queries
                $.getJSON(getQS($this, 0), function(data) {
                    data = data.query.backlinks;
                    if (data.length && !($this.children('s').length)) {
                        takeAction($this);
                    }
                    checkComplete();
                });
                $.getJSON(getQS($this, 1), function(data) {
                    data = data.query.embeddedin;
                    if (data.length && !($this.children('s').length)) {
                        takeAction($this);
                    }
                    checkComplete();
                });
            } else {
                $.getJSON(getQS($this), function(data) {
                    data = getData(data);
                    if (removeIfFalse === (data.length === 0)) {
                        takeAction($this);
                    }
                    checkComplete();
                });
            }
        });
    }

    init();
});