Created
February 25, 2019 10:50
-
-
Save lazygyu/805a341d3fe831872d81aab1aa0335c5 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
const {createCanvas, loadImage} = require('canvas'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const name = process.argv[2]; | |
const no = process.argv[3] || 0; | |
const request = require('got'); | |
if( !name ) { | |
console.error('USAGE : node index [manga_name] [no]'); | |
process.exit(1); | |
} | |
getCollection(name); | |
async function getCollection(name){ | |
console.log(`looking for ${name}`); | |
const itemPat = /&wr_id=([0-9]+)/g; | |
const countPat = /총 ([0-9]+)화/g; | |
const resp = await request('https://mangashow2.me/bbs/page.php?hid=manga_detail&manga_name=' + encodeURI(name)); | |
const html = resp.body; | |
const dir = path.resolve(__dirname, 'images', name); | |
let total = 0; | |
if( !fs.existsSync(dir) ){ | |
fs.mkdirSync(dir); | |
} | |
let m = null; | |
const t_count=countPat.exec(html); | |
if( t_count ){ | |
console.log(t_count[0]); | |
total = parseInt(t_count[1]); | |
} | |
if( total == 0 ){ | |
console.log('no manga exists'); | |
process.exit(2); | |
} | |
let skip = no === 0 ? 0 : total - no; | |
if( skip ) console.log(`skip ${skip}`); | |
let ids = []; | |
do{ | |
m = itemPat.exec(html); | |
if(!m) break; | |
ids.push(m[1]); | |
}while(m); | |
if( skip ) ids = ids.slice(skip); | |
for(let i=ids.length-1;i>=0;i--){ | |
var tmp = await saveManga(dir, ids[i]); | |
} | |
} | |
async function saveManga(dir, wr_id){ | |
const resp = await request('https://mangashow2.me/bbs/board.php?bo_table=msm_manga&wr_id=' + wr_id); | |
const html = resp.body; | |
let vcnt, images, chapter, seed, title; | |
const CX = 5, CY = 5; | |
function __v(){ | |
if(chapter < 554714){ | |
const e = 1e4 * Math.sin(seed++); | |
return Math.floor(1e5 * (e - Math.floor(e))); | |
} | |
seed++; | |
let t = 100 * Math.sin(10 * seed), n = 1e3 * Math.cos(13 * seed), a = 1e4 * Math.tan(14 * seed); | |
return t = Math.floor(100 * (t - Math.floor(t))), n = Math.floor(1e3 * (n - Math.floor(n))), a = Math.floor(1e4 * (a - Math.floor(a))), t + n + a; | |
} | |
const viewcntPat = /var view_cnt = ([0-9]+);/; | |
const chapterPat = /var chapter = ([0-9]+);/; | |
const imgListPat = /var img_list = (\[[^\]]+\]);/; | |
const titlePat = /<title>(.+)<\/title>/; | |
let tmp = viewcntPat.exec(html); | |
if(tmp){ | |
vcnt = tmp[1]; | |
console.log(`view_cnt : ${vcnt}`); | |
} | |
tmp = chapterPat.exec(html); | |
if(tmp){ | |
chapter = tmp[1]; | |
} | |
tmp = titlePat.exec(html); | |
if(tmp){ | |
title = tmp[1]; | |
console.log(`title : ${title}`); | |
} | |
tmp = imgListPat.exec(html); | |
if(tmp){ | |
images = JSON.parse(tmp[1]); | |
console.log(`${images.length} image(s) found`); | |
} | |
seed = vcnt / 10; | |
for(d = [], m = 0; m < 25; m++){ | |
d.push([m, __v()]); | |
} | |
d = d.sort( (e,t)=>{ | |
return (e[1] - t[1]) || (e[0] - t[0]); | |
}); | |
const outdir = path.resolve(__dirname, 'images', dir, title); | |
if( !fs.existsSync( outdir ) ){ | |
fs.mkdirSync(outdir); | |
} | |
let success = 0; | |
let chain = Promise.resolve(); | |
images.forEach( (url,i)=>{ | |
chain = chain.then( function(){ | |
return new Promise( (rs,rj)=>{ | |
loadImage(url).then( img => { | |
const iw = img.width, ih = img.height; | |
const dw = Math.floor(iw / CX), dh = Math.floor(ih / CY); | |
const canv = createCanvas(iw, ih); | |
const ctx = canv.getContext('2d'); | |
const u = dw, g = dh, a=0; | |
if( vcnt == 0 ){ | |
ctx.drawImage(img, 0, 0, iw, ih, 0, 0, iw, ih); | |
}else{ | |
for (let p in d) { | |
var h = p % CX, _ = Math.floor(p / CX), f = d[p][0] % CX, v = Math.floor(d[p][0] / CX), s = 1 == a ? -r / 2 : 0; | |
ctx.drawImage(img, h * u, _ * g, u, g, f * u + s, v * g, u, g); | |
} | |
} | |
const filename = `${('0000'+i).substr(-4)}.png`; | |
const out = fs.createWriteStream(path.resolve(outdir, filename)); | |
canv.createPNGStream().pipe(out); | |
success++; | |
if(success == images.length){ | |
process.stdout.write('\n'); | |
console.log('done'); | |
}else{ | |
process.stdout.clearLine(); | |
process.stdout.cursorTo(0); | |
process.stdout.write(Math.round(success/images.length*100) + '% : ' + filename); | |
} | |
rs(); | |
}); | |
}); | |
}); | |
}); | |
return chain; | |
} |
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
{ | |
"name": "mangashowmecroller", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"canvas": "^2.3.1", | |
"got": "^9.6.0", | |
"request": "^2.88.0", | |
"request-promise-native": "^1.0.7" | |
}, | |
"devDependencies": { | |
"async-request": "^1.2.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment