Greasy Fork

Greasy Fork is available in English.

copymanga-自动存储浏览记录

自动存储拷贝漫画的浏览记录,以防拷贝卷记录跑路。

当前为 2024-03-31 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         copymanga-自动存储浏览记录
// @namespace    http://tampermonkey.net/
// @description  自动存储拷贝漫画的浏览记录,以防拷贝卷记录跑路。
// @version      1.1
// @author       Y_jun
// @license      MIT
// @icon         https://hi77-overseas.mangafuna.xyz/static/free.ico
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @match        *://*.copymanga.com/*
// @match        *://*.copymanga.org/*
// @match        *://*.copymanga.net/*
// @match        *://*.copymanga.info/*
// @match        *://*.copymanga.site/*
// @match        *://*.copymanga.tv/*
// @match        *://*.mangacopy.com/*
// @match        *://copymanga.com/*
// @match        *://copymanga.org/*
// @match        *://copymanga.net/*
// @match        *://copymanga.info/*
// @match        *://copymanga.site/*
// @match        *://copymanga.tv/*
// @match        *://mangacopy.com/*
// @run-at       document-start
// ==/UserScript==


let changeTotal = 1; //1:完整保存浏览记录,0:只保存前几页
let offset = 0;
let limit = 25;
let total = 50;
let lastIndex = 1;
let token = 'Token xxxxxxx'

function sleep(time) {
    return new Promise((resolve) => setTimeout(resolve, time));
}

function completeDate(value) {
    return value < 10 ? "0" + value : value;
}

function getNowFormatTime() {
    let nowDate = new Date();
    let colon = ":";
    let char = "-";
    let day = nowDate.getDate();
    let month = nowDate.getMonth() + 1;//注意月份需要+1
    let year = nowDate.getFullYear();
    let h = nowDate.getHours();
    let m = nowDate.getMinutes();
    let s = nowDate.getSeconds();
    //补全0,并拼接
    return year + char + completeDate(month) + char + completeDate(day) + " " + completeDate(h) + colon + completeDate(m) + colon + completeDate(s);
}

function addNotice() {
    let button = document.createElement('button');
    button.id = 'save-button';
    button.style.marginLeft = '20px';
    button.textContent = '开始保存完整记录';
    button.onclick = () => {
        button.className = 'allow-save-liulan';
    }

    let notice = document.createElement('span');
    notice.id = 'save-liulan';
    notice.style.marginLeft = '20px';
    notice.textContent = '尚未保存浏览记录';
    let collectActionArea = document.querySelector('.collectAction');

    collectActionArea.appendChild(button)
    collectActionArea.appendChild(notice);
}

function editNotice(text) {
    let notice = document.getElementById('save-liulan');
    notice.textContent = text;
}

function getPopularNum(popularStr) {
    if (popularStr.indexOf('W') > -1) {
        return Number(popularStr.substring(0, popularStr.length - 1)) * 10000;
    }
    if (popularStr.indexOf('K') > -1) {
        return Number(popularStr.substring(0, popularStr.length - 1)) * 1000;
    }
    return Number(popularStr);
}

async function getLiulanList() {
    const datetime = getNowFormatTime();
    while (offset < total) {
        if (!document.querySelector('.allow-save-liulan')) {
            await sleep(2000);
            continue;
        }
        editNotice('保存浏览记录中,进度:' + Math.round(offset / total * 10000) / 100 + "%");
        GM_xmlhttpRequest({
            method: "get",
            url: `${window.location.origin}/api/kb/web/browses?limit=${limit}&offset=${offset}&free_type=1`,
            data: "",
            headers: {
                "Content-Type": "application/json",
                "Authorization": token,
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36"
            },
            onload: res => {
                if (res.status === 200) {
                    const response = JSON.parse(res.response);
                    if (response.code === 200) {
                        const results = response.results;
                        total = changeTotal === 1 ? results.total : total;
                        const mangaList = results.list;
                        mangaList.forEach((manga) => {
                            const uuid = manga.comic.uuid;
                            const authors = [];
                            if (Array.isArray(manga.comic.author)) {
                                const authorList = manga.comic.author;
                                authorList.forEach((author) => {
                                    authors.push(author.name);
                                })
                            }
                            const mangaObj = {
                                "name": manga.comic.name,
                                "lastRead": manga.last_chapter_name,
                                "lastIndex": lastIndex,
                                "lastTime": datetime,
                                "lastChapter": manga.comic.last_chapter_name,
                                "updateTime": manga.comic.datetime_updated,
                                "popular": manga.comic.popular,
                                "authors": authors,
                                "path": manga.comic.path_word
                            }
                            lastIndex++;
                            GM_setValue(uuid, mangaObj);
                        });
                    } else {
                        editNotice('保存浏览记录出错');
                        console.log('code不为200:\n' + res);
                        total = 1;
                    }
                } else {
                    editNotice('保存浏览记录出错');
                    console.log('status不为200:\n' + res);
                    total = 1;
                }
            },
            onerror: () => {
                console.log('读取浏览记录失败');
            }
        });
        offset += limit;
        await sleep(2000);
    }
    editNotice('保存完毕');
}
function getLastRead(path, count = 1) {
    if (document.querySelector('.table-default') === null) {
        if (count <= 50) {
            const args = Array.from(arguments).slice(0, arguments.length);
            args.push(count + 1);
            setTimeout(getLastRead, 200, ...args);
        }
        return;
    }
    const name = document.querySelector('h6').textContent;
    const updateArr = document.querySelector('.table-default-right').textContent.split('更新');
    const lastChapter = updateArr[1].substring(3);
    const updateTime = updateArr[2].substring(3);
    const authors = document.querySelectorAll('.comicParticulars-right-txt')[1].innerHTML.match(/>[^<]+<\/a>/g);
    for (let i = 0; i < authors.length; i++) {
        const author = authors[i];
        authors[i] = author.substring(1, author.length - 4);
    }
    const popularStr = document.querySelectorAll('.comicParticulars-right-txt')[2].innerText;
    const popular = getPopularNum(popularStr);
    GM_xmlhttpRequest({
        method: "get",
        url: `${window.location.origin}/api/v3/comic2/${path}/query?platform=1&_update=true`,
        data: "",
        headers: {
            "Content-Type": "application/json",
            "Authorization": token,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36"
        },
        onload: res => {
            if (res.status === 200) {
                const response = JSON.parse(res.response);
                if (response.code === 200) {
                    const results = response.results;
                    if (results.browse) {
                        const mangaObj = {
                            "name": name,
                            "lastRead": results.browse.chapter_name,
                            "lastIndex": 0,
                            "lastTime": getNowFormatTime(),
                            "lastChapter": lastChapter,
                            "updateTime": updateTime,
                            "popular": popular,
                            "authors": authors,
                            "path": path
                        }
                        GM_setValue(results.browse.comic_uuid, mangaObj);
                    }
                } else {
                    console.log('code不为200:\n' + res);
                }
            } else {
                console.log('status不为200:\n' + res);
            }
        },
        onerror: () => {
            console.log('读取最近阅读失败');
        }
    });
}

window.onload = function () {
    const pathArr = window.location.pathname.split('/');
    if (window.location.pathname === '/web/person/liulan') {
        addNotice();
        getLiulanList();
    } else if (pathArr.length === 3 && pathArr[1] === 'comic') {
        document.addEventListener('visibilitychange', () => {
            getLastRead(pathArr[2].replace('#', ''));
        });
    }
}