Greasy Fork is available in English.

Bing Image Creator auto-download

Automatic image downloader for Bing Image Creator.

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name         Bing Image Creator auto-download
// @namespace    http://tampermonkey.net/
// @version      Alpha-v2
// @license      MIT
// @description  Automatic image downloader for Bing Image Creator.
// @match        https://www.bing.com/images/create*?*autosavetimer=*
// @grant        GM_download
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==
//
// I just pasted this together from things found scattered around the internet.  Primarily: https://github.com/Emperorlou/MidJourneyTools
//
// To enable periodic downloading of newly-created images, go to a 'recent creations' page, and add "&autosavetimer=60" to the URL;
// something like: `https://www.bing.com/images/create/-/1234?autosavetimer=60`.
//
// This implementation is designed to be left unattended - periodically reloading itself.  If you click a link it will disable the script,
// unless you remove `?*autosavetimer=*` from `@match` above.

(function() {
    'use strict';

    const downloadables = "img[src$='&pid=ImgGn']";
    var activeDownloads = 0;

    function get_download_url(img) {
      const src = img.attributes['src'].nodeValue;
      return src.replace(/\?.*$/, "?pid=ImgGn");
    }

    function get_filename(img, src, ref) {
        var url = new URL(src);
        var refurl = new URL(ref);
        var src_filename = url.pathname.split('/').pop();

        var ref_path = refurl.pathname.split('/');
        while (ref_path.length && ref_path.shift() != 'create')
            ;
        var pageid = (ref_path.length >= 2 && ref_path[1]) || refurl.searchParams.get('id') || "";
        var desc = (ref_path.length >= 2 && ref_path[0]) || refurl.searchParams.get('q') || "";
        //var desc = img.attr("alt", "");

        console.log("page id:", pageid, " src_filename:", src_filename, " description:", desc);

        return src_filename + "_" + pageid + "_" + desc + ".jpg";
    }

    function reload() {
        $("#girrcc").load(location.href + " #girrcc a");
        //window.location.reload(true);
    }

    function find_href(elem) {
        while (elem) {
            if (elem.hasAttribute('href')) return elem.href;
            elem = elem.parentElement;
        }
        return null;
    }

    $(document).ready(() => {
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = '.saved_image { border: 3px green dashed; }';

        document.head.appendChild(style);

        setInterval(() => {
            window.renderSavedImageIndicators();
            autoSaveNextImage();
        }, 500);
        launchInactivityTimer();
    });

    function launchInactivityTimer() {
        var timer;
        var params = new URLSearchParams(window.location.search);
        var timeout = params.get('autosavetimer') || 60;

        window.onload = resetTimer;
        document.onmousemove = resetTimer;
        document.onkeydown = resetTimer;

        function resetTimer() {
            clearInterval(timer);
            timer = setInterval(reload, timeout * 1000);
        }

        resetTimer();
    }

    function downloadFile(url, filename, referrer) {
        setUrlBusy(url);
        const download = GM_download({
            url: url,
            name: filename,
            saveAs: false,
            conflictAction: "uniquify",
            onload: function () {
                setUrlSaved(url);
            },
            onerror: function () {
                clearUrlBusy(url);
            },
            ontimeout: function () {
                clearUrlBusy(url);
            }
        });
    };

    function autoSaveNextImage() {
        // find thumbnails
        const allImages = $($(downloadables).get().reverse());
        for(const img of allImages) {
            const src = get_download_url(img);
            const ref = find_href(img) || "https://www.example.com/";

            if (isUrlReady(src)) {
                const filename = get_filename(img, src, ref);
                if (filename) {
                    downloadFile(src, filename, ref);
                }
                document.dispatchEvent(new Event("mousemove"));

                // Only start one image per timer loop.  Launching multiple downloads simultaneously may be unwise.
                break;
            }
        }
    }

    window.renderSavedImageIndicators = () => {
        const allImages = $(downloadables);
        for(const img of allImages) {
            const src = get_download_url(img);

            if (src && isUrlSaved(src))
                $(img).addClass("saved_image");
        }
    }

    function setUrlBusy(src) {
        sessionStorage.setItem("busyImage-" + src, Date.now());
        activeDownloads++;
        if (activeDownloads > 1) console.log("concurrent downloads:", activeDownloads);
    }

    function clearUrlBusy(src) {
        sessionStorage.removeItem("busyImage-" + src);
        activeDownloads--;
    }

    function setUrlSaved(src) {
        localStorage.setItem("savedImage-" + src, true);
        clearUrlBusy(src);
    }

    function isUrlSaved(src) {
        return localStorage.getItem("savedImage-" + src) === "true" ? true : false;
    }

    function isUrlReady(src) {
        if (!src || isUrlSaved(src)) return false;

        const stamp = sessionStorage.getItem("busyImage-" + src);
        if (!stamp) return true;
        if (Date.now() - stamp < 60000) {
            console.log("file has been busy too long (lost event?):", src);
            clearUrlBusy(src);
            return true;
        }
        console.log("still waiting to finish:", src);
        return false;
    }

})();