// ==UserScript== // @name Poipiku Downloader // @description Download images or text from Poipiku // @author calary // @namespace http://tampermonkey.net/ // @version 0.2 // @license GPL-3.0 // @include http*://poipiku.com* // @match https://poipiku.com/ // @icon https://poipiku.com/favicon.ico // @require https://cdn.bootcdn.net/ajax/libs/jquery/2.2.4/jquery.min.js // @require https://cdn.bootcss.com/jszip/3.1.4/jszip.min.js // @require https://cdn.bootcss.com/FileSaver.js/1.3.2/FileSaver.min.js // @grant GM.xmlHttpRequest // @grant GM_xmlhttpRequest // @run-at document-end // @downloadURL none // ==/UserScript== jQuery(function ($) { const website = "poipiku"; const defaultErrorMsg = "Something went wrong"; const url = window.location.href; const execResult = /\/(\d+)\/(\d+)/.exec(url); const authorId = execResult && execResult[1]; const workId = execResult && execResult[2]; const logined = $(".LoginButton").length === 0; const isText = $(".IllustItem").hasClass("Text"); const hasPassword = $(".IllustItem").hasClass("Password"); if (!workId) { return; } const $panel = $(`
Logined: ${logined}.
You ${ logined ? "can" : "cannot" } download high quality images.
Password
Rename image with page id
`) .css({ position: "fixed", left: 0, top: 50, zIndex: 999999, background: "#fff", color: "#333", fontSize: 18, fontFamily: "sans-serif", padding: 10, }) .appendTo($("body")); const $password = $panel.find(".password"); const $saveFileMode = $panel.find(".saveFileMode"); if (!hasPassword) { $panel.find(".line-password").hide(); } if (isText) { $panel.find(".line-images").hide(); $panel.find(".line-qualitytip").hide(); $panel.find(".line-mode").hide(); } else { $panel.find(".line-text").hide(); } $panel.find(".btn-downloadImages").on("click", downloadImages); $panel.find(".btn-downloadText").on("click", downloadText); function request(config) { return new Promise((resolve, reject) => { $.ajax({ ...config, success: (response) => { resolve(response); }, error: () => { reject(new Error("Something went wrong")); }, }); }); } function getBlob(url) { return fetch(url).then((response) => response.blob()); } // 过滤文件名非法字符 function filterFilename(filename) { return filename.replace(/\?|\*|\:|\"|\<|\>|\\|\/|\|/g, ""); } // 生成保存文件名 function getSaveFilename() { const twitter = $(".UserInfoProgile a").html(); const username = $(".UserInfoUserName a").html(); const username2 = twitter ? twitter.substring(1) : username; const desc = $(".IllustItemDesc").text().substring(0, 20); return filterFilename( `[${username2}][${website}][${authorId}_${workId}]${desc}` ); } // 生成保存图片文件名 // 默认:序号.后缀名 // 选中:网站_作品id_序号.后缀名 function getSaveImageFilename(src, index) { let suffix = src.substring(src.lastIndexOf(".") + 1); const mode = $saveFileMode.is(":checked"); if (mode) { return `${website}_${workId}_${index + 1}.${suffix}`; } return `${index + 1}.${suffix}`; } // 批量下载图片的默认方法 function saveImages(list, $status) { let zip = new JSZip(); let finishehCount = 0; let folder = zip.folder(getSaveFilename()); $status = $status || $("
"); $status.text(`0/${list.length}`); let promises = list.map(function (src, index) { return getBlob(src).then((blob) => { finishehCount++; $status.text(`${finishehCount}/${list.length}`); folder.file(getSaveImageFilename(src, index), blob, { binary: true }); }); }); Promise.all(promises).then(() => { let url = window.location.href; let exec = /(\d+)\..*$/.exec(window.location.href); let id = 0; if (exec) { id = exec[1]; } zip .generateAsync({ type: "blob", base64: true }) .then((content) => saveAs(content, getSaveFilename())); }); } // 保存文字的默认方法 function saveText(option) { let str = ""; if (option.title) { str += `标题:${option.title}\n`; } if (option.author) { str += `作者:${option.author}\n`; } if (option.twitter) { str += `推特:${option.twitter}\n`; } str += `地址:${window.location.href}\n`; str += `\n\n`; str += option.content; saveAs( new Blob([str], { type: "text/plain;charset=UTF-8" }), getSaveFilename() + ".txt" ); } // 下载图片 function downloadImages() { const $this = $(this); const promise = logined ? request({ url: "/f/ShowIllustDetailF.jsp", type: "POST", data: { ID: authorId, TD: workId, AD: "-1", PAS: $password.val(), }, dataType: "json", }).then(function (payload) { if (!payload.html) { throw new Error("Fetch content error. Entered wrong password?"); } return payload.html; }) : request({ url: "/f/ShowAppendFileF.jsp", type: "POST", data: { UID: authorId, IID: workId, PAS: $password.val(), MD: 0, TWF: -1, }, dataType: "json", }).then(function (payload) { if (payload.result_num < 0) { throw new Error(payload.html); } return $(".IllustItemThumb").eq(0).prop("outerHTML") + payload.html; }); promise .then(function (html) { let $page = $(html); let list = []; $page .find(logined ? ".DetailIllustItemImage" : ".IllustItemThumbImg") .each(function () { const src = $(this).attr("src"); if (src) { list.push(window.location.protocol + src); } }); if (list.length) { saveImages(list, $this.find(".status")); } else { throw new Error("No Images"); } }) .catch(function (e) { alert(e.message || defaultErrorMsg); }); } // 下载文字 function downloadText() { request({ url: "/f/ShowAppendFileF.jsp", type: "POST", data: { UID: authorId, IID: workId, PAS: $password.val(), MD: 0, TWF: -1, }, dataType: "json", }) .then(function (payload) { if (payload.result_num < 0) { throw new Error(payload.html); } let $page = $(payload.html); saveText({ title: $(".IllustItemDesc").text(), author: $(".UserInfoUserName a").html(), twitter: $(".UserInfoProgile a").prop("href"), content: $page.find(".NovelSection").text(), }); }) .catch(function (e) { alert(e.message || defaultErrorMsg); }); } });