lelinhtinh / Userscript

Userscripts collection
http://devs.forumvi.com/f23-userscript
MIT License
151 stars 53 forks source link

Request #111

Closed hotboykila2014 closed 2 years ago

hotboykila2014 commented 2 years ago

Nếu có thể thì mình hi vọng bạn viết một userscript cho web Metruyenchu.com, mình tìm được script của bạn nntoan nhưng script hiện tại có khá nhiều bug và bạn ấy không còn support nữa. Cảm ơn bạn đã đọc.

gianghd commented 2 years ago

Mình update lại dùng khá ổn.

// ==UserScript==
// @name            MeTruyenChu downloader
// @name:vi         MeTruyenChu downloader
// @namespace    http://tampermonkey.net/
// @version      1
// @icon            https://static.cdnno.com/background/metruyenchu.jpg
// @description     Tải truyện từ MeTruyenChu định dạng EPUB.
// @description:vi  Tải truyện từ MeTruyenChu định dạng EPUB.
// @author       You
// @match           https://metruyenchu.com/truyen/*
// @match           https://metruyenchu.com/truyen/*
// @match           https://nuhiep.com/truyen/*
// @match           https://nuhiep.com/truyen/*
// @require         https://code.jquery.com/jquery-3.5.1.min.js
// @require         https://unpkg.com/jszip@3.1.5/dist/jszip.min.js
// @require         https://unpkg.com/file-saver@2.0.2/dist/FileSaver.min.js
// @require         https://unpkg.com/ejs@2.7.4/ejs.min.js
// @require         https://unpkg.com/jepub@2.1.4/dist/jepub.min.js
// @require         https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
// @noframes
// @connect         self
// @supportURL      https://github.com/lelinhtinh/Userscript/issues
// @run-at          document-idle
// @grant           GM_xmlhttpRequest
// @grant           GM.xmlHttpRequest
// ==/UserScript==
(function ($, window, document) {
    'use strict';
    /**
   * Nhận cảnh báo khi có chương bị lỗi
   */
    var errorAlert = true;
    /**
   * Những đoạn ghi chú cuối chương của converter
   * Chỉ cần ghi phần bắt đầu, không phân biệt hoa thường
   * Ngăn cách các đoạn bằng dấu |
   */
    var converter = 'ps:|hoan nghênh quảng đại bạn đọc quang lâm|Huyền ảo khoái trí ân cừu';

    converter = new RegExp('(' + converter + ')', 'i');

    var pageName = document.title,
        $win = $(window),
        $li = $('<li>', {
            id: 'download',
            class:'mr-3'
        }),
        $download = $('<a>', {
            class: 'btn btn-outline-warning btn-md btn-block bg-yellow-white text-primary font-weight-semibold d-flex align-items-center justify-content-center',
            href: '#download',

            text: 'Tải xuống',
        }),
        downloadStatus = function (status) {
            $download.removeClass('btn-primary btn-success btn-info btn-warning btn-danger').addClass('btn-' + status);
        },
        $novelId = $('.active'),
        chapList = [],
        chapListSize = 0,
        $navTabChap = 0,
        chapId = '',
        chapTitle = '',
        count = 0,
        begin = '',
        end = '',
        endDownload = false,
        ebookTitle = '',
        ebookAuthor = '',
        ebookCover = '',
        ebookDesc = '',
        ebookType = [],
        beginEnd = '',
        titleError = [],
        host = location.host,
        pathname = location.pathname + '/',
        referrer = location.protocol + '//' + host + pathname,
        ebookFilename = pathname.slice(1, -1) + '.epub',
        credits =
        '<p>Truyện được tải từ <a href="' +
        referrer +
        '">metruyenchu</a></p><p>Userscript được viết bởi: <a href="https://lelinhtinh.github.io/jEpub/">Zzbaivong</a>, Được sửa bởi FixBug</p>',
        jepub;

    $("#js-read__content").removeClass("post-body");
    if (!$novelId.length) return;

    var $infoBlock = $('.media-body');
    var $imagesBlock = $('.media');

    ebookTitle = $infoBlock.find('h1').text().trim();
    ebookAuthor = $infoBlock.find('ul:first').find('li:first').text().trim();
    ebookCover = $imagesBlock.find('img').attr('src');
    ebookDesc = $('.content').html();

    var $ebookType = $infoBlock.find('ul:first').find('li');
    if ($ebookType.length) {
        var i = 1;
        $ebookType.each(function () {
            if (i > 2) {
                ebookType.push($(this).text().trim());
            }
            i++;
        });
    }
    jepub = new jEpub();
    jepub
        .init({
        title: ebookTitle,
        author: ebookAuthor,
        publisher: host,
        description: ebookDesc,
        tags: ebookType,
    })
        .uuid(referrer);
    $li.append($download);
    $li.insertAfter('#suggest-book');

    $download.one('click contextmenu', function (e) {
        e.preventDefault();

        var showChapList = $('.container a[href="#nav-chap"]');
        document.title = '[...] Vui lòng chờ trong giây lát';
        $download.html('Chờ một chút...');
        $navTabChap = $('#nav-tab-chap');
        chapListSize = Number($navTabChap.find('span:last').text().trim());
        if (chapListSize > 0) {
            var i;
            for (i = 1; i <= chapListSize; i++) {
                chapList.push('chuong-'+i);
            }

            if (e.type === 'contextmenu') {
                $download.off('click');
                var startFrom = prompt('Nhập ID chương truyện bắt đầu tải:', chapList[0]);
                startFrom = chapList.indexOf(startFrom);
                if (startFrom !== -1) chapList = chapList.slice(startFrom);
            } else {
                $download.off('contextmenu');
            }
            chapListSize = chapList.length;
            $win.on('beforeunload', function () {
                return 'Truyện đang được tải xuống...';
            });

            $download.one('click', function (e) {
                e.preventDefault();
                saveEbook();
            });

            getContent();
        }

    });

    function getContent() {
        if (endDownload) return;
        chapId = chapList[count];

        $.ajax({
            url: pathname + chapId + '/',
            xhrFields: {
                withCredentials: true,
            },
        }).done(function (response) {
            var $data = $(response),
                $chapter = $data.find('#js-read__content'),
                $notContent = $chapter.find('iframe, script, style, a, div, p:has(a[href*="truyencv.com"])'),
                $referrer = $chapter.find('[style]').filter(function () {
                    return this.style.fontSize === '1px' || this.style.fontSize === '0px' || this.style.color === 'white';
                }),
                chapContent;

            if (endDownload) return;

            chapTitle = $data.find('.nh-read__title').text().trim();
            if (chapTitle === '') chapTitle = 'Chương ' + chapId.match(/\d+/)[0];

            if (!$chapter.length) {
                chapContent = downloadError('Không có nội dung');
            } else {
                if ($chapter.find('#btnChapterVip').length) {
                    chapContent = downloadError('Chương VIP');
                } else if (
                    $chapter.filter(function () {
                        return this.textContent.toLowerCase().indexOf('vui lòng đăng nhập để đọc chương này') !== -1;
                    }).length
                ) {
                    chapContent = downloadError('Chương yêu cầu đăng nhập');
                } else {
                    var $img = $chapter.find('img');
                    if ($img.length) {
                        $img.replaceWith(function () {
                            return '<br /><a href="' + this.src + '">Click để xem ảnh</a><br />';
                        });
                    }

                    if ($notContent.length) $notContent.remove();
                    if ($referrer.length) $referrer.remove();

                    if ($chapter.text().trim() === '') {
                        chapContent = downloadError('Nội dung không có');
                    } else {
                        if (!$download.hasClass('btn-danger')) downloadStatus('warning');
                        chapContent = cleanHtml($chapter.html());
                    }
                }
            }

            jepub.add(chapTitle, chapContent);

            if (count === 0) begin = chapTitle;
            end = chapTitle;

            $download.html('Đang tải <strong>' + count + '/' + chapListSize + '</strong>');

            count++;
            document.title = '[' + count + '] ' + pageName;
            if (count >= chapListSize) {
                saveEbook();
            } else {
                getContent();
            }
        }).fail(function (err) {
            setTimeout(function() {
                window.open(pathname + chapId + '/');
                getContent();
            }, 10000);
        });
    }

    function saveEbook() {
        if (endDownload) return;
        endDownload = true;
        $download.html('Bắt đầu tạo EPUB');

        if (titleError.length) {
            titleError = '<p class="no-indent"><strong>Các chương lỗi: </strong>' + titleError.join(', ') + '</p>';
        } else {
            titleError = '';
        }
        beginEnd = '<p class="no-indent">Nội dung từ <strong>' + begin + '</strong> đến <strong>' + end + '</strong></p>';

        jepub.notes(beginEnd + titleError + '<br /><br />' + credits);

        GM.xmlHttpRequest({
            method: 'GET',
            url: ebookCover,
            responseType: 'arraybuffer',
            onload: function (response) {
                try {
                    jepub.cover(response.response);
                } catch (err) {
                    console.error(err);
                }
                genEbook();
            },
            onerror: function (err) {
                console.error(err);
                genEbook();
            },
        });
    }

    function genEbook() {
        jepub
            .generate('blob', function (metadata) {
            $download.html('Đang nén <strong>' + metadata.percent.toFixed(2) + '%</strong>');
        })
            .then(function (epubZipContent) {
            document.title = '[⇓] ' + ebookTitle;
            $win.off('beforeunload');

            $download
                .attr({
                href: window.URL.createObjectURL(epubZipContent),
                download: ebookFilename,
            })
                .text('Hoàn thành')
                .off('click');
            if (!$download.hasClass('btn-danger')) downloadStatus('success');

            saveAs(epubZipContent, ebookFilename);
        })
            .catch(function (err) {
            downloadStatus('danger');
            console.error(err);
        });
    }

    function cleanHtml(str) {
        str = str.replace(/\s*Chương\s*\d+\s?:[^<\n]/, '');
        str = str.replace(/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]+/gm, ''); // eslint-disable-line
        str = str.replace(/\s[a-zA-Z0-9]{6,8}(="")?\s/gm, function (key, attr) {
            if (attr) return ' ';
            if (!isNaN(key)) return key;
            if (key.split(/[A-Z]/).length > 2) return ' ';
            if (key.split(/\d/).length > 1) return ' ';
            return key;
        });
        str = str.replace(/\([^(]+<button[^/]+<\/button>[^)]*\)\s*/gi, '');
        str = str.split(converter)[0];
        return '<div>' + str + '</div>';
    }
    function downloadError(mess, err) {
        downloadStatus('danger');
        if (err) console.error(mess);
        if (!chapTitle) return;

        titleError.push(chapTitle);
        if (errorAlert) errorAlert = confirm('Lỗi! ' + mess + '\nBạn có muốn tiếp tục nhận cảnh báo?');

        return '<p class="no-indent"><a href="' + referrer + chapId + '">' + mess + '</a></p>';
    }

})(jQuery, window, document);
lelinhtinh commented 2 years ago

@hotboykila2014 bạn có thể lấy script từ https://github.com/gianghd/userscript

@gianghd vậy mình close issue này nhé. Mình thấy script của bạn quên sửa thông tin cá nhân kìa: @namespace, @author, @supportURL. Ngoài ra bạn cũng nên upload lên như GreasyFork, OpenUserJS. Filename cũng cần đổi đuôi thành .user.js.