mirror of
https://github.com/daniel-j/fimfic2epub.git
synced 2024-09-30 00:56:13 +13:00
more wip
This commit is contained in:
parent
8ba203b437
commit
d1d78bc777
3 changed files with 158 additions and 126 deletions
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
#epubDialogContainer .drop-down-pop-up-container {
|
#epubDialogContainer .drop-down-pop-up-container {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1001;
|
z-index: 1001;
|
||||||
|
@ -11,3 +11,11 @@
|
||||||
#epubDialogContainer .drop-down-pop-up-container .drop-down-pop-up h1 {
|
#epubDialogContainer .drop-down-pop-up-container .drop-down-pop-up h1 {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#epubDialogContainer table.properties {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#epubDialogContainer table.properties td.label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
|
@ -80,67 +80,58 @@ module.exports = class FimFic2Epub {
|
||||||
this.storyId = FimFic2Epub.getStoryId(storyId)
|
this.storyId = FimFic2Epub.getStoryId(storyId)
|
||||||
|
|
||||||
this.hasDownloaded = false
|
this.hasDownloaded = false
|
||||||
this.isDownloading = false
|
this.downloadPromise = null
|
||||||
this.zip = null
|
|
||||||
|
this.storyInfo = null
|
||||||
|
this.titlePage = null
|
||||||
this.chapterContent = []
|
this.chapterContent = []
|
||||||
this.remoteResources = new Map()
|
this.remoteResources = new Map()
|
||||||
this.storyInfo = null
|
|
||||||
this.isDownloading = false
|
|
||||||
this.cachedFile = null
|
this.cachedFile = null
|
||||||
this.hasCoverImage = false
|
this.hasCoverImage = false
|
||||||
this.coverImageDimensions = {width: 0, height: 0}
|
this.coverImageDimensions = {width: 0, height: 0}
|
||||||
this.includeTitlePage = true
|
this.includeTitlePage = true
|
||||||
this.categories = []
|
this.categories = []
|
||||||
this.tags = []
|
this.tags = []
|
||||||
|
|
||||||
|
this.zip = new JSZip()
|
||||||
}
|
}
|
||||||
|
|
||||||
download () {
|
download () {
|
||||||
return new Promise((resolve, reject) => {
|
if (this.downloadPromise) {
|
||||||
if (this.isDownloading) {
|
return this.downloadPromise
|
||||||
reject('Already downloading')
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if (this.hasDownloaded) {
|
|
||||||
resolve()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.build().then(resolve).catch(reject)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
build () {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.isDownloading = true
|
|
||||||
|
|
||||||
this.zip = new JSZip()
|
|
||||||
this.zip.file('mimetype', 'application/epub+zip')
|
|
||||||
this.zip.file('META-INF/container.xml', containerXml)
|
|
||||||
|
|
||||||
console.log('Fetching story metadata...')
|
console.log('Fetching story metadata...')
|
||||||
|
|
||||||
FimFic2Epub.fetchStoryInfo(this.storyId).then((storyInfo) => {
|
let p = FimFic2Epub.fetchStoryInfo(this.storyId)
|
||||||
|
.then((storyInfo) => {
|
||||||
this.storyInfo = storyInfo
|
this.storyInfo = storyInfo
|
||||||
this.storyInfo.uuid = 'urn:fimfiction:' + this.storyInfo.id
|
this.storyInfo.uuid = 'urn:fimfiction:' + this.storyInfo.id
|
||||||
|
|
||||||
this.filename = FimFic2Epub.getFilename(this.storyInfo)
|
this.filename = FimFic2Epub.getFilename(this.storyInfo)
|
||||||
|
|
||||||
this.zip.file('OEBPS/Styles/style.css', styleCss)
|
|
||||||
this.zip.file('OEBPS/Styles/coverstyle.css', coverstyleCss)
|
|
||||||
if (this.includeTitlePage) {
|
|
||||||
this.zip.file('OEBPS/Styles/titlestyle.css', titlestyleCss)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.zip.file('OEBPS/toc.ncx', template.createNcx(this))
|
|
||||||
|
|
||||||
this.fetchTitlePage(resolve, reject)
|
|
||||||
}).catch(reject)
|
|
||||||
})
|
})
|
||||||
|
.then(this.fetchTitlePage.bind(this))
|
||||||
|
.then(() => {
|
||||||
|
this.downloadPromise = null
|
||||||
|
})
|
||||||
|
|
||||||
|
this.downloadPromise = p
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchTitlePage (resolve, reject) {
|
build () {
|
||||||
|
return this.extractTitlePageInfo(this.titlePage)
|
||||||
|
.then(this.checkCoverImage.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchTitlePage () {
|
||||||
console.log('Fetching index page...')
|
console.log('Fetching index page...')
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
fetchRemote(this.storyInfo.url, (raw, type) => {
|
fetchRemote(this.storyInfo.url, (raw, type) => {
|
||||||
this.extractTitlePageInfo(raw).then(() => this.checkCoverImage(resolve, reject))
|
this.titlePage = raw
|
||||||
|
resolve(raw)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +210,8 @@ module.exports = class FimFic2Epub {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCoverImage (resolve, reject) {
|
checkCoverImage () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
this.hasCoverImage = !!this.storyInfo.full_image
|
this.hasCoverImage = !!this.storyInfo.full_image
|
||||||
|
|
||||||
if (this.hasCoverImage) {
|
if (this.hasCoverImage) {
|
||||||
|
@ -245,19 +237,21 @@ module.exports = class FimFic2Epub {
|
||||||
} else {
|
} else {
|
||||||
this.processStory(resolve, reject)
|
this.processStory(resolve, reject)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
processStory (resolve, reject) {
|
processStory (resolve, reject) {
|
||||||
console.log('Fetching chapters...')
|
console.log('Fetching chapters...')
|
||||||
|
|
||||||
this.fetchChapters(() => {
|
this.fetchChapters().then(() => {
|
||||||
this.zip.file('OEBPS/Text/nav.xhtml', template.createNav(this))
|
|
||||||
|
|
||||||
console.log('Fetching remote files...')
|
console.log('Fetching remote files...')
|
||||||
|
|
||||||
this.fetchRemoteFiles(() => {
|
this.fetchRemoteFiles(() => {
|
||||||
console.log('Finishing build...')
|
console.log('Finishing build...')
|
||||||
|
|
||||||
|
this.zip.file('mimetype', 'application/epub+zip')
|
||||||
|
this.zip.file('META-INF/container.xml', containerXml)
|
||||||
|
|
||||||
let coverFilename = ''
|
let coverFilename = ''
|
||||||
this.remoteResources.forEach((r, url) => {
|
this.remoteResources.forEach((r, url) => {
|
||||||
let dest = '../' + r.dest
|
let dest = '../' + r.dest
|
||||||
|
@ -287,6 +281,8 @@ module.exports = class FimFic2Epub {
|
||||||
|
|
||||||
this.chapterContent.length = 0
|
this.chapterContent.length = 0
|
||||||
|
|
||||||
|
this.zip.file('OEBPS/content.opf', template.createOpf(this))
|
||||||
|
|
||||||
if (this.hasCoverImage) {
|
if (this.hasCoverImage) {
|
||||||
this.zip.file('OEBPS/Text/cover.xhtml', template.createCoverPage(coverFilename, this.coverImageDimensions.width, this.coverImageDimensions.height))
|
this.zip.file('OEBPS/Text/cover.xhtml', template.createCoverPage(coverFilename, this.coverImageDimensions.width, this.coverImageDimensions.height))
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,9 +293,15 @@ module.exports = class FimFic2Epub {
|
||||||
this.zip.file('OEBPS/Text/title.xhtml', template.createTitlePage(this))
|
this.zip.file('OEBPS/Text/title.xhtml', template.createTitlePage(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.zip.file('OEBPS/content.opf', template.createOpf(this))
|
this.zip.file('OEBPS/Text/nav.xhtml', template.createNav(this))
|
||||||
|
this.zip.file('OEBPS/toc.ncx', template.createNcx(this))
|
||||||
|
|
||||||
|
this.zip.file('OEBPS/Styles/style.css', styleCss)
|
||||||
|
this.zip.file('OEBPS/Styles/coverstyle.css', coverstyleCss)
|
||||||
|
if (this.includeTitlePage) {
|
||||||
|
this.zip.file('OEBPS/Styles/titlestyle.css', titlestyleCss)
|
||||||
|
}
|
||||||
|
|
||||||
this.isDownloading = false
|
|
||||||
this.hasDownloaded = true
|
this.hasDownloaded = true
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
|
@ -353,14 +355,15 @@ module.exports = class FimFic2Epub {
|
||||||
recursive()
|
recursive()
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchChapters (cb) {
|
fetchChapters () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
let chapters = this.storyInfo.chapters
|
let chapters = this.storyInfo.chapters
|
||||||
let chapterCount = this.storyInfo.chapters.length
|
let chapterCount = this.storyInfo.chapters.length
|
||||||
let currentChapter = 0
|
let currentChapter = 0
|
||||||
let completeCount = 0
|
let completeCount = 0
|
||||||
|
|
||||||
if (chapterCount === 0) {
|
if (chapterCount === 0) {
|
||||||
cb()
|
resolve()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +383,7 @@ module.exports = class FimFic2Epub {
|
||||||
if (completeCount < chapterCount) {
|
if (completeCount < chapterCount) {
|
||||||
recursive()
|
recursive()
|
||||||
} else {
|
} else {
|
||||||
cb()
|
resolve()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -391,6 +394,7 @@ module.exports = class FimFic2Epub {
|
||||||
recursive()
|
recursive()
|
||||||
recursive()
|
recursive()
|
||||||
recursive()
|
recursive()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
findRemoteResources (prefix, where, html) {
|
findRemoteResources (prefix, where, html) {
|
||||||
|
|
74
src/main.js
74
src/main.js
|
@ -36,22 +36,20 @@ let checkbox = {
|
||||||
let dialog = {
|
let dialog = {
|
||||||
controller (args) {
|
controller (args) {
|
||||||
this.dragging = m.prop(false)
|
this.dragging = m.prop(false)
|
||||||
this.xpos = m.prop(100)
|
this.xpos = m.prop(0)
|
||||||
this.ypos = m.prop(100)
|
this.ypos = m.prop(0)
|
||||||
this.el = m.prop(null)
|
this.el = m.prop(null)
|
||||||
|
this.progress = m.prop(0)
|
||||||
this.ondown = (e) => {
|
this.ondown = (e) => {
|
||||||
let el = this.el().firstChild
|
let rect = this.el().firstChild.getBoundingClientRect()
|
||||||
let rect = el.getBoundingClientRect()
|
let offset = {x: e.pageX - rect.left - document.body.scrollLeft, y: e.pageY - rect.top - document.body.scrollTop}
|
||||||
let offset = {x: e.pageX - rect.left, y: e.pageY - rect.top}
|
|
||||||
this.dragging(true)
|
this.dragging(true)
|
||||||
let onmove = (e) => {
|
let onmove = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (this.dragging()) {
|
if (this.dragging()) {
|
||||||
let rect = el.getBoundingClientRect()
|
this.xpos(Math.max(0, e.pageX - offset.x))
|
||||||
this.xpos(Math.max(0, Math.min(e.pageX - offset.x, window.innerWidth - rect.width)))
|
this.ypos(Math.max(0, e.pageY - offset.y))
|
||||||
this.ypos(Math.max(0, Math.min(e.pageY - offset.y, window.innerHeight - rect.height)))
|
this.move()
|
||||||
// console.log(e.pageX, e.pageY)
|
|
||||||
m.redraw()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let onup = () => {
|
let onup = () => {
|
||||||
|
@ -62,12 +60,48 @@ let dialog = {
|
||||||
window.addEventListener('mousemove', onmove, false)
|
window.addEventListener('mousemove', onmove, false)
|
||||||
window.addEventListener('mouseup', onup, false)
|
window.addEventListener('mouseup', onup, false)
|
||||||
}
|
}
|
||||||
|
this.onOpen = function (el, first) {
|
||||||
|
if (!first) {
|
||||||
|
this.el(el)
|
||||||
|
let rect = this.el().firstChild.getBoundingClientRect()
|
||||||
|
this.xpos((window.innerWidth / 2) - (rect.width / 2) + document.body.scrollLeft)
|
||||||
|
this.ypos((window.innerHeight / 2) - (rect.height / 2) + document.body.scrollTop)
|
||||||
|
this.move()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.move = () => {
|
||||||
|
this.el().style.left = this.xpos() + 'px'
|
||||||
|
this.el().style.top = this.ypos() + 'px'
|
||||||
|
}
|
||||||
|
this.createEpub = (e) => {
|
||||||
|
e.target.disabled = true
|
||||||
|
ffc.download()
|
||||||
|
.then(ffc.build.bind(ffc))
|
||||||
|
.then(ffc.getFile.bind(ffc)).then((file) => {
|
||||||
|
console.log('Saving file...')
|
||||||
|
if (typeof safari !== 'undefined') {
|
||||||
|
blobToDataURL(file, (dataurl) => {
|
||||||
|
document.location.href = dataurl
|
||||||
|
alert('Add .epub to the filename of the downloaded file')
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
saveAs(file, ffc.filename)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
view (ctrl, args, extras) {
|
view (ctrl, args, extras) {
|
||||||
return m('.drop-down-pop-up-container', {config: ctrl.el, style: {left: ctrl.xpos() + 'px', top: ctrl.ypos() + 'px'}}, m('.drop-down-pop-up', [
|
return m('.drop-down-pop-up-container', {config: ctrl.onOpen.bind(ctrl)}, m('.drop-down-pop-up', [
|
||||||
m('h1', {onmousedown: ctrl.ondown}, m('i.fa.fa-book'), 'Export EPUB', m('a.close_button', {onclick: closeDialog})),
|
m('h1', {onmousedown: ctrl.ondown}, m('i.fa.fa-book'), 'Export to EPUB', m('a.close_button', {onclick: closeDialog})),
|
||||||
m('.drop-down-pop-up-content', [
|
m('.drop-down-pop-up-content', [
|
||||||
m(checkbox, {name: 'toggle-chapter-headings'}, 'Toggle chapter headings')
|
m('table.properties', [
|
||||||
|
m('tr', m('td.label', 'Cover image'), m('td', 'some config')),
|
||||||
|
m('tr', m('td.label', 'Chapter headings'), m('td', m(checkbox, {name: 'toggle-chapter-headings'})))
|
||||||
|
]),
|
||||||
|
m('.drop-down-pop-up-footer', [
|
||||||
|
m('button.styled_button', {onclick: ctrl.createEpub}, 'Create EPUB'),
|
||||||
|
ctrl.progress() > 0 ? m('.rating_container', m('.bars_container', m('.bar_container', m('.bar_dislike', m('.bar.bar_like', {style: {width: ctrl.progress() * 100 + '%'}}))))) : null
|
||||||
|
])
|
||||||
])
|
])
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
@ -85,20 +119,6 @@ function clickButton () {
|
||||||
if (!ffc) ffc = new FimFic2Epub(STORY_ID)
|
if (!ffc) ffc = new FimFic2Epub(STORY_ID)
|
||||||
|
|
||||||
openDialog()
|
openDialog()
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
ffc.download().then(ffc.getFile.bind(ffc)).then((file) => {
|
|
||||||
console.log('Saving file...')
|
|
||||||
if (typeof safari !== 'undefined') {
|
|
||||||
blobToDataURL(file, (dataurl) => {
|
|
||||||
document.location.href = dataurl
|
|
||||||
alert('Add .epub to the filename of the downloaded file')
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
saveAs(file, ffc.filename)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (epubButton) {
|
if (epubButton) {
|
||||||
|
|
Loading…
Reference in a new issue