Sadpanda Save/Export All Favorites

Load all favorites to the page and save it or just copy the textbox contents. Works on exhentai and e-hentai.

Fra 26.07.2019. Se den seneste versjonen.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Sadpanda Save/Export All Favorites
// @namespace   SaddestPanda
// @description Load all favorites to the page and save it or just copy the textbox contents. Works on exhentai and e-hentai.
// @include     /^https?://e.hentai\.org/favorites.php.*/
// @homepage    https://greasyfork.org/en/scripts/23406-sadpanda-save-export-all-favorites
// @supportURL  https://greasyfork.org/en/scripts/23406-sadpanda-save-export-all-favorites/feedback
// @version     2.3.1
// @grant       GM.getValue
// @grant       GM.setValue
// @grant       GM.deleteValue
// @grant       GM_addValueChangeListener
// @grant       GM.addValueChangeListener
// @require     https://greasyfork.org/scripts/371339-gm-webextpref/code/GM_webextPref.js?version=623327
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/he/1.2.0/he.min.js
// ==/UserScript==

//Top text box inspiration and its code from http://userscripts-mirror.org/scripts/show/173553. But this one won't have an import feature like that one.
//Using Jquery for jquery purposes and he.js for he.js purposes.
//Using GM_webextPref for the preferences menu. Many thanks to the author "eight" for the library. Greasyfork libraries use a specific version so they should be from malicious updates.

//Use the options menu to change these values.
var inserttoTable = true; //Disables inserting new pages to the table. Set this to false if your browser gets real slow. You can still use the textbox to save your favorites.
var pageTimer = 5000; //Waiting timer for each page in miliseconds. Default is 2500. Making it too short might prevent pages from loading.

const pref = GM_webextPref({
    default: {
        inserttoTable: true,
        pageTimer: 5000
    },
    body: [{
            key: "inserttoTable",
            type: "checkbox",
            label: "Insert new pages into the current page. Disable this if your browser freezes."
        },
        {
            key: "pageTimer",
            type: "number",
            label: "Time (ms) to load each page. Keep this higher than 2000 especially if you set the thumbnails to load with the page."
        }
    ]
});

var counter = 0,
    showExport = 0,
    pageNumber = "",
    winlocsea = "?";
var displayMode = $("#dms [selected='selected']")[0].value; // m:minimal, p:minimal+, l:compact, e:extended, t:thumbnail
//console.log(displayMode);
if (window.location.search == "") {
    winlocsea = "?";
} else {
    winlocsea = window.location.search;
}
var PageUrl = "favorites.php" + winlocsea + "&page=";

function destroyBox() {
    $('.uselessbr').each(function() { $(this).remove(); });
    $('#exportFav').remove();
    $('#exportStatus').remove();
}

function getPageNumber() {
    var finalcell = $(".ptt")[0].rows[0].cells[$(".ptt")[0].rows[0].cells.length - 2];
    pageNumber = finalcell.textContent;
}

function addRemoveButton() {
    $('#exportFav').after("<div>");
    $('#exportFav').next().append($('<input/>').attr('type', 'button').attr('value', 'Remove titles from the list').attr('id', 'removeTitles').attr('style', 'margin-top:5px;min-height:18px;'));
    $('#removeTitles').click(removeTitles);
}

function removeTitles() {
    $('#exportFav')[0].textContent = $('#exportFav')[0].textContent.replace(/( - .*)/g, "");
}

function getText(thisa) {
    var thetext = "";
    if (displayMode == "e") {
        thetext = he.encode(thisa.href + " - " + thisa.children[0].children[0].innerText);
    } else if (displayMode == "l") {
        thetext = he.encode(thisa.href + " - " + thisa.children[0].innerText);
    } else {
        thetext = he.encode(thisa.href + " - " + thisa.text);
    }
    $('#exportFav').append(thetext + '\n');
}

function getThisPage() {
    var trlen, thislink, j = 0;
    if (displayMode == "e") {
        trlen = $(".glink").length;
        for (j = 0; j < trlen; j++) {
            thislink = $(".glink")[j].parentNode.parentNode;
            getText(thislink);
        }
    } else {
        trlen = $(".itg .glname").length;
        for (j = 0; j < trlen; j++) {
            thislink = $(".itg .glname a")[j];
            getText(thislink);
        }
    }
}

function exportFavorites() {
    if (showExport === 0) {
        showExport = 1;
        $('#nb').after('<br class="uselessbr"/>');
        $('#nb').after($('<input/>').attr('type', 'button').attr('value', 'START').attr('id', 'startBut').attr('href', 'javascript:void(0)').attr('style', 'margin-left:5px;margin-top:5px;min-height:18px;'));
        $('#startBut').click(getThePages);
        $('#nb').after($('<input/>').attr('type', 'button').attr('value', 'Options').attr('id', 'optionsBut').attr('href', 'javascript:void(0)').attr('style', 'margin-top:5px;min-height:18px;'));
        $('#optionsBut').click(pref.openDialog);
        $('#nb').after('<br class="uselessbr"/>');
        $('#nb').after('<textarea id="exportStatus" name="Text2" cols="80" rows="8" ... />');
        $('#nb').after('<h2 class="uselessbr">Status');
        $('#nb').after('<textarea id="exportFav" name="Text1" cols="80" rows="7" ... />');
        $('#nb').after('<h2 class="uselessbr">Text List of Favorites');
        $('#nb').after('<br class="uselessbr"/><br class="uselessbr"/>');
        $('#exportStatus').append("Currently the website is not that slow but keep the delay between pages higher than 3000 or your pages & thumbnails might not load." + '\n\n');
        $('#exportStatus').append("Chrome and some other browsers throttle background tabs so if you switch to another tab it might prevent you from loading all the pages." + '\n');
        $('#exportStatus').append("To bypass that; turn this tab into its own window before you start and don't minimize it." + '\n');
        if (pageNumber > 10) {
            $('#exportStatus').append("You more than 10 pages. If your browser crashes disable inserting to the page from the options." + '\n\n');
        }
        $('#exportStatus').append("Press START below to start loading the pages." + '\n');
    } else {
        //destroyBox();
        //showExport = 0;
        return;
    }

    if (window.location.search.indexOf("page=") != -1) {
        $('#exportFav').append("GO TO THE FIRST PAGE AND TRY AGAIN" + '\n');
        $('#exportStatus').append("GO TO THE FIRST PAGE AND TRY AGAIN" + '\n');
        return;
    }
}

function getThePages() {
    inserttoTable = pref.get("inserttoTable");
    pageTimer = pref.get("pageTimer");
    getThisPage();
    if (pageNumber > 1) {
        $('#exportStatus').append("Loading all pages will take " + (Math.ceil(pageTimer / 100) * (pageNumber)) / 10 + " seconds." + '\n');
        //$('#exportStatus').append("NOTICE - If your browser completely freezes, try using the newest Firefox/Chrome with tampermonkey/violentmonkey or help me fix it." + '\n');
        for (var ii = 1; ii < pageNumber; ii++) {
            //console.log("Queued page: " + ii);
            setTimeout(function() {
                counter++;
                //console.log("Current page: " + counter);
                $('#exportStatus').append("Loading Page " + (counter + 1) + " of " + pageNumber + "..." + '\n');
                if ((counter + 1) == pageNumber) {
                    setTimeout(function() {
                        $('#exportStatus').append("Loading complete." + '\n' + "Copy above list, Ctrl+S to save the page or use an extension like SingleFile or Save Page WE." + '\n');
                        addRemoveButton();
                        $('#exportStatus').append("Confirmation: " + ($('#exportFav')[0].value.split("\n").length - 1) + " favorites in above text area, " + ($(".itg .glname a").length + $(".gl4e .glink").length) + " favorites in below page." + '\n');
                        if (pageNumber > 10) {
                            $('#exportStatus').append("If your gallery count doesn't add up, try again. You can load the pages faster now that you cached all the thumbnails." + '\n\n');
                        }
                        $('#exportStatus').scrollTop($('#exportStatus')[0].scrollHeight);
                    }, pageTimer + 2500);
                }
                $('#exportStatus').scrollTop($('#exportStatus')[0].scrollHeight);
                $.ajax({
                    url: PageUrl + counter,
                    type: 'GET',
                    tryCount: 0,
                    retryLimit: 5,
                    success: function(sss) {
                        //do something
                        var trlen, thislink, j = 0;
                        trlen = (displayMode == "e") ? $(sss).find(".glink").length : $(sss).find(".itg .glname").length;
                        for (j = 0; j < trlen; j++) {
                            thislink = (displayMode == "e") ? $(sss).find(".glink")[j].parentNode.parentNode : $(sss).find(".itg .glname a")[j];
                            getText(thislink);
                            if (inserttoTable) {
                                if (displayMode != "t") {
                                    $(".itg tbody")[0].append($(thislink).parents("tr:first")[0]);
                                } else {
                                    $(".itg")[0].append($(thislink).parents(".gl1t")[0]);
                                }
                            }
                        }
                    },
                    error: function(xhr, textStatus, errorThrown) {
                        this.tryCount++;
                        if (this.tryCount <= this.retryLimit) {
                            //try again
                            $.ajax(this);
                            return;
                        }
                        return;
                        /*
                        if (textStatus == 'timeout') {

                        }
                        if (xhr.status == 500) {
                            //handle error
                        } else {
                            //handle error
                        }
                        */
                    }
                });

            }, 200 + ii * pageTimer);
        }
    } else {
        $('#exportStatus').append("Loading complete." + '\n' + "Copy above list, Ctrl+S to save the page or use an extension like SingleFile or Save Page WE." + '\n');
        $('#exportStatus').append("Confirmation: " + ($('#exportFav')[0].value.split("\n").length - 1) + " favorites in above text area, " + ($(".itg .glname a").length + $(".gl4e .glink").length) + " favorites in below page." + '\n');
        addRemoveButton();
    }
}

$(document).ready(function() {
    var topmenu = document.querySelector("#nb");
    topmenu.style.justifyContent = "center";
    topmenu.style.maxWidth = "1400px";
    $('#nb').append($('<div/>').attr('id', 'exportFavsdiv'));
    $('#exportFavsdiv').append($('<a/>').attr('href', 'javascript:void(0)').attr('id', 'exportFavorites').text('Load All Favorites'));
    $('#exportFavorites').click(exportFavorites);
    document.querySelector("#exportFavsdiv").style.marginLeft = "8px";
    getPageNumber();
});