Last active
August 10, 2024 15:00
-
-
Save hiroshil/4b71922792ee181bff8ea683b807add1 to your computer and use it in GitHub Desktop.
Script download manga trên 1 domain của hentaivn thành một file zip (Lưu ý: cần cài thêm extension "Allow CORS" và bật chế độ "Access-Control-Allow-Origin" từ "ORIGIN" sang "*" trong trang tùy chọn để script có thể hoạt động)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 210vn-dl | |
// @namespace https://gist.github.com/hiroshil | |
// @version 0.0.6 | |
// @description Script dùng để download manga R18 trên 1 domain của hentaivn | |
// @license MIT | |
// @author hiroshil | |
// @source https://gist.github.com/hiroshil/b85af14867493a72bd1cb24831bf0668 | |
// @include http*://*.*/*doc-truyen* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=hentaivn.icu | |
// @downloadURL https://gist.github.com/hiroshil/4b71922792ee181bff8ea683b807add1/raw/210vn-dl.user.js | |
// @updateURL https://gist.github.com/hiroshil/4b71922792ee181bff8ea683b807add1/raw/210vn-dl.user.js | |
// ==/UserScript== | |
/* jshint esversion: 8 */ | |
//https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists | |
//https://stackoverflow.com/questions/3754092/how-to-get-a-html-element-from-a-string-with-jquery | |
//https://stackoverflow.com/questions/30008114/how-do-i-promisify-native-xhr | |
//https://stackoverflow.com/questions/5582574/how-to-check-if-a-string-contains-text-from-an-array-of-substrings-in-javascript | |
function waitForElm(selector) { | |
return new Promise(resolve => { | |
if ($(selector).length) { | |
return resolve($(selector)); | |
} | |
const observer = new MutationObserver(mutations => { | |
if ($(selector).length) { | |
resolve($(selector)); | |
observer.disconnect(); | |
} | |
}); | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true | |
}); | |
}); | |
} | |
function waitForXHRRequest(url,method,responseType) { | |
return new Promise( (resolve, reject) => { | |
var res = new XMLHttpRequest(); | |
res.responseType = responseType; | |
res.open(method, url, true); | |
res.send(); | |
res.onload = () => { | |
if (res.status >= 200 && res.status < 400) { | |
resolve(res.response); | |
} else { | |
reject(false); | |
} | |
} | |
}); | |
} | |
function sleeper(ms) { | |
return function(x) { | |
return new Promise(resolve => setTimeout(() => resolve(x), ms)); | |
}; | |
} | |
function downloadChapter(id,filename, callback, ret = 3, skipCr = true){ | |
$.post("../ajax_load_server.php", { | |
server_id: id, | |
server_type: 2 | |
},async (res) => { | |
if (res){ | |
const imgs = $(res).filter("img"); | |
const zipFileWriter = new zip.BlobWriter(); | |
const zipWriter = new zip.ZipWriter(zipFileWriter); | |
for (let i = 0; i < imgs.length; i++) { | |
const src = imgs[i].src; | |
if (skipCr) { | |
if ( src.split("?")[0].endsWith(".gif") ) continue; | |
} | |
var blob; | |
do { | |
blob = await waitForXHRRequest(src,'GET','blob'); | |
ret -= 1; | |
if (!blob && !ret) { | |
alert("Lỗi khi download file: " + src) | |
} | |
else | |
{ | |
await sleeper(200); | |
} | |
} | |
while (!blob && ret); | |
if (blob.type.includes("image")){ | |
const blobReader = new zip.BlobReader(blob); | |
await zipWriter.add(String(i) + "_" + src.split("?").shift().split("/").pop(), blobReader); | |
} | |
} | |
await zipWriter.close(); | |
const zipFileBlob = await zipFileWriter.getData(); | |
const anchor = document.createElement("a"); | |
const clickEvent = new MouseEvent("click"); | |
anchor.href = window.URL.createObjectURL(zipFileBlob); | |
anchor.download = filename; | |
anchor.dispatchEvent(clickEvent); | |
} | |
else { | |
alert("Download không thành công!! Vui lòng thử lại!"); | |
} | |
callback(); | |
}); | |
} | |
function setupButton(jNode) { | |
jNode.each(function() { | |
const td = $("<td></td>"); | |
const button = $("<button></button>").addClass("dl-btn"); | |
button.text("Download"); | |
button.bind('click',function() { | |
const chapURL = $(this).parent().parent()[0].firstElementChild.firstElementChild; | |
$(this).attr('disabled','disabled'); | |
let hname = $("h1[itemprop='name']")[0].innerText; | |
const cfilter = ["chap", "oneshot", "one shot"]; | |
if ( cfilter.find(s => hname.toLowerCase().includes(s)) ) hname = hname.split("-")[0].trim(); | |
const output = hname + " - " + chapURL.innerText + ".zip"; | |
downloadChapter(chapURL.href.split("-").at(1), output, () => { $(".dl-btn[disabled]").removeAttr('disabled'); }); | |
}); | |
td.append(button); | |
$(this).append(td); | |
}); | |
} | |
async function main(){ | |
var xhr = await waitForXHRRequest("https://raw.githubusercontent.com/gildas-lormeau/zip.js/v2.7.17/dist/zip.js","GET",undefined); | |
eval(xhr); | |
const jNode = await waitForElm('#inner-listshowchapter > table > tbody > tr'); | |
setupButton(jNode); | |
} | |
const regex = /^https:\/\/[^/]+\.[^/]+\/\d+-doc-truyen-[^/]+\.html$/; | |
if (regex.test(window.location.href)) main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment