Imgur Archivist

Checks whether dead Imgur links are archived and replaces them.

目前為 2023-08-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name Imgur Archivist
// @namespace https://reddit.com/u/VladVV/
// @version 0.7
// @description Checks whether dead Imgur links are archived and replaces them.
// @author /u/VladVV
// @match *://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=archive.org
// @grant none
// @license EUPL v1.2
// ==/UserScript==

(function () {
    'use strict';

    // A dictionary to store the dead Imgur URLs and their archived versions
    var imgurArchive = {};

    // A function to check if an Imgur link is dead or alive
    function checkImgurLink(url) {
        if (url in imgurArchive) return; //Abort if url has already been checked
        var xhr = new XMLHttpRequest();
        xhr.open('HEAD', url);
        xhr.onreadystatechange = function () {
            if (this.readyState === this.DONE) {
                if (this.responseURL.indexOf('removed.png') !== -1 || this.status === 404) {
                    // Imgur image is removed or deleted
                    // Setup a GET request to the archive.org API
                    var archiveUrl = 'https://archive.org/wayback/available?url=' + url;
                    var archiveXhr = new XMLHttpRequest();
                    archiveXhr.open('GET', archiveUrl);
                    archiveXhr.onreadystatechange = function () {
                        if (this.readyState === this.DONE) {
                            var response = JSON.parse(this.responseText);
                            if (response.archived_snapshots.closest) {
                                // Archived image found
                                // Add the dead link and the archived link to the dictionary
                                imgurArchive[url] = response.archived_snapshots.closest.url;
                            } else {
                                // The removed image is not archived :(
                                imgurArchive[url] = false;
                            }
                        }
                    };
                    archiveXhr.send();
                } else {
                    // Imgur image is live; our services aren't needed.
                    imgurArchive[url] = true;
                }
            }
        };
        xhr.send();
    }


    const archive_org_re = /^(?:https?:\/\/)?(?:web\.archive\.org\/web\/\d+\/)/
    // A function to replace an Imgur link with its archived version if it exists in the dictionary
    function replaceImgurLink(link) {
        var url = link.href;
        if (url in imgurArchive || url.replace(archive_org_re, '') in imgurArchive) {
            if (imgurArchive[url] !== true && imgurArchive[url] !== false) {
                // Save old element attributes to be restored
                let old_style = link.style; let old_title = link.title;

                // Set temporary element attributes
                link.style.color = 'green';
                link.style.outline = 'thin dotted green';
                link.title = "Archived image available. (Imgur link is dead)";

                // Set archive link if not already set
                if (url in imgurArchive) link.setAttribute('href', imgurArchive[url]);

                // Add event listener to restore old element attributes
                link.addEventListener('mouseleave', function () {
                    link.style = old_style; link.title = old_title;
                }, { once: true });
            } else if (imgurArchive[url] === false) {
                // Save old element attributes to be restored
                let old_style = link.style; let old_title = link.title;

                // Set temporary element attributes
                link.style.color = 'red';
                link.style.outline = 'thin dotted red';
                link.title = "No archived image available. (Imgur link is dead)";

                // Add event listener to restore old element attributes
                link.addEventListener('mouseleave', function () {
                    link.style = old_style; link.title = old_title;
                }, { once: true });
            }
        }
    }

    // A list of <a> elements that have already been processed (for dynamic content loading)
    var old_links = [];
    function updateLinks() {
        // Get all the links in the document
        var links = Array.from(document.getElementsByTagName('a'));

        // Filter out link tags that have already been processed
        if (old_links !== []) {
            for (let i = 0; i < links.length; i++) {
                if (links[i] in old_links) {
                    links.splice(i, 1);
                } else {
                    old_links.push(links[i]);
                }
            }
        } else {
            old_links = links;
        }

        // Loop through the links and check if they are Imgur links
        for (let i = 0; i < links.length; i++) {
            if (links[i].href.indexOf('imgur') !== -1 && links[i].href.indexOf('archive.org') === -1) {
                checkImgurLink(links[i].href);
            }
        }
    }
    updateLinks();

    // Create an observer instance to respond to new content loaded dynamically by the page
    var observer = new MutationObserver (function (mutations) {
        mutations.forEach (function (mutation) {
            if (mutation.type === "childList") {
                mutation.addedNodes.forEach (function (node) {
                    var links = node.querySelectorAll('a');
                    for (let i = 0; i < links.length; i++) {
                        if (links[i].href.indexOf('imgur') !== -1 && links[i].href.indexOf('archive.org') === -1) {
                            checkImgurLink(links[i].href);
                            old_links.push(links[i]);
                        }
                    }
                });
            }
        });
    });
    observer.observe(document.documentElement || document.body, {childList: true, subtree: true});

    // Add an event listener to the whole document that waits for hovers on links
    document.addEventListener('mouseover', function (event) {
        // Get the target element of the hover event
        var target = event.target;
        //Traverse the DOM tree until we find a link (or not)
        while (target && target.tagName !== 'A') {
            target = target.parentNode;
        }
        // If a link is found, replace it with its archived version if possible
        if (target) {
            replaceImgurLink(target);
        }
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址