fc2 show all products

show full list of products in 1 page and sort by id / show full title

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         fc2 show all products
// @namespace    https://github.com/x94fujo6rpg/SomeTampermonkeyScripts
// @version      0.3
// @description  show full list of products in 1 page and sort by id / show full title
// @author       x94fujo6
// @match        https://adult.contents.fc2.com/*
// @grant        none
// ==/UserScript==
/* jshint esversion: 9 */

(function () {
    'use strict';
    let msgid = "fc2_script_message";
    let listener = false;

    window.document.body.onload = () => {
        startScript();
    };

    function dPrint(...any) {
        console.log(`[${msgid}]: `, ...any);
    }

    function startScript() {
        if (document.visibilityState == "visible") {
            if (listener) {
                document.removeEventListener("visibilitychange", startScript);
                //dPrint("remove event listener");
            } else {
                //dPrint("normal start");
            }
            setReload();
            checkLink();
        } else {
            document.addEventListener("visibilitychange", startScript);
            //dPrint("document not visible, set event listener");
            listener = true;
        }
    }

    function setReload() {
        let menu = document.querySelector("[data-menulist]");
        if (!menu) return;
        let links = menu.querySelectorAll("a");
        links.forEach(a => {
            if (a.getAttribute("reload")) return;
            a.onclick = (event) => {
                event.preventDefault();
                document.location.href = a.href;
            };
            a.setAttribute("reload", true);
        });
    }

    function checkLink() {
        let link = document.location.href;
        //dPrint(`link: ${link}`);
        if (link.match(/users\/[^\/]+\/articles\?sort=date&order=desc/)) {
            let regtest = link.match(/page=(\d+)/);
            let page = regtest ? regtest[1] : false;
            if (regtest) page = (page == 1) ? true : false;
            if (!regtest || page) {
                dPrint("listview");
                dPrint(`script start, link: ${link}`);
                sortList();
            }
        } else if (link.match(/article_search.php\?id=\d+/) || link.match(/\/article\/\d+\//)) {
            dPrint("productpage");
            productpage();
        }
    }

    function updateMessage(text = "") {
        document.getElementById(msgid).textContent = text;
        dPrint(text);
    }

    function sortList() {
        let pos = document.querySelector("section.seller_user_articlesList");
        let products;
        let list;
        
        if (!pos) return;

        dPrint("sortList");
        products = [...pos.children];
        list = products.map(div => processDiv(div));

        document.querySelector(".c-pager-101").remove();
        list.sort((a, b) => b.id - a.id);

        products.forEach(e => e.remove());
        list.forEach(data => { pos.appendChild(data.ele); });

        let message = Object.assign(document.createElement("span"), {
            id: msgid,
            textContent: "script start",
            style: `
                    display: inline-block;
                    margin: 0.5rem;
                    color: gold;
                `,
        });
        document.querySelector("div.seller_user_articles_pageHeader").appendChild(message);
        getAllProduct();

        async function getAllProduct() {
            let total = document.querySelector(".seller_user_articles_pageHeaderCount");
            if (!total) return;
            total = total.textContent.match(/\((\d*)\)/)[1];
            total = parseInt(total, 10);

            let max_page = Math.ceil(total / 30);
            if (max_page == 1) {
                updateMessage(`only 1 page, abort`);
            } else {
                let user = document.location.href.match(/users\/([^\/]*)\/articles/)[1];
                let url = `https://adult.contents.fc2.com/users/${user}/articles?sort=date&order=desc&deal=&page=`;
                updateMessage(`max page = ${max_page}, start to retrieve data`);

                for (let page = 2; page <= max_page; page++) {
                    updateMessage(`processing... please wait [page: ${page}, total: ${max_page}]`);
                    await getPage(url, page)
                        .then(async (resolve) => {
                            await resort(resolve, page);
                        })
                        .catch((reject) => {
                            updateMessage(`somthing went wrong...script stopped`);
                            dPrint(reject);
                            return;
                        });
                }
            }
            updateMessage(`done`);

            function getPage(rq_url, page) {
                return new Promise((resolve, reject) => {
                    let rq = new XMLHttpRequest();
                    rq.open("GET", `${rq_url}${page}`);
                    rq.onreadystatechange = function () {
                        if (rq.readyState == 4) {
                            return (rq.status == 200) ? setTimeout(resolve, 500, rq.responseText) : reject(rq.responseText);
                        }
                    };
                    rq.send(null);
                });
            }

            function resort(data) {
                return new Promise((resolve, reject) => {
                    let current = getCurrentProduct();
                    if (!current) return reject(false);

                    data = extractProducts(data);
                    current.push(...data);
                    current.sort((a, b) => b.id - a.id);

                    let pos = document.querySelector("section.seller_user_articlesList");
                    [...pos.children].forEach(e => e.remove());

                    current.forEach(p => pos.appendChild(p.ele));

                    data = null;
                    current = null;
                    return resolve(true);
                });

                function getCurrentProduct() {
                    let pos = document.querySelector("section.seller_user_articlesList");
                    if (pos) {
                        return [...pos.children].map(ele => {
                            return {
                                id: ele.querySelector("a").href.match(/id=(\d*)/)[1],
                                ele: ele.cloneNode(true),
                            };
                        });
                    } else {
                        return false;
                    }
                }

                function extractProducts(domtext) {
                    let parser = new DOMParser();
                    let new_document = parser.parseFromString(domtext, "text/html");
                    let pos = new_document.querySelector("section.seller_user_articlesList");
                    let products = [...pos.children];
                    let list = products.map(div => processDiv(div));
                    parser = null; // release memory
                    new_document = null;
                    return list;
                }
            }
        }
    }

    function processDiv(div) {
        let id = div.querySelector("a").href.match(/id=(\d*)/)[1];
        let box = div.querySelector(".c-cntCard-110-f_indetail");
        let title_ele = div.querySelector(".c-cntCard-110-f_itemName");
        let title_span = convertToSpan(title_ele);
        let id_span = Object.assign(document.createElement("span"), {
            textContent: id,
            style: `font-size: 1.5rem;`,
        });
        let all_link;
        let remove_ele = [
            ".items_article_SmapleVideo",
            "span.c-cntCard-110-f_thumb_type",
            "button",
            "section.c-tooltip-107",
            ".detail-layout",
            ".c-cntCard-110-f_seller",
        ];
        box.insertAdjacentElement("afterbegin", title_span);
        box.insertAdjacentElement("afterbegin", id_span);
        title_ele.remove();

        div.querySelector("img").setAttribute("loading", "lazy");
        remove_ele.forEach(css_selector => {
            removeFromEle(div, css_selector);
        });

        all_link = div.querySelectorAll("a");
        if (all_link) all_link.forEach(a => { a.target = "_blank"; });
        return { id: id, ele: div.cloneNode(true) };

        function removeFromEle(ele, css_selector) {
            let target = ele.querySelector(css_selector);
            if (target) target.remove();
        }

        function convertToSpan(ele) {
            return Object.assign(document.createElement("span"), {
                textContent: ele.textContent,
                className: ele.className,
                style: `
                    overflow: visible;
                    display: inline-block;
                    width: auto;
                `,
            });
        }
    }

    function productpage() {
        let data = document.querySelector("[type='application/ld+json']").textContent;
        data = JSON.parse(data);
        let id = data.productID;
        let title = data.name;
        let pos = document.querySelector(".items_article_headerInfo h3");
        let e = newButton(`Copy [${id} ${title}]`, `${id} ${title}`);
        pos.insertAdjacentElement("afterend", e);
    }

    function newButton(text, copy) {
        let e = document.createElement("a");
        e.style = "color: deeppink; font-size: 1.5rem;";
        e.textContent = text;
        e.onclick = function () {
            navigator.clipboard.writeText(repalceForbiddenChar(copy));
        };
        return e;
    }

    function repalceForbiddenChar(string = "") {
        let forbidden = `<>:"/|?*\\`;
        let replacer = `<>:”/|?*\`;
        for (let index of forbidden) {
            string = string.replaceAll(forbidden[index], replacer[index]);
        }
        return string.trim();
    }
})();