It'll be fine, I Promise

This commit is contained in:
Daniel J 2016-06-28 09:39:31 +02:00
parent edb92e364b
commit 9423c22733
5 changed files with 186 additions and 158 deletions

View file

@ -16,4 +16,6 @@ const STORY_ID = process.argv[2]
const ffc = new FimFic2Epub(STORY_ID)
ffc.download()
ffc.download().then(() => {
ffc.saveStory()
})

View file

@ -41,18 +41,21 @@ export default class FimFic2Epub {
}
download () {
return new Promise((resolve, reject) => {
if (this.isDownloading) {
alert("Calm down, I'm working on it (it's processing)")
reject()
return
}
if (this.cachedBlob) {
this.saveStory()
resolve()
return
}
this.build()
this.build().then(resolve).catch(reject)
})
}
build () {
return new Promise((resolve, reject) => {
this.isDownloading = true
this.zip = new JSZip()
@ -86,17 +89,20 @@ export default class FimFic2Epub {
this.zip.file('toc.ncx', template.createNcx(this))
this.zip.file('Text/nav.xhtml', template.createNav(this))
this.fetchTitlePage()
this.fetchTitlePage(resolve, reject)
})
})
}
fetchTitlePage () {
fetchTitlePage (resolve, reject) {
console.log('Fetching index page...')
fetchRemote(this.storyInfo.url, (raw, type) => {
this.extractTitlePageInfo(raw, () => this.checkCoverImage())
this.extractTitlePageInfo(raw).then(() => this.checkCoverImage(resolve, reject))
})
}
extractTitlePageInfo (html, cb) {
extractTitlePageInfo (html) {
return new Promise((resolve, reject) => {
let descPos = html.indexOf('<div class="description" id="description')
descPos = descPos + html.substring(descPos).indexOf('">') + 2
html = html.substring(descPos)
@ -157,7 +163,7 @@ export default class FimFic2Epub {
tags.push(t)
tags.byImage[t.image] = t
if (this.includeTitlePage) {
this.remoteResources.set(t.image, {filename: 'tag_' + tag[1], originalUrl: t.image, where: ['tags']})
this.remoteResources.set(t.image, {filename: 'tag-' + tag[1], originalUrl: t.image, where: ['tags']})
}
}
this.tags = tags
@ -165,11 +171,12 @@ export default class FimFic2Epub {
cleanMarkup(description, (html) => {
this.storyInfo.description = html
this.findRemoteResources('description', 'description', html)
cb()
resolve()
})
})
}
checkCoverImage () {
checkCoverImage (resolve, reject) {
this.hasCoverImage = !!this.storyInfo.full_image
if (this.hasCoverImage) {
@ -180,19 +187,19 @@ export default class FimFic2Epub {
coverImage.src = this.storyInfo.full_image
coverImage.addEventListener('load', () => {
this.processStory(coverImage)
this.processStory(resolve, reject, coverImage)
}, false)
} else {
fetchRemote(this.storyInfo.full_image, (data, type) => {
this.processStory(process.sizeOf(data))
this.processStory(resolve, reject, process.sizeOf(data))
}, 'buffer')
}
} else {
this.processStory()
this.processStory(resolve, reject)
}
}
processStory (coverImage) {
processStory (resolve, reject, coverImage) {
console.log('Fetching chapters...')
this.fetchChapters(() => {
@ -251,21 +258,12 @@ export default class FimFic2Epub {
.then((blob) => {
this.cachedBlob = blob
this.isDownloading = false
this.saveStory()
resolve()
})
} else {
this.zip
.generateNodeStream({
type: 'nodebuffer',
streamFiles: true,
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
})
.pipe(process.fs.createWriteStream(this.storyInfo.title + ' by ' + this.storyInfo.author.name + '.epub'))
.on('finish', () => {
console.log('Saved epub')
})
this.cachedBlob = true
this.isDownloading = false
resolve()
}
})
})
@ -377,13 +375,31 @@ export default class FimFic2Epub {
saveStory () {
console.log('Saving epub...')
let filename = this.storyInfo.title + ' by ' + this.storyInfo.author.name + '.epub'
if (isNode) {
this.zip
.generateNodeStream({
type: 'nodebuffer',
streamFiles: true,
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
})
.pipe(process.fs.createWriteStream(filename))
.on('finish', () => {
console.log('Saved epub as', filename)
})
return
}
if (typeof safari !== 'undefined') {
blobToDataURL(this.cachedBlob, (dataurl) => {
document.location.href = dataurl
alert('Rename downloaded file to .epub')
})
} else {
saveAs(this.cachedBlob, this.storyInfo.title + ' by ' + this.storyInfo.author.name + '.epub')
saveAs(this.cachedBlob, filename)
}
}
}

View file

@ -1,12 +1,38 @@
export default function fetch (url, cb, type) {
import isNode from 'detect-node'
function fetchNode (url, cb, responseType) {
process.request({
url: url,
encoding: responseType ? null : 'utf8',
headers: {
referer: 'http://www.fimfiction.net/'
}
}, (error, response, body) => {
if (error) {
console.error(error)
cb()
return
}
let type = response.headers['content-type']
cb(body, type)
})
}
export default function fetch (url, cb, responseType) {
if (url.indexOf('//') === 0) {
url = 'http:' + url
}
if (isNode) {
fetchNode(url, cb, responseType)
return
}
let x = new XMLHttpRequest()
x.open('get', url, true)
if (type) {
x.responseType = type
if (responseType) {
x.responseType = responseType
}
x.onload = function () {
cb(x.response, x.getResponseHeader('content-type'))

View file

@ -55,11 +55,7 @@ export default function fetchRemote (url, cb, responseType) {
if (url.indexOf('//') === 0) {
url = 'http:' + url
}
if (isNode) {
fetchNode(url, cb, responseType)
return
}
if (document.location.protocol === 'https:' && url.indexOf('http:') === 0) {
if (!isNode && document.location.protocol === 'https:' && url.indexOf('http:') === 0) {
fetchBackground(url, cb, responseType)
return
}
@ -72,17 +68,3 @@ export default function fetchRemote (url, cb, responseType) {
}, responseType)
}
function fetchNode (url, cb, responseType) {
process.request({
url: url,
encoding: responseType ? null : 'utf8'
}, (error, response, body) => {
if (error) {
console.error(error)
cb()
return
}
let type = response.headers['content-type']
cb(body, type)
})
}

View file

@ -10,6 +10,8 @@ const epubButton = document.querySelector('.story_container ul.chapters li.botto
if (epubButton) {
epubButton.addEventListener('click', function (e) {
e.preventDefault()
ffc.download()
ffc.download().then(() => {
ffc.saveStory()
})
}, false)
}