TTV Auto Upload

Tự động điền form đăng chương trên tangthuvien.net với tính năng nâng cao

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

// ==UserScript==
// @name         TTV Auto Upload
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Tự động điền form đăng chương trên tangthuvien.net với tính năng nâng cao
// @author       Your name
// @match        https://tangthuvien.net/dang-chuong/story/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Thêm CSS cho thông báo và nút
    const style = document.createElement('style');
    style.textContent = `
        .ttv-notification {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px 20px;
            background: #4CAF50;
            color: white;
            border-radius: 4px;
            z-index: 9999;
            display: none;
        }
        .ttv-error {
            background: #f44336;
        }
        .ttv-button-group {
            margin-top: 10px;
            display: flex;
            gap: 10px;
            align-items: center;
        }
        .ttv-file-input {
            display: none;
        }
        .ttv-file-label {
            padding: 6px 12px;
            background: #5bc0de;
            color: white;
            border-radius: 4px;
            cursor: pointer;
            display: inline-block;
            margin: 0;
        }
        .ttv-file-label:hover {
            background: #46b8da;
        }
    `;
    document.head.appendChild(style);

    // Tạo div thông báo
    const notification = document.createElement('div');
    notification.className = 'ttv-notification';
    document.body.appendChild(notification);

    // Hiển thị thông báo
    function showNotification(message, isError = false) {
        notification.textContent = message;
        notification.className = 'ttv-notification' + (isError ? ' ttv-error' : '');
        notification.style.display = 'block';
        setTimeout(() => {
            notification.style.display = 'none';
        }, 3000);
    }

    // Đọc nội dung file
    function readFileContent(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = (e) => resolve(e.target.result);
            reader.onerror = (e) => reject(new Error('Lỗi đọc file: ' + e.target.error));
            reader.readAsText(file, 'UTF-8');
        });
    }

    // Xử lý khi chọn file
    async function handleFileSelect(event) {
        try {
            const file = event.target.files[0];
            if (!file) return;

            // Đọc nội dung file
            const content = await readFileContent(file);

            // Tự động điền nội dung
            const contentInput = document.querySelector('textarea[name="introduce[1]"]');
            if (contentInput) {
                contentInput.value = content;

                // Thử tự động lấy tên chương từ dòng đầu tiên
                const firstLine = content.split('\n')[0].trim();
                if (firstLine.includes('Chương')) {
                    const chapterNameInput = document.querySelector('input[name="chap_name[1]"]');
                    if (chapterNameInput) {
                        chapterNameInput.value = firstLine;
                    }
                }

                showNotification('Đã điền nội dung từ file thành công!');
            } else {
                showNotification('Không tìm thấy ô nhập nội dung!', true);
            }
        } catch (error) {
            console.error('Lỗi xử lý file:', error);
            showNotification('Có lỗi xảy ra khi đọc file!', true);
        }
    }

    // Thêm các nút điều khiển
    function addControlButtons() {
        const actionDiv = document.getElementById('action-btns');
        if (!actionDiv) {
            showNotification('Không tìm thấy vị trí để thêm nút!', true);
            return;
        }

        const buttonGroup = document.createElement('div');
        buttonGroup.className = 'ttv-button-group col-sm-8 col-sm-offset-2';

        // Nút tự động điền
        const autoFillBtn = document.createElement('button');
        autoFillBtn.type = 'button';
        autoFillBtn.className = 'btn btn-primary';
        autoFillBtn.innerHTML = '<span>Tự động điền</span>';
        autoFillBtn.onclick = autoFillForm;

        // Input chọn file
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.txt';
        fileInput.className = 'ttv-file-input';
        fileInput.id = 'ttv-file-input';
        fileInput.onchange = handleFileSelect;

        // Label cho input file
        const fileLabel = document.createElement('label');
        fileLabel.htmlFor = 'ttv-file-input';
        fileLabel.className = 'ttv-file-label';
        fileLabel.innerHTML = '<span>Chọn file txt</span>';

        // Nút lưu cấu hình
        const saveConfigBtn = document.createElement('button');
        saveConfigBtn.type = 'button';
        saveConfigBtn.className = 'btn btn-success';
        saveConfigBtn.innerHTML = '<span>Lưu cấu hình</span>';
        saveConfigBtn.onclick = saveChapterConfig;

        // Nút tải cấu hình
        const loadConfigBtn = document.createElement('button');
        loadConfigBtn.type = 'button';
        loadConfigBtn.className = 'btn btn-info';
        loadConfigBtn.innerHTML = '<span>Tải cấu hình</span>';
        loadConfigBtn.onclick = loadChapterConfig;

        buttonGroup.appendChild(autoFillBtn);
        buttonGroup.appendChild(fileInput);
        buttonGroup.appendChild(fileLabel);
        buttonGroup.appendChild(saveConfigBtn);
        buttonGroup.appendChild(loadConfigBtn);

        actionDiv.appendChild(buttonGroup);
    }

    // Tự động điền form
    function autoFillForm() {
        try {
            // Kiểm tra CSRF token
            const tokenInput = document.querySelector('input[name="_token"]');
            if (!tokenInput) {
                showNotification('Không tìm thấy token!', true);
                return;
            }

            // Lấy thông tin chương hiện tại
            const chap_stt = document.querySelector('.chap_stt1')?.value;
            const chap_serial = document.querySelector('.chap_serial')?.value;
            const chap_vol = document.querySelector('.chap_vol')?.value;
            const chap_vol_name = document.querySelector('.chap_vol_name')?.value;

            if (!chap_stt || !chap_serial) {
                showNotification('Không tìm thấy thông tin chương!', true);
                return;
            }

            // Điền các trường
            const fields = {
                'chap_stt[1]': chap_stt,
                'chap_number[1]': chap_serial,
                'vol[1]': chap_vol || '1',
                'vol_name[1]': chap_vol_name || '',
                'chap_name[1]': `Chương ${chap_serial}`
            };

            for (const [name, value] of Object.entries(fields)) {
                const input = document.querySelector(`input[name="${name}"]`);
                if (input) {
                    input.value = value;
                }
            }

            // Focus vào ô nội dung
            const contentInput = document.querySelector('textarea[name="introduce[1]"]');
            if (contentInput) {
                contentInput.focus();
                showNotification('Đã điền form thành công!');
            } else {
                showNotification('Không tìm thấy ô nhập nội dung!', true);
            }
        } catch (error) {
            console.error('Lỗi khi tự động điền form:', error);
            showNotification('Có lỗi xảy ra khi điền form!', true);
        }
    }

    // Lưu cấu hình chương
    function saveChapterConfig() {
        try {
            const config = {
                chap_stt: document.querySelector('.chap_stt1')?.value,
                chap_serial: document.querySelector('.chap_serial')?.value,
                chap_vol: document.querySelector('.chap_vol')?.value,
                chap_vol_name: document.querySelector('.chap_vol_name')?.value
            };

            localStorage.setItem('ttv_chapter_config', JSON.stringify(config));
            showNotification('Đã lưu cấu hình thành công!');
        } catch (error) {
            console.error('Lỗi khi lưu cấu hình:', error);
            showNotification('Có lỗi xảy ra khi lưu cấu hình!', true);
        }
    }

    // Tải cấu hình chương
    function loadChapterConfig() {
        try {
            const savedConfig = localStorage.getItem('ttv_chapter_config');
            if (!savedConfig) {
                showNotification('Không tìm thấy cấu hình đã lưu!', true);
                return;
            }

            const config = JSON.parse(savedConfig);

            // Cập nhật các trường
            const fields = {
                '.chap_stt1': config.chap_stt,
                '.chap_serial': config.chap_serial,
                '.chap_vol': config.chap_vol,
                '.chap_vol_name': config.chap_vol_name
            };

            for (const [selector, value] of Object.entries(fields)) {
                const input = document.querySelector(selector);
                if (input && value) {
                    input.value = value;
                }
            }

            showNotification('Đã tải cấu hình thành công!');
        } catch (error) {
            console.error('Lỗi khi tải cấu hình:', error);
            showNotification('Có lỗi xảy ra khi tải cấu hình!', true);
        }
    }

    // Thêm các nút điều khiển khi trang đã load
    window.addEventListener('load', function() {
        addControlButtons();
    });
})();