Chapter Downloader

Tự động lấy nội dung từ chương hiện tại đến chương cuối cùng trên truyen.tangthuvien.vn

当前为 2025-04-21 提交的版本,查看 最新版本

// ==UserScript==
// @name         Chapter Downloader
// @namespace    http://tampermonkey.net/
// @version      4.0
// @description  Tự động lấy nội dung từ chương hiện tại đến chương cuối cùng trên truyen.tangthuvien.vn
// @author       You
// @match        https://truyen.tangthuvien.vn/doc-truyen/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    let chapterUrls = [];
    let isAutoDownloading = false;
    let isLoaded = false;

    // Giao diện
    const panel = document.createElement('div');
    panel.innerHTML = `
    <div style="position: fixed; top: 10%; right: 10px; width: 300px; z-index: 9999; background: #fff; border: 1px solid #ccc; padding: 10px; font-family: sans-serif;">
        <textarea id="content-textarea" style="width: 100%; height: 200px; margin-bottom: 10px;"></textarea>
        <button id="start-btn">Bắt đầu</button>
        <button id="clear-btn">Xoá</button>
        <button id="copy-btn">Sao chép</button>
        <div style="margin-top:5px; font-size: 12px; color: gray;">Tự động từ chương hiện tại đến hết.</div>
    </div>`;
    document.body.appendChild(panel);

    const textarea = document.getElementById('content-textarea');
    const startBtn = document.getElementById('start-btn');
    const clearBtn = document.getElementById('clear-btn');
    const copyBtn = document.getElementById('copy-btn');

    // Lưu và khôi phục nội dung
    textarea.value = localStorage.getItem('chapterDownloaderContent') || '';
    textarea.addEventListener('input', () => {
        localStorage.setItem('chapterDownloaderContent', textarea.value);
    });

    clearBtn.onclick = () => {
        textarea.value = '';
        localStorage.removeItem('chapterDownloaderContent');
    };

    copyBtn.onclick = () => {
        textarea.select();
        document.execCommand('copy');
        alert('Đã sao chép!');
    };

    function extractChapterContent() {
        const title = document.querySelector('h2')?.innerText.trim();
        const content = document.querySelector('.box-chap')?.innerText.trim();
        if (!title || !content) return false;

        textarea.value += `\n\n---\n\n${title}\n\n${content}`;
        localStorage.setItem('chapterDownloaderContent', textarea.value);
        return true;
    }

    async function fetchChapterList() {
        const storySlug = window.location.pathname.split('/')[2];
        const listUrl = `https://truyen.tangthuvien.vn/danh-sach-chuong/${storySlug}`;

        const html = await fetch(listUrl).then(res => res.text());
        const temp = document.createElement('div');
        temp.innerHTML = html;

        const links = Array.from(temp.querySelectorAll('a[href*="/doc-truyen/"]'));
        const urls = links.map(a => a.href.split('?')[0]);
        return [...new Set(urls)];
    }

    async function startAutoDownload() {
        isAutoDownloading = true;
        startBtn.textContent = 'Đang chạy...';

        if (!isLoaded) {
            chapterUrls = await fetchChapterList();
            isLoaded = true;
        }

        const currentUrl = window.location.href.split('?')[0];
        let startIndex = chapterUrls.findIndex(url => url === currentUrl);

        if (startIndex === -1) {
            alert('Không tìm thấy chương hiện tại trong danh sách!');
            isAutoDownloading = false;
            return;
        }

        for (let i = startIndex; i < chapterUrls.length; i++) {
            const url = chapterUrls[i];
            console.log(`Tải chương ${i + 1}: ${url}`);
            await fetch(url)
                .then(res => res.text())
                .then(html => {
                    const temp = document.createElement('div');
                    temp.innerHTML = html;

                    const title = temp.querySelector('h2')?.innerText.trim();
                    const content = temp.querySelector('.box-chap')?.innerText.trim();

                    if (title && content) {
                        textarea.value += `\n\n---\n\n${title}\n\n${content}`;
                        localStorage.setItem('chapterDownloaderContent', textarea.value);
                    } else {
                        console.warn('Không lấy được nội dung chương:', url);
                    }
                });

            await new Promise(resolve => setTimeout(resolve, 1000)); // nghỉ 1s
        }

        alert('Đã tải xong toàn bộ chương!');
        startBtn.textContent = 'Bắt đầu';
        isAutoDownloading = false;
    }

    startBtn.onclick = () => {
        if (!isAutoDownloading) {
            startAutoDownload();
        }
    };
})();