Chapter Downloader

Tự động trích xuất nội dung truyện từ truyen.tangthuvien.net

当前为 2025-03-09 提交的版本,查看 最新版本

// ==UserScript==
// @name         Chapter Downloader
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Tự động trích xuất nội dung truyện từ truyen.tangthuvien.net
// @author       TangThuVienExtractor
// @match        https://truyen.tangthuvien.net/doc-truyen/*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Biến toàn cục để theo dõi trạng thái trích xuất tự động
    let isAutomaticExtraction = false;

    // Tạo panel ở bên phải trang
    function createPanel() {
        // Tạo container chính cho panel
        const panel = document.createElement('div');
        panel.style.position = 'fixed';
        panel.style.top = '100px';
        panel.style.right = '20px';
        panel.style.width = '300px';
        panel.style.backgroundColor = '#f9f9f9';
        panel.style.border = '1px solid #ddd';
        panel.style.borderRadius = '5px';
        panel.style.padding = '10px';
        panel.style.zIndex = '9999';
        panel.style.display = 'flex';
        panel.style.flexDirection = 'column';
        panel.style.gap = '10px';
        panel.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.1)';

        // Tạo tiêu đề panel
        const title = document.createElement('h3');
        title.textContent = 'Trích xuất nội dung truyện';
        title.style.margin = '0 0 10px 0';
        title.style.textAlign = 'center';
        title.style.borderBottom = '1px solid #ddd';
        title.style.paddingBottom = '10px';
        panel.appendChild(title);

        // Tạo textarea để hiển thị nội dung đã trích xuất
        const textarea = document.createElement('textarea');
        textarea.style.width = '100%';
        textarea.style.height = '200px';
        textarea.style.padding = '8px';
        textarea.style.borderRadius = '3px';
        textarea.style.border = '1px solid #ddd';
        textarea.style.marginBottom = '10px';
        textarea.style.resize = 'vertical';
        panel.appendChild(textarea);

        // Lấy nội dung đã lưu từ localStorage (nếu có)
        const savedContent = localStorage.getItem('tangthuvien_extracted_content');
        if (savedContent) {
            textarea.value = savedContent;
        }

        // Tạo container cho các nút
        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.flexDirection = 'column';
        buttonContainer.style.gap = '5px';
        panel.appendChild(buttonContainer);

        // Tạo nút bắt đầu trích xuất
        const startButton = document.createElement('button');
        startButton.textContent = 'Bắt đầu lấy text';
        startButton.style.padding = '8px';
        startButton.style.backgroundColor = '#4caf50';
        startButton.style.color = 'white';
        startButton.style.border = 'none';
        startButton.style.borderRadius = '3px';
        startButton.style.cursor = 'pointer';
        startButton.addEventListener('click', function() {
            if (!isAutomaticExtraction) {
                isAutomaticExtraction = true;
                startButton.textContent = 'Đang trích xuất...';
                startButton.style.backgroundColor = '#ff9800';
                
                // Bắt đầu quá trình trích xuất tự động
                autoExtractAndNavigate();
            } else {
                isAutomaticExtraction = false;
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.backgroundColor = '#4caf50';
            }
        });
        buttonContainer.appendChild(startButton);

        // Tạo nút xóa nội dung
        const clearButton = document.createElement('button');
        clearButton.textContent = 'Xóa nội dung';
        clearButton.style.padding = '8px';
        clearButton.style.backgroundColor = '#f44336';
        clearButton.style.color = 'white';
        clearButton.style.border = 'none';
        clearButton.style.borderRadius = '3px';
        clearButton.style.cursor = 'pointer';
        clearButton.addEventListener('click', function() {
            textarea.value = '';
            localStorage.removeItem('tangthuvien_extracted_content');
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Đã xóa nội dung';
            notification.style.position = 'fixed';
            notification.style.bottom = '20px';
            notification.style.right = '20px';
            notification.style.backgroundColor = '#f44336';
            notification.style.color = 'white';
            notification.style.padding = '10px';
            notification.style.borderRadius = '5px';
            notification.style.zIndex = '10000';
            document.body.appendChild(notification);
            
            // Xóa thông báo sau 3 giây
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 3000);
        });
        buttonContainer.appendChild(clearButton);

        // Tạo nút sao chép nội dung
        const copyButton = document.createElement('button');
        copyButton.textContent = 'Sao chép nội dung';
        copyButton.style.padding = '8px';
        copyButton.style.backgroundColor = '#2196f3';
        copyButton.style.color = 'white';
        copyButton.style.border = 'none';
        copyButton.style.borderRadius = '3px';
        copyButton.style.cursor = 'pointer';
        copyButton.addEventListener('click', function() {
            textarea.select();
            document.execCommand('copy');
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Đã sao chép nội dung';
            notification.style.position = 'fixed';
            notification.style.bottom = '20px';
            notification.style.right = '20px';
            notification.style.backgroundColor = '#2196f3';
            notification.style.color = 'white';
            notification.style.padding = '10px';
            notification.style.borderRadius = '5px';
            notification.style.zIndex = '10000';
            document.body.appendChild(notification);
            
            // Xóa thông báo sau 3 giây
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 3000);
        });
        buttonContainer.appendChild(copyButton);

        // Thêm panel vào body
        document.body.appendChild(panel);
        
        // Trả về các phần tử để sử dụng sau này
        return {
            panel,
            textarea,
            startButton
        };
    }

    // Hàm trích xuất nội dung chương hiện tại
    function extractCurrentChapterContent() {
        const panelElements = document.querySelector('textarea');
        const startButton = document.querySelector('button');
        
        if (!panelElements || !startButton) {
            console.error('Không tìm thấy panel hoặc textarea');
            return false;
        }
        
        // Lấy tiêu đề chương
        const chapterTitle = document.querySelector('h2');
        if (!chapterTitle) {
            console.error('Không tìm thấy tiêu đề chương');
            return false;
        }
        
        // Lấy nội dung chương
        const chapterContentSelector = '.box-chap';
        const chapterContent = document.querySelector(chapterContentSelector);
        if (!chapterContent) {
            console.error('Không tìm thấy nội dung chương');
            return false;
        }
        
        // Xử lý nội dung
        let contentText = chapterContent.innerText || chapterContent.textContent;
        contentText = contentText.trim();
        
        // Thêm nội dung vào textarea
        let currentContent = panelElements.value || '';
        
        // Thêm dấu phân cách nếu đã có nội dung trước đó
        if (currentContent !== '') {
            currentContent += '\n\n------------\n\n';
        }
        
        // Thêm tiêu đề và nội dung
        currentContent += chapterTitle.innerText + '\n\n' + contentText;
        
        // Cập nhật textarea và lưu vào localStorage
        panelElements.value = currentContent;
        localStorage.setItem('tangthuvien_extracted_content', currentContent);
        
        // Hiển thị thông báo
        const notification = document.createElement('div');
        notification.textContent = 'Đã trích xuất: ' + chapterTitle.innerText;
        notification.style.position = 'fixed';
        notification.style.bottom = '20px';
        notification.style.right = '320px';
        notification.style.backgroundColor = '#4caf50';
        notification.style.color = 'white';
        notification.style.padding = '10px';
        notification.style.borderRadius = '5px';
        notification.style.zIndex = '10000';
        document.body.appendChild(notification);
        
        // Xóa thông báo sau 3 giây
        setTimeout(() => {
            document.body.removeChild(notification);
        }, 3000);
        
        return true;
    }

    // Hàm tự động trích xuất và chuyển trang
    function autoExtractAndNavigate() {
        if (!isAutomaticExtraction) {
            return;
        }
        
        // Trích xuất nội dung chương hiện tại
        const extractionSuccess = extractCurrentChapterContent();
        
        if (extractionSuccess) {
            // Tìm nút chuyển đến chương tiếp theo
            const nextButton = document.querySelector('.bot-next_chap.bot-control');
            
            // Kiểm tra xem có thông báo "Bạn đã đọc đến chương mới nhất" hay không
            const pageContent = document.body.innerText;
            if (pageContent.includes('Bạn đã đọc đến chương mới nhất')) {
                // Kết thúc quá trình khi thấy thông báo này
                isAutomaticExtraction = false;
                const startButton = document.querySelector('button');
                if (startButton) {
                    startButton.textContent = 'Bắt đầu lấy text';
                    startButton.style.backgroundColor = '#4caf50';
                }
                
                // Hiển thị thông báo hoàn thành
                const notification = document.createElement('div');
                notification.textContent = 'Đã hoàn thành trích xuất toàn bộ truyện!';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#4caf50';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 5 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 5000);
                return;
            }
            
            if (nextButton) {
                // Hiển thị thông báo
                const notification = document.createElement('div');
                notification.textContent = 'Đang chuyển đến chương tiếp theo...';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#ff9800';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 2 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 1000);
                
                // Nhấp vào nút chuyển trang
                nextButton.click();
                
                // Đợi 2 giây để trang mới tải xong, sau đó tiếp tục quá trình
                setTimeout(() => {
                    // Kiểm tra xem nút có bị ẩn hay không
                    const startButton = document.querySelector('button');
                    
                    // Nếu không tìm thấy nút hoặc nút không đúng trạng thái,
                    // bắt đầu trực tiếp quá trình trích xuất
                    
                    // Hiển thị thông báo đang đợi trang tải
                    const notification = document.createElement('div');
                    notification.textContent = 'Đợi trang tải xong...';
                    notification.style.position = 'fixed';
                    notification.style.bottom = '20px';
                    notification.style.right = '320px';
                    notification.style.backgroundColor = '#FFA500';
                    notification.style.color = 'white';
                    notification.style.padding = '10px';
                    notification.style.borderRadius = '5px';
                    notification.style.zIndex = '10000';
                    document.body.appendChild(notification);
                    
                    // Xóa thông báo và bắt đầu trích xuất sau 2 giây
                    setTimeout(() => {
                        document.body.removeChild(notification);
                        autoExtractAndNavigate();
                    }, 1000);
                }, 1000);
            } else {
                // Nếu không tìm thấy nút chuyển trang
                isAutomaticExtraction = false;
                const startButton = document.querySelector('button');
                if (startButton) {
                    startButton.textContent = 'Bắt đầu lấy text';
                    startButton.style.backgroundColor = '#4caf50';
                }
                
                // Hiển thị thông báo
                const notification = document.createElement('div');
                notification.textContent = 'Không tìm thấy nút chuyển trang';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#f44336';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 5 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 5000);
            }
        } else {
            // Nếu trích xuất thất bại
            isAutomaticExtraction = false;
            const startButton = document.querySelector('button');
            if (startButton) {
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.backgroundColor = '#4caf50';
            }
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Trích xuất thất bại';
            notification.style.position = 'fixed';
            notification.style.bottom = '20px';
            notification.style.right = '320px';
            notification.style.backgroundColor = '#f44336';
            notification.style.color = 'white';
            notification.style.padding = '10px';
            notification.style.borderRadius = '5px';
            notification.style.zIndex = '10000';
            document.body.appendChild(notification);
            
            // Xóa thông báo sau 5 giây
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 5000);
        }
    }

    // Khởi tạo panel khi trang đã tải xong
    window.addEventListener('load', function() {
        // Đợi 1 giây để đảm bảo trang đã tải hoàn toàn
        setTimeout(() => {
            createPanel();
        }, 1000);
    });
})();