您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tải truyện từ metruyenchu.com định dạng epub.
当前为
// ==UserScript== // @name MeTruyenChu downloader // @namespace https://nntoan.com/ // @description Tải truyện từ metruyenchu.com định dạng epub. // @version 1.0.1 // @icon https://i.imgur.com/ZOmmIGK.png // @author Toan Nguyen // @oujs:author nntoan // @license MIT; https://nntoan.mit-license.org/ // @supportURL https://github.com/nntoan/UserScripts/issues // @match http://vtruyen.com/truyen/* // @match https://vtruyen.com/truyen/* // @require https://code.jquery.com/ui/1.12.0/jquery-ui.min.js // @require https://unpkg.com/[email protected]/dist/jszip.min.js // @require https://unpkg.com/[email protected]/ejs.min.js // @require https://unpkg.com/[email protected]/dist/jepub.min.js // @require https://unpkg.com/[email protected]/dist/FileSaver.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/src/mbDownloader.js // @connect self // @run-at document-idle // @noframes // ==/UserScript== /*global console, location*/ (function ($, window, document) { // eslint-disable-line 'use strict'; $(document).ready(function() { $.widget('nntoan.mbDownloader', $.nntoan.mbDownloader, { _create: function () { var self = this; this._super(); // Capture network requests var proxied = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function () { if (arguments[1].includes('v2/chapters') === true) { self.options.xhr.chapter.url = arguments[1]; } return proxied.apply(this, [].slice.call(arguments)); }; // Extending options this.options.processing.ebookFileName = this.options.general.pathname.slice(8, -5); this.options.xhr.content.url = this.options.general.pathname + this.options.chapters.chapId + '/'; // Styling download button for current site this.elements.$downloadBtn.attr('class', 'btn btn-warning btn-md btn-block text-white font-weight-semibold d-flex align-items-center justify-content-center'); this.elements.$downloadBtn.html('<i class="nh-icon icon-book mr-2"></i>Tải xuống'); this.elements.$downloadWrapper = $('<li></li>', { class: 'mr-3 w-150' }); this.elements.$downloadWrapper.html(this.elements.$downloadBtn); this.elements.$downloadWrapper.appendTo(this.options.classNames.downloadAppendTo); document.getElementById(this.options.classNames.getChapterTrigger).click(); console.time('downloadAndGenerateEpub'); }, /** * Get list of chapters request. * * @param {Object} that Curent widget object * @param {Event} event jQuery event * @param {Element} $widget Current node element * @returns void */ getListOfChapters: function (that, event, $widget) { var options = that.options, $ajax = null; if (options.isGlocCallbackRequired) { $ajax = that._trigger('getListOfChaptersPreprocess', event, that); } else { $ajax = $.ajax(options.xhr.chapter); } $ajax.done(function (response) { if (options.isGlocCallbackRequired) { $.ajax(options.xhr.chapter).done(function (data) { that.processListOfChapters(data, that, $widget); }).fail(function (error) { $widget.text('Lỗi trước khi bị lỗi danh mục :)'); that.downloadStatus('error'); console.error(error); //eslint-disable-line }); } else { that.processListOfChapters(response, that, $widget); } }).fail(function (error) { $widget.text('Lỗi danh mục'); that.downloadStatus('error'); console.error(error); //eslint-disable-line }); }, /** * Process with the XHR response of chapters list. * * @param {jqXHR} response XHR response * @param {Object} that Curent widget object * @param {Element} $widget Current node element * @returns void */ processListOfChapters: function (response, that, $widget) { var options = that.options; options.chapters.chapList = response._data.chapters; options.chapters.chapList = options.chapters.chapList.map(function (val) { return that.chapListValueFilter(options, val); }).filter(function (chapter) { return chapter !== ''; }); that._trigger('chapListFiltered', null, options.chapters.chapList); that.processing.chapListSize = options.chapters.chapList.length; if (that.processing.chapListSize > 0) { that.elements.$window.on('beforeunload', function () { return 'Truyện đang được tải xuống...'; }); $widget.one('click', function (e) { e.preventDefault(); that.saveEbook($widget); }); that.getContent($widget); } }, /** * Callback function to handle chap list values. * * @param {Object} options * @param {String} val * @returns {String} */ chapListValueFilter: function (options, val) { val = val.slug.replace(options.general.referrer, ''); val = '/' + val; return val.trim(); }, /** * Update CSS of download button. * * @param {String} status Download status * @returns void */ downloadStatus: function (status) { var self = this, options = this.options; self.elements.$downloadBtn.removeClass(options.classNames.downloadBtnStatus); if (status === 'error') { self.elements.$downloadBtn.addClass('btn-danger'); } if (status === 'warning') { self.elements.$downloadBtn.addClass('btn-warning'); } if (status === 'success') { self.elements.$downloadBtn.addClass('btn-success'); } }, /** * Cleanup redundant charactes in chapter content. * * @param {String} html Chapter content as HTML * @returns {String} */ cleanupHtml: function (html) { var options = this.options; html = html.replace(options.regularExp.chapter, ''); html = html.replace(options.regularExp.novel, ''); html = html.replace(options.regularExp.chineseSpecialChars, ''); html = html.replace(options.regularExp.alphanumeric, function (key, attr) { if (attr) return ' '; if (!isNaN(key)) return key; if (key.split(options.regularExp.alphabet).length > 2) return ' '; if (key.split(options.regularExp.number).length > 1) return ' '; return key; }); html = html.replace(options.regularExp.buttons, ''); html = html.split(this.createRegExp(options.regularExp.eoctext))[0]; html = html.replace('<br> <br>', '<br />'); return '<div>' + html + '</div>'; }, }); $(this).mbDownloader({ readyToInit: true, createDownloadWrapper: true, processing: { ebookFileExt: '.epub' }, jwt: { crypt: 'c&fjFR!WXPDPPmTj*!np2E98TPw5GMN93S43WVZDnR9fcmf@g*RA*Z', }, classNames: { novelId: '#report', infoBlock: '#app .container', chapterContent: '#js-read__content', chapterNotContent: 'iframe, script, style, a, div, p:has(a[href*="vtruyen.com"])', chapterVip: '#btnChapterVip', chapterTitle: '.nh-read__title', ebookTitle: 'h1', ebookAuthor: '.row.no-gutters .list-unstyled.mb-4 .border-secondary', ebookCover: '.row.no-gutters .nh-thumb.shadow', ebookDesc: '#nav-intro .content', ebookType: '.row.no-gutters .list-unstyled.mb-4 li .border-primary', getChapterTrigger: 'nav-tab-chap', downloadBtnStatus: 'btn-primary btn-success btn-info btn-warning btn-danger blue success warning info danger error', downloadWrapper: 'mr-3 w-150', downloadAppendTo: '.row.no-gutters .list-unstyled.d-flex.align-items-center', }, ebook: { fallbackCover: 'https://static.cdnno.com/background/vtruyen.jpg' }, chapters: { chapListSlice: [6, -1], }, xhr: { chapter: { type: 'GET', url: '', }, content: { type: 'GET', xhrFields: { withCredentials: true } } }, bookInfoUpdated: function (event, data) { var that = data.that, options = that.options, $infoBlock = that.elements.$infoBlock; options.ebook = $.extend(options.ebook, { title: $infoBlock.find(options.classNames.ebookTitle).text().trim(), author: $infoBlock.find(options.classNames.ebookAuthor).text().trim(), cover: $infoBlock.find(options.classNames.ebookCover).find('img').attr('src'), description: $infoBlock.find(options.classNames.ebookDesc).html(), }); data.epubInfo = $.extend(data.epubInfo, options.ebook); console.log('Book information updated...', data.epubInfo); }, chapTitleUpdated: function(event, data) { var options = data.this.options; options.xhr.content.url = location.protocol + '//' + options.general.host + options.chapters.chapId; }, beforeCreateEpub: function(event, that) { console.log('Prepare generate epub...'); }, complete: function(event, that) { console.log('Epub downloaded successfully. Please check your Downloads folder.'); console.timeEnd('downloadAndGenerateEpub'); } }); }); })(jQuery, window, document); // eslint-disable-line