NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Blocktruyen Helper // @namespace com.acbpro.bloctruyen.helper // @version 2.8 // @description Blogtruyen helper // @author You // @match http*://blogtruyen.com/* // @match http*://forum.blogtruyen.com/* // @match http*://blogtruyen.vn/* // @match http*://forum.blogtruyen.vn/* // @match http*://blogtruyenmoi.com/* // @match http*://forum.blogtruyenmoi.com/* // @match http*://blogtruyenmoi.vn/* // @match http*://forum.blogtruyenmoi.vn/* // @grant GM_xmlhttpRequest // @require http://code.jquery.com/jquery-3.3.1.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.4/js/uikit.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.4/js/components/notification.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.4/js/uikit-icons.min.js // @require https://unpkg.com/jszip@3.2.1/dist/jszip.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jszip-utils/0.0.2/jszip-utils.min.js // @require https://unpkg.com/file-saver@2.0.1/dist/FileSaver.min.js // @downloadURL https://openuserjs.org/install/trungking/Blocktruyen_Helper.user.js // @updateURL https://openuserjs.org/meta/trungking/Blocktruyen_Helper.meta.js // @license MIT // ==/UserScript== (function () { 'use strict'; log('Blogtruyen Helper started'); var Promise = window.Promise; if (!Promise) { Promise = JSZip.external.Promise; } const http = GM_xmlhttpRequest; const outputExt = 'zip'; const tit = document.title; let downloaded = 0; let total = 0; let downloading = false; let target = null; var referer = { 'i.blogtruyen.com': 'blogtruyen.com', 'i.imgur.com': 'imgur.com', 'storage.fshare.vn': 'fshare.vn', 'truyen.cloud': 'www.nettruyen.com' }; const id = '#bt-helper-offcanvas'; const body = 'body:not(#tinymce)'; let dlCurrent = 1; const jsZip = new JSZip(); loadCSS('https://css.acbpro.com/uikit.min.css'); injectJS(); const setting_button = '<button style="position: fixed;right: 0;top: 55px;border-radius:0" uk-toggle="target: #bt-helper-offcanvas" type="button" uk-icon="cog" class="uk-icon-button"></button>'; const expand_button = '<button style="position: fixed;right: 0;top: 91px;border-radius:0" type="button" uk-icon="expand" class="uk-icon-button" onclick="expandSpoiler()"></button>'; const block_button = '<button id="bt-helper-block-id" type="button" class="uk-button uk-button-danger uk-button-small" onclick="blockId()" style="font-size: 9px;padding: 0 7px;line-height: 26px; margin-bottom: 2px;">Chặn truyện</button>'; $(block_button).prependTo($('#btnBookmart').parent()); $(setting_button).appendTo(body); if (window.location.toString().indexOf('forum.blogtruyen.com') > -1 && $('.spoiler a,.top-spoiler a').length) { $(expand_button).appendTo(body); } const offcanvas = ` <div id="bt-helper-offcanvas" uk-offcanvas> <div class="uk-offcanvas-bar"> <div class="uk-margin-small-bottom"> Block Tag </div> <input id='block-tag' class="uk-input uk-margin-bottom" type="text" placeholder="EX: ntr,shoujo"> <div class="uk-margin-small-bottom"> Block Poster ID </div> <input id='block-poster' class="uk-input uk-margin-bottom" type="text" placeholder="EX: 99079,99080"> <div class="uk-margin-small-bottom"> Block ID </div> <input id='block-id' class="uk-input" type="text" placeholder="EX: 99079,99080"> <br><br> <label> <input id='block-pinned' type="checkbox"> Block pinned </label> <br> <button class="uk-button uk-button-primary uk-margin-top" onclick="saveSetting()">Save</button> <div id='bt-helper-success' class="uk-margin-top" style='display:none; color: green'>Saved. Refresh page to see the change</div> <button class="uk-offcanvas-close" type="button" uk-close> </button></div></div> ` $(offcanvas).appendTo(body); var setting = readSetting(); // if ($('#list-chapters').length !== 0) { // console.log('Append download'); // $('<a href="#">download</a>').appendTo($('#list-chapters .download')) // $('#list-chapters .download a').on('click', function (e) { // e.preventDefault(); // if (downloading) return; // downloading = true; // target = e.target; // const item = $(e.target).parents('p').find('.title a')[0]; // const url = item.href; // const chapName = item.title; // let html = ''; // download(url, function (data) { // const $html = $(data); // const $images = $html.find('#content img'); // total = $images.length; // downloaded = 0; // $images.each((key, image) => { // const filename = ('0000' + dlCurrent++ + '.' + image.src.split('.').pop()); // jsZip.file(filename, urlToPromise(image.src), { // binary: true // }); // }); // genZip(chapName); // }, function () { // log('Error download ', url); // }); // }); // } function download(url, success, error) { return http({ method: 'GET', url: url, onload: function (response) { success(response.response); }, onerror: function (err) { console.log(err); } }); } // block pinned if (setting.pinned) { $('#storyPinked').remove() } $('#storyPinked .tiptip').toArray().forEach((item, index) => { var id = item.href.split('/')[3]; if (setting.id.includes(id)) { item.remove(); log('Remove pinned ', id); return; } }) // Block manga list var mangaList = toArray($('.list-mainpage.listview div[class="col-sm-12"]')); mangaList.forEach((item, index) => { var categories = toArray($(item).find('.category a')); var poster = $(item).find('.poster'); var title = $(item).find('a')[0].title; var id = $(item).find('a')[0].href.match(/\/([0-9]+)\//)[1]; if (setting.id.includes(id)) { item.remove(); log('Remove ', title, ' with id ', id); return; } if (poster && poster.length) { var href = poster[0].href.split('/'); var posterID = href[href.length - 1]; if (setting.poster.some(item => posterID.toString() == item)) { item.remove(); if (title) { log('Remove ', title, ' with posterID ', posterID); } } } var blacklist = categories.some(cat => { var $cat = $(cat); var text = $cat.text(); var href = $cat.attr('href').split('/'); var slug = href[href.length - 1]; if (setting.tag.indexOf(text.toLowerCase()) != -1 || setting.tag.indexOf(slug.toLowerCase()) != -1) { return true; } return false; }); if (blacklist) { item.remove(); var cats = toArray($(item).find('.category a')).map(item => item.title); if (title) { log('Remove ', title, ' with tag ', cats.join(',')); } } }); log('Blogtruyen Helper injected'); function readSetting() { var setting = JSON.parse(localStorage.getItem("bt-helper-setting")); if (!setting) { return; } var tag = setting.tag ? setting.tag : []; var poster = setting.poster ? setting.poster : []; var id = setting.id ? setting.id : []; var pinned = setting.pinned ? setting.pinned : false; $('#block-tag').val(tag.join(',')); $('#block-poster').val(poster.join(',')); $('#block-id').val(id.join(',')); $('#block-pinned')[0].checked = !!pinned; return setting; } function injectJS() { var script = document.createElement('script'); script.type = "text/javascript"; script.innerHTML = ` function saveSetting(){ var $tag = $('#block-tag').val().split(',').map(s => s.trim().toLowerCase()); var $poster = $('#block-poster').val().split(',').map(s => s.trim()); var $id = $('#block-id').val().split(',').map(s => s.trim()); var $pinned = $('#block-pinned')[0].checked; var setting = JSON.stringify({tag: $tag, poster: $poster, id: $id, pinned: $pinned}); localStorage.setItem("bt-helper-setting", setting); $('#bt-helper-success').show(); console.log('bt-helper:::','Setting saved', setting); } function expandSpoiler(){ $('.spoiler a,.top-spoiler a').each(function (e) { jsSpoiler(this) }); } function blockId(){ var $id = $('.entry-title').find('a')[0].href.match('/([0-9]+)/')[1]; var $blockIds = $('#block-id'); if (!$blockIds.val().includes($id)){ var ar = $blockIds.val().split(',').filter(a => a); ar.push($id); $blockIds.val(ar.join(',')); saveSetting(); $('#bt-helper-block-id').remove(); } } `; document.getElementsByTagName('head')[0].appendChild(script); log('Inject JS success'); } // functions function genZip(chapName) { jsZip.generateAsync({ type: "blob" }).then(function callback(blob) { var zipName = genFileName(chapName) + '.' + outputExt; saveAs(blob, zipName); }, function (e) { log(e); }); } function genZip2(chapName) { log('call genzip'); jsZip.generateAsync({ type: 'blob' }).then(function (blob) { var zipName = genFileName(chapName) + '.' + outputExt; // noty('<a href="' + URL.createObjectURL(dlPrevZip) + '" download="' + zipName + '"><strong>Click vào đây</strong></a> nếu trình duyệt không tự tải xuống', 'success'); saveAs(blob, zipName); document.title = '[⇓] ' + tit; }, function () { noty('Lỗi tạo file nén của <strong>' + chapName + '</strong>', 'error'); cancelProgress(); document.title = '[x] ' + tit; endZip(); }); } function genFileName(chapName) { return chapName.replace(/\s+/g, '_').replace(/\./g, '-'); } function urlToPromise(url, key) { var urlObj = new URL(url), urlPro = urlObj.protocol, urlHost = urlObj.hostname, urlRef = referer[urlHost] ? referer[urlHost] : urlHost, urlOri = urlPro + '//' + urlRef; return new Promise(function (resolve, reject) { http({ method: 'GET', url: url, headers: { referer: urlOri, origin: urlOri }, responseType: 'arraybuffer', onload: function (response) { if (response.response.byteLength < 10000 || (response.statusText !== 'OK' && response.statusText !== '')) { log(response); reject(); } else { downloaded++; updateStatus(); resolve(response.response); } }, onerror: function (err) { reject(err); } }); }); } function updateStatus() { log('Download ' + downloaded + '/' + total); if (downloaded < total) { target.innerText = downloaded + '/' + total; } else { downloading = false; target.innerText = 'completed'; } } })(); function toArray(obj) { return $.map(obj, function (value, index) { return [value]; }); } function loadCSS(url) { var link = window.document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = url; document.getElementsByTagName("HEAD")[0].appendChild(link); } function log() { var args = Array.prototype.slice.call(arguments); args.unshift('bt-helper:::'); console.log.apply(console, args); }