proper module

This commit is contained in:
daniel-j 2016-08-15 11:11:20 +02:00
parent daf4c4ec7f
commit 0fbacd0546
9 changed files with 139 additions and 113 deletions

3
.gitignore vendored
View file

@ -1,12 +1,13 @@
.DS_Store
node_modules/
extension/fimfic2epub.js
extension/eventPage.js
extension/*.js.map
extension.crx
extension.pem
extension.xpi
extension.zip
fimfic2epub.safariextension/
fimfic2epub.js
fimfic2epub.js.map
*.epub

View file

@ -15,12 +15,18 @@ Right now the addon is not available in Add-ons for Firefox, but it's fully comp
Installation & usage (command line)
-------------------
You can install the tool by running `npm install -g fimfic2epub`. You can then run it with `$ fimfic2epub <story id>`. This will save the EPUB in the current working directory.
You can install the tool by running `npm install -g fimfic2epub`. You can then run it with `$ fimfic2epub <story id> <optional filename>`. By default the EPUB will be saved in the current working directory with the filename `Title by Author.epub`. You can set filename to `-` and the epub will be emitted to stdout instead.
Example:
```
Download Tag Test by McPoodle
Download with automatic filename:
$ fimfic2epub 180690
Download and save to a specified filename:
$ fimfic2epub 180690 path/to/file.epub
Same as above, but use a pipe:
$ fimfic2epub 180690 - > path/to/file.epub
```

View file

@ -1,11 +1,38 @@
#!/usr/bin/env node
const FimFic2Epub = require('../fimfic2epub')
const fs = require('fs')
const STORY_ID = process.argv[2]
const ffc = new FimFic2Epub(STORY_ID)
ffc.download().then(() => {
ffc.saveStory()
const outputStdout = process.argv[3] === '-' || process.argv[3] === '/dev/stdout'
if (outputStdout) {
console.log = console.error
console.log('Outputting to stdout')
}
ffc.download()
.then(() => {
let filename = process.argv[3] || ffc.filename
let stream
if (outputStdout) {
stream = process.stdout
} else {
stream = fs.createWriteStream(filename)
}
ffc.streamFile()
.pipe(stream)
.on('finish', () => {
if (!outputStdout) {
console.log('Saved story as ' + filename)
}
})
})
.catch((err) => {
console.log('Error: ' + (err || 'Unknown error'))
process.exit(1)
})

View file

@ -4,7 +4,7 @@
"name": "fimfic2epub",
"short_name": "fimfic2epub",
"description": "Improved EPUB exporter for Fimfiction",
"version": "1.0.9",
"version": "1.1.0",
"icons": {
"128": "icon-128.png"

View file

@ -34,26 +34,21 @@ webpackConfig.forEach((c) => {
debug: false
}))
c.plugins.push(new webpack.optimize.DedupePlugin())
/*
c.plugins.push(new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true
},
comments: false,
mangle: {
screw_ie8: true
},
screw_ie8: true,
sourceMap: false
}))
*/
if (c.uglify) {
c.plugins.push(new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true
},
comments: false,
mangle: {
screw_ie8: true
},
screw_ie8: true,
sourceMap: !!c.devtool
}))
}
}
Object.assign({}, c, {
cache: {},
devtool: inProduction ? null : 'inline-source-map',
debug: !inProduction
})
})
const wpCompiler = webpack(webpackConfig)
@ -79,7 +74,17 @@ let lintPipe = lazypipe()
.pipe(standard.reporter, 'default', { breakOnError: false })
// Cleanup task
gulp.task('clean', () => del(['extension/fimfic2epub.js', 'extension/eventPage.js']))
gulp.task('clean', () => del([
'extension/fimfic2epub.js',
'extension/eventPage.js',
'extension/*.js.map',
'fimfic2epub.js',
'fimfic2epub.js.map',
'extension.zip',
'extension.xpi',
'extension.crx',
'fimfic2epub.safariextension/'
]))
// Main tasks
gulp.task('webpack', webpackTask)
@ -90,7 +95,7 @@ gulp.task('watch:webpack', () => {
})
gulp.task('lint', () => {
return gulp.src(['gulpfile.babel.js', 'webpack.config.babel.js', 'src/**/*.js']).pipe(lintPipe())
return gulp.src(['gulpfile.babel.js', 'webpack.config.babel.js', 'src/**/*.js', 'bin/fimfic2epub']).pipe(lintPipe())
})
gulp.task('watch:lint', () => {
return watch(['src/**/*.js'], watchOpts, function (file) {
@ -147,7 +152,7 @@ gulp.task('pack:chrome', (done) => {
})
gulp.task('pack:safari', (done) => {
exec('cp -r extension/ fimfic2epub.safariextension', [], (error, stdout, stderr) => {
exec('rm -rf fimfic2epub.safariextension/; cp -r extension/ fimfic2epub.safariextension', [], (error, stdout, stderr) => {
// gutil.log('[pack:chrome]', stdout)
if (error || stderr) {
done(new gutil.PluginError('pack:safari', stderr, {showStack: false}))

View file

@ -1,6 +1,6 @@
{
"name": "fimfic2epub",
"version": "1.0.9",
"version": "1.1.0",
"description": "Tool to generate EPUB ebooks from fimfiction stories",
"author": "djazz",
"scripts": {
@ -10,13 +10,13 @@
"fimfic2epub": "./bin/fimfic2epub"
},
"main": "fimfic2epub.js",
"engines": {
"node": ">=0.6.0"
},
"files": [
"fimfic2epub.js",
"fimfic2epub.js.map",
"bin/"
],
"dependencies": {
"detect-node": "^2.0.3",
"escape-string-regexp": "^1.0.5",
@ -26,17 +26,19 @@
"mithril": "^0.2.5",
"pretty-data": "^0.40.0",
"request": "^2.74.0",
"sanitize-filename": "^1.6.0",
"tidy-html5": "^0.1.1",
"zero-fill": "^2.2.3"
},
"devDependencies": {
"file-saver": "^1.3.2",
"babel-register": "^6.11.6",
"babel-preset-node6": "^11.0.0",
"babel-core": "^6.13.2",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.13.2",
"babel-preset-node6": "^11.0.0",
"babel-register": "^6.11.6",
"del": "^2.2.2",
"exports-loader": "^0.6.3",
"file-saver": "^1.3.2",
"gulp": "^3.9.1",
"gulp-filter": "^4.0.0",
"gulp-json-editor": "^2.2.1",
@ -53,6 +55,7 @@
"webpack": "^2.1.0-beta.13",
"webpack-node-externals": "^1.3.3"
},
"standard": {
"env": {
"browser": true

View file

@ -3,6 +3,7 @@ import JSZip from 'jszip'
import escapeStringRegexp from 'escape-string-regexp'
import zeroFill from 'zero-fill'
import { XmlEntities } from 'html-entities'
import sanitize from 'sanitize-filename'
import isNode from 'detect-node'
@ -16,12 +17,6 @@ import { mimeMap, containerXml } from './constants'
const entities = new XmlEntities()
function blobToDataURL (blob, callback) {
let a = new FileReader()
a.onloadend = function (e) { callback(a.result) }
a.readAsDataURL(blob)
}
module.exports = class FimFic2Epub {
constructor (storyId) {
@ -32,7 +27,7 @@ module.exports = class FimFic2Epub {
this.remoteResources = new Map()
this.storyInfo = null
this.isDownloading = false
this.cachedBlob = null
this.cachedFile = null
this.hasCoverImage = false
this.includeTitlePage = true
this.categories = []
@ -42,10 +37,10 @@ module.exports = class FimFic2Epub {
download () {
return new Promise((resolve, reject) => {
if (this.isDownloading) {
reject()
reject('Already downloading')
return
}
if (this.cachedBlob) {
if (this.cachedFile) {
resolve()
return
}
@ -79,6 +74,8 @@ module.exports = class FimFic2Epub {
this.storyInfo.chapters = this.storyInfo.chapters || []
this.storyInfo.uuid = 'urn:fimfiction:' + this.storyInfo.id
this.filename = sanitize(this.storyInfo.title + ' by ' + this.storyInfo.author.name + '.epub')
this.zip.file('Styles/style.css', styleCss)
this.zip.file('Styles/coverstyle.css', coverstyleCss)
if (this.includeTitlePage) {
@ -245,26 +242,8 @@ module.exports = class FimFic2Epub {
this.zip.file('content.opf', template.createOpf(this))
console.log('Packaging epub...')
if (!isNode) {
this.zip
.generateAsync({
type: 'blob',
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
})
.then((blob) => {
this.cachedBlob = blob
this.isDownloading = false
resolve()
})
} else {
this.cachedBlob = true
this.isDownloading = false
resolve()
}
this.isDownloading = false
resolve()
})
})
}
@ -373,47 +352,35 @@ module.exports = class FimFic2Epub {
}
}
saveStory () {
let filename = this.storyInfo.title + ' by ' + this.storyInfo.author.name + '.epub'
console.log('Saving epub...')
if (isNode) {
const fs = require('fs')
/*this.zip.generateAsync({
type: 'nodebuffer',
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
}).then((epub) => {
console.log(epub)
})*/
// for node, resolve a Buffer, in browser resolve a Blob
getFile () {
return new Promise((resolve, reject) => {
if (this.cachedFile) {
resolve(this.cachedFile, this.filename)
return
}
this.zip
.generateNodeStream({
type: 'nodebuffer',
streamFiles: true,
.generateAsync({
type: isNode ? 'nodebuffer' : 'blob',
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
}).then((file) => {
this.cachedFile = file
resolve(file)
})
.pipe(fs.createWriteStream(filename))
.on('finish', () => {
console.log('Saved epub as', filename)
})
.on('error', (err) => {
throw err
})
return
}
if (typeof safari !== 'undefined') {
blobToDataURL(this.cachedBlob, (dataurl) => {
document.location.href = dataurl
alert('Rename downloaded file to .epub')
})
} else {
const saveAs = require('file-saver')
saveAs(this.cachedBlob, filename)
}
})
}
// example usage: .pipe(fs.createWriteStream(filename))
streamFile () {
return this.zip
.generateNodeStream({
type: 'nodebuffer',
streamFiles: true,
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {level: 9}
})
}
}

View file

@ -1,5 +1,12 @@
import FimFic2Epub from './FimFic2Epub'
import { saveAs } from 'file-saver'
function blobToDataURL (blob, callback) {
let a = new FileReader()
a.onloadend = function (e) { callback(a.result) }
a.readAsDataURL(blob)
}
const STORY_ID = document.location.pathname.match(/^\/story\/(\d*)/)[1]
@ -11,7 +18,17 @@ if (epubButton) {
epubButton.addEventListener('click', function (e) {
e.preventDefault()
ffc.download().then(() => {
ffc.saveStory()
ffc.getFile().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)
}
})
})
}, false)
}

View file

@ -2,7 +2,7 @@
import path from 'path'
import nodeExternals from 'webpack-node-externals'
// let inProduction = process.env.NODE_ENV === 'production' || process.argv.indexOf('-p') !== -1
let inProduction = process.env.NODE_ENV === 'production' || process.argv.indexOf('-p') !== -1
const bundleExtensionConfig = {
entry: {
@ -17,13 +17,12 @@ const bundleExtensionConfig = {
module: {
loaders: [
/*
{
test: /\.js$/, loader: 'babel', exclude: /node_modules/, query: {
sourceMaps: inProduction
sourceMaps: true,
presets: ['es2015']
}
},
*/
{
test: /\.styl$/,
loader: 'raw-loader!stylus-loader'
@ -45,8 +44,9 @@ const bundleExtensionConfig = {
externals: ['request', 'fs', 'tidy-html5', 'image-size'],
plugins: [],
devtool: 'inline-source-map',
debug: true
devtool: 'source-map',
debug: true,
uglify: inProduction
}
const bundleNpmModuleConfig = {
@ -62,13 +62,12 @@ const bundleNpmModuleConfig = {
module: {
loaders: [
/*
{
test: /\.js$/, loader: 'babel', exclude: /node_modules/, query: {
sourceMaps: inProduction
sourceMaps: !inProduction,
presets: ['es2015']
}
},
*/
{
test: /\.styl$/,
loader: 'raw-loader!stylus-loader'
@ -90,8 +89,9 @@ const bundleNpmModuleConfig = {
externals: [nodeExternals(), 'exports?tidy_html5!tidy-html5'],
plugins: [],
devtool: 'inline-source-map',
debug: true
devtool: 'source-map',
debug: true,
uglify: inProduction
}
export default [bundleExtensionConfig, bundleNpmModuleConfig]