Greasy Fork

Greasy Fork is available in English.

Bing Image Creator auto-download

Automatic image downloader for Bing Image Creator.

当前为 2023-08-14 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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;
    }

})();