Last active
November 27, 2022 13:44
-
-
Save GHolk/ba6b19be90c2a14f432256fc4038886b to your computer and use it in GitHub Desktop.
This file contains 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
alias jse js 'use strict'; function $all(q, root=document) { return Array.from(root.querySelectorAll(q)) }; function $(q, root=document) { return root.querySelector(q) }; let $ex = (s) => tri.controller.acceptExCmd(s) ; let $set = (...args) => tri.config.set(...args); let $d = document; let $w = window; | |
command dlx jse var downloadJob=tri.downloadJob={browser:tri.browserBg||browser,os:"windows",native:false,downloadPath:"kwk",stop:false,ex:tri.excmds,idList:[],dlhandlerwrap(...args){return tri.downloadJob.dlhandler(...args)},dlhandler(){},async init(){const tab=await this.browser.tabs.query({active:true,currentWindow:true});this.tabId=tab[0].id;this.windowId=tab[0].windowId;return;this.dlhandle=function(e){const i=this.idList.findIndex(x=>x.id==e.id);if(i==-1)return;const job=this.idList[i];let state;if(typeof e.state=="object")state=e.state.current;else state=e.state;switch(e.state.current){case"complete":job.resolve();case"interrupted":let error=new Error("download fail");error.codeName="download-error";job.reject(error);this.idList.splice(i,1);default:true}};this.browser.downloads.onChanged.addListener(this.dlhandlerwrap);this.browser.downloads.onCreated.addListener(this.dlhandlerwrap)},destroy(){this.browser.downloads.onChanged.removeListener(this.dlhandlerwrap);this.browser.downloads.onCreated.removeListener(this.dlhandlerwrap)},async download(url,file){let id;try{id=await this.browser.downloads.download({filename:file,url:url})}catch(fail){fail.codeName="download-error";throw fail}return{id:id,url:url,file:file}},getTitle(url){const path=url.pathname;let title;if(path.match(/index.php/)){title=url.searchParams.get("title")}else title=decodeURIComponent(url.pathname.slice(1));return title.replace(/[*"'.?/:]/g,c=>"%"+c.charCodeAt().toString(16).toUpperCase())},async downloadFromAnchor(a){const url=new URL(a.href);const title=this.getTitle(url);const file=title+".html";const cacheNode=a.nextElementSibling.querySelector('a[href^="https://webcache"]');if(!cacheNode)return"no-cache";if(this.native){if(await this.fileExist(file))return"skip"}const cache=cacheNode.href;return await this.download(cache,`${this.downloadPath}/${file}`)},downloadCurrentHtml(){function doctypeToString(node=document.doctype){if(!node)return"";return"<!DOCTYPE "+node.name+(node.publicId?` PUBLIC "${node.publicId}"`:"")+(!node.publicId&&node.systemId?" SYSTEM":"")+(node.systemId?` "${node.systemId}"`:"")+">"+"\n"}function cleanCopy(root){const deep=true;const copy=root.cloneNode(deep);copy.querySelectorAll("iframe[src ^= moz-extension").forEach(e=>e.remove());fixRelativeUrl(copy);fixEncode(copy);return copy}function fixEncode(root){if(document.characterSet=="UTF-8")return;const list=root.querySelectorAll("meta[http-equiv=content-type],"+"meta[http-equiv=Content-Type],"+"meta[charset]");if(list.length==0){if(!confirm("not UTF-8 and no charset tag found, add one?"))return;const encodeNode=document.createElement("meta");encodeNode.setAttribute("charset","utf-8");encodeNode.dataset.gholkOriginalCharset="";const head=root.querySelector("head");if(head)head.prepend(encodeNode);else root.prepend(encodeNode)}else{list.forEach(encodeNode=>{if(encodeNode.hasAttribute("charset")){const original=encodeNode.getAttribute("charset");encodeNode.dataset.gholkOriginalCharset=original;encodeNode.setAttribute("charset","utf-8")}else if(encodeNode.hasAttribute("http-equiv")){encodeNode.dataset.gholkOriginalContentType=encodeNode.content;encodeNode.content="text/html; charset=UTF-8"}else alert(`unknown error while fix encode node: ${encodeNode.outerHTML}`)})}}function fixRelativeUrl(root){let base=root.querySelector("base");if(base){const relative=base.getAttribute("href");base.dataset.gholkOriginalHref=relative;base.setAttribute("href",base.href)}else{base=document.createElement("base");base.href=root.baseURI;base.dataset.gholkOriginalHref="";let head=root.querySelector("head");if(head)head.prepend(base);else root.prepend(base)}}const html=doctypeToString()+cleanCopy(document.documentElement).outerHTML;const blob=new Blob([html],{type:"text/html"});const download=document.createElement("a");download.download=document.title+".html";download.href=URL.createObjectURL(blob);document.body.appendChild(download);download.click();download.remove();URL.revokeObjectURL(blob)},async downloadFromPath(path){const title=path.slice(1);const url=`https://wiki.komica.org/${title}`;const cache="http://webcache.googleusercontent.com/search?q=cache:"+url;this.cacheUrl=cache;const file=title.replace(/[*"'.?/:]/g,c=>encodeURIComponent(c))+".html";if(this.native&&await this.fileExist(file))return"skip";return await this.download(cache,this.downloadPath+"/"+file)},async fileExist(file){const ex=this.ex;const safe=await ex.shellescape(file);let exist;if(this.os=="windows"){exist=await ex.exclaim_quiet(`if exist ..\\Downloads\\${this.downloadPath}\\${safe} echo exist`)}else exist=await ex.exclaim_quiet(`test -f $HOME/Downloads/${this.downloadPath}/${safe} && echo -n exist`);return Boolean(exist)},async queryIdList(list){const ql=list.map(id=>this.browser.downloads.search({id:id}));return(await Promise.all(ql)).flat()},async dlax(method,n=0){await this.init();let l;let backupGoogleSearch=false;if(method=="downloadFromPath"){l=tri.state.komica_wiki_data}else if(method=="downloadFromAnchor"){l=$all("a>h3").map(h=>h.parentNode)}else throw new Error("unknown method");for(let i=n;i<l.length&&!this.stop;true){console.log("line "+i);let errorDownload;let dl;try{dl=await this[method](l[i])}catch(error){if(error.codeName!="download-error")throw error;errorDownload=error}if(dl=="skip"){console.log("skip");i++;continue}if(dl=="no-cache"){backupGoogleSearch=true;i++;continue}let retry=false;while(true){const state=(await this.browser.downloads.search({id:dl.id}))[0];if(state.state=="complete"){await this.ex.sleep(3e3);break}if(state.state=="in_progress"){await this.ex.sleep(500);continue}const tabp=await this.tabopen(dl.url);const tab=await tabp;const is404p=this.check404(tab.id);const first=await Promise.race([is404p,this.sleep(3).then(x=>"timeout")]);if(first=="error-404"){await this.browser.tabs.remove(tab.id);backupGoogleSearch=true}if(first!="timeout")break;retry=await this.tabEval(`confirm('retry ${i}? (or skip)')`);if(!retry){try{await this.browser.tabs.remove(tab.id);backupGoogleSearch=true}catch(error){console.error(error);console.log("tab is already closed")}}break}if(!retry)i++}if(backupGoogleSearch){this.downloadCurrentHtml();await this.sleep(1)}if(method=="downloadFromAnchor"){if(confirm(`next?`))$("#pnnext").click()}},async dlap(n=0){await this.init();const l=tri.state.komica_wiki_data;for(let i=n;i<l.length&&!this.stop;true){console.log("line "+i);let errorDownload;let dl;try{dl=await this.downloadFromPath(l[i])}catch(error){if(error.codeName!="download-error")throw error;errorDownload=error}if(dl=="skip"){console.log("skip");i++;continue}let retry=false;while(true){const state=(await this.browser.downloads.search({id:dl.id}))[0];if(state.state=="complete"){await this.ex.sleep(3e3);break}if(state.state=="in_progress"){await this.ex.sleep(500);continue}const tabp=await this.tabopen(dl.url);const tab=await tabp;const is404p=this.check404(tab.id);const first=await Promise.race([is404p,this.sleep(3).then(x=>"timeout")]);if(first=="error-404"){await this.browser.tabs.remove(tab.id)}if(first!="timeout")break;retry=await this.tabEval(`confirm('retry ${i}? (or skip)')`);if(!retry){try{await this.browser.tabs.remove(tab.id)}catch(error){console.error(error);console.log("tab is already closed")}}break}if(!retry)i++}},sleep(s){return new Promise(wake=>setTimeout(wake,s*1e3))},async check404(tabId){while(true){let tab;try{tab=await this.browser.tabs.get(tabId)}catch(closed){return"close"}if(tab.title.match(/^Error 404/))return"error-404";await this.ex.sleep(200)}},async tabEval(code){if(tri.browserBg)return eval(code);const resultList=await this.browser.tabs.executeScript(this.tabId,{code:code});return resultList[0]},async tabopen(url){return await this.browser.tabs.create({active:true,url:url,windowId:this.windowId})},async dlan(list=$all("a>h3")){for(const h of list){await this.downloadFromAnchor(h.parentNode)&&await tri.excmds.sleep(5e3)}if(confirm("next?"))$("#pnnext").click()},Defer:function Defer(){this.promise=new Promise((resolve,reject)=>{this.resolve=resolve;this.reject=reject})}}; | |
bindurl ^https://www.google.com/search c dlx downloadJob.dlax('downloadFromAnchor') | |
bindurl ^https://www.google.com/search C fillcmdline dlx downloadJob.dlax('downloadFromAnchor') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment