JDipi / Smugmug-Album-Downloader

Downloads high quality images from SmugMug albums
GNU General Public License v3.0
3 stars 1 forks source link

Throttle requests #4

Open sulfurcatwalk opened 3 months ago

sulfurcatwalk commented 3 months ago

dont want to DOS them and get blocked

noahkrueger commented 6 hours ago

This updated script was able to help me overcome the throttling.

// ==UserScript== // @name Smugmug Album Downloader // @namespace http://tampermonkey.net/ // @version 0.1 // @description Smugmug Album Downloader // @author Your Name // @match https://*.smugmug.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js // @grant GM_download // @grant GM_addStyle // @grant GM_info // ==/UserScript==

(function() { 'use strict';

// Wait for the page to fully load
window.onload = function() {
    console.log('Page has loaded');

    // Verify if the target element exists before inserting the button
    if ($(".sm-gallery-cover-title").length > 0) {
        console.log('Found .sm-gallery-cover-title');

        // Append the download button to the .sm-gallery-cover-title element
        $(`<button id="downloadAlb">Download Album</button>`).appendTo(".sm-gallery-cover-title");

        GM_addStyle(`
          .sm-gallery-cover-title {
            display: flex;
            gap: 10px;
            align-items: center;
          }
          #downloadAlb {
            height: 40px;
            border-radius: 10px;
          }
          #downloadAlb:hover {
            background-color: gray;
          }
        `);

        // Handle button click event
        $("#downloadAlb").on("click", async function () {
            try {
                let albumId, albumKey;

                // Try to extract album information from link or fallback to script method
                let linkElement = $("link[rel='alternate'][type*='rss+xml']");

                if (linkElement.length > 0) {
                    let url = linkElement.attr("href");
                    let albumRegex = url.match(/\d*_[a-zA-Z\d]*/gm)[0].split("_");
                    albumId = albumRegex[0];
                    albumKey = albumRegex[1];
                } else {
                    console.log('RSS link not found, falling back to script method.');

                    let raw = $('script[crossorigin][type=module]:not(script[src])')["0"].outerHTML;
                    albumId = raw.match(/albumId":(\d*)/)[1];
                    albumKey = raw.match(/albumKey":"(.+?)"/)[1];
                }

                console.log(`Album ID: ${albumId}, Album Key: ${albumKey}`);

                const settings = {
                    async: true,
                    crossDomain: true,
                    url: `https://${document.location.hostname}/services/api/json/1.4.0?galleryType=album&albumId=${albumId}&albumKey=${albumKey}&PageNumber=2&imageId=0&returnModelList=true&PageSize=5000&method=rpc.gallery.getalbum`,
                    method: "GET",
                };

                console.log('Starting the API request...');

                const response = await $.ajax(settings);
                console.log('API response received:', response);

                if (response.Images && response.Images.length > 0) {
                    console.log(`Total Images Found: ${response.Images.length}`);

                    for (let image of response.Images) {
                        let picID = image.GalleryUrl.split("/").slice(-1)[0];
                        let height = 0;
                        let largestSize = "";
                        let ext = "";

                        // Get the largest image size
                        for (let size in image.Sizes) {
                            if (image.Sizes[size].usable && image.Sizes[size].height > height) {
                                height = image.Sizes[size].height;
                                largestSize = size;
                                ext = image.Sizes[size].ext;
                            }
                        }

                        let imageUrl = `https://photos.smugmug.com/photos/${picID}/0/${largestSize}/${picID}-${largestSize}.${ext}`;
                        console.log(`Downloading Image: ${imageUrl}`);

                        GM_download({
                            url: imageUrl,
                            name: `${picID}-${largestSize}.${ext}`,
                            onload: () => {
                                console.log(`Download complete: ${picID}`);
                            },
                            onerror: (e) => {
                                console.error(`Error downloading image ${picID}:`, e);
                            }
                        });

                        await new Promise(resolve => setTimeout(resolve, 500));
                    }
                } else {
                    console.log('No images found in the response.');
                }
            } catch (error) {
                console.error('Error:', error);
            }
        });
    } else {
        console.log('.sm-gallery-cover-title not found, button not inserted.');
    }
};

})();