Skip to content

Commit

Permalink
Merge pull request #39 from GreatWizard/ci/kindlegen
Browse files Browse the repository at this point in the history
  • Loading branch information
GreatWizard authored Nov 6, 2021
2 parents 4f9f12f + 5122661 commit fc1651d
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 53 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ jobs:
distribution: "temurin"
java-version: "17"
- run: |
sudo apt-get update
PANDOC_URL=$(curl https://api.github.com/repos/jgm/pandoc/releases/latest | jq -r ".assets[] | select(.name | test(\"amd64.deb$\")) | .browser_download_url")
curl --silent --show-error --location --fail --retry 4 --retry-delay 5 --output pandoc.deb $PANDOC_URL
sudo dpkg -i pandoc.deb
sudo apt install -f
rm pandoc.deb
- run: yarn install
- run: yarn test
10 changes: 5 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ const path = require('path')

const build = require('./lib/build')
const getFormats = require('./lib/get-formats')
const { installKindlegen } = require('./lib/kindlegen')
const { detectOrInstallKindlegen } = require('./lib/kindlegen')
const mergeConfig = require('./lib/merge-config')
const { printTitle, warn, info, success, error } = require('./lib/message')
const { getOptions, printVersion, printHelp } = require('./lib/options')
const { findConfig, readConfig, validateConfig } = require('./lib/read-config')

const settings = { kindlegen: false, pdf: true }
const settings = { kindlegenPath: undefined }

const options = getOptions()

Expand All @@ -29,13 +29,13 @@ const options = getOptions()
printTitle()

try {
settings.kindlegen = await installKindlegen({
settings.kindlegenPath = await detectOrInstallKindlegen({
mobi: options.mobi,
kindlegenPath: options['kindlegen-path'],
})
} catch (e) {
warn(`Kindle format (Mobi) is disabled: ${e.message}`)
settings.kindlegen = false
settings.kindlegenPath = undefined
}

let configFile = await findConfig(options.config)
Expand All @@ -54,7 +54,7 @@ const options = getOptions()
new Promise(function (resolve, reject) {
return build(currentConfig, {
cwd,
kindlegenPath: options['kindlegen-path'],
kindlegenPath: settings.kindlegenPath,
debug: options.debug,
})
.then(() => {
Expand Down
6 changes: 1 addition & 5 deletions lib/get-formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ const defaultChoices = ['epub', 'mobi', 'pdf']
module.exports = (settings, options = {}) => {
let choices = defaultChoices

if (!settings.kindlegen) {
if (!settings.kindlegenPath) {
choices.splice(choices.indexOf('mobi'), 1)
}

if (!settings.pdf) {
choices.splice(choices.indexOf('pdf'), 1)
}

if (options.epub || options.mobi || options.pdf) {
let result = []
if (options.epub && choices.includes('epub')) {
Expand Down
102 changes: 63 additions & 39 deletions lib/kindlegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { spawn } = require('child_process')
const tar = require('tar')
const unzipper = require('unzipper')

const { warn } = require('./message')
const { humanizePlatformArch } = require('./utils')

const kindlegenFilename = () => (process.platform === 'win32' ? 'kindlegen.exe' : 'kindlegen')
Expand Down Expand Up @@ -59,31 +60,36 @@ const downloadKindleGen = (fileUrl) => {
})
}

const extractKindleGen = async (file) => {
let stream = fs.createReadStream(file.path)
const extractKindleGen = (file) => {
let filename = kindlegenFilename()
if (file.path.endsWith('.zip')) {
const zip = stream.pipe(unzipper.Parse({ forceStream: true }))
for await (const entry of zip) {
if (entry.path === filename) {
entry.pipe(fs.createWriteStream(filename))
} else {
entry.autodrain()
}
}
} else if (file.path.endsWith('.tar.gz')) {
stream.pipe(
tar.x({
filter(path) {
return path === filename
},
}),
)
return fs
.createReadStream(file.path)
.pipe(unzipper.Parse())
.on('entry', function (entry) {
if (entry.path === filename) {
entry.pipe(fs.createWriteStream(filename))
} else {
entry.autodrain()
}
})
.promise()
}
await new Promise((resolve) => stream.on('end', resolve))
if (process.platform === 'darwin' || process.platform === 'linux') {
fs.chmodSync('kindlegen', 0o755)
if (file.path.endsWith('.tar.gz')) {
return new Promise((resolve, reject) => {
fs.createReadStream(file.path)
.pipe(
tar.x({
filter(path) {
return path === filename
},
}),
)
.on('finish', () => resolve())
.on('error', (err) => reject(err.message))
})
}
throw new Error('Unsupported file format')
}

module.exports.epubToMobi = (input, output, options = {}) => {
Expand All @@ -105,28 +111,35 @@ module.exports.epubToMobi = (input, output, options = {}) => {
})
}

module.exports.installKindlegen = async (options = {}) => {
let forceInstall = options.mobi
if (options.kindlegenPath) {
if (!fs.existsSync(options.kindlegenPath)) {
throw new Error(`KindleGen seems not installed at the location "${options.kindlegenPath}"`)
module.exports.detectOrInstallKindlegen = async (options = {}) => {
let { kindlegenPath } = options
let binUrl = undefined
if (process.platform === 'darwin' && process.arch === 'x32') {
binUrl = 'https://archive.org/download/kindlegen-mac-i386-v2-9/KindleGen_Mac_i386_v2_9.zip'
} else if (process.platform === 'linux') {
binUrl = 'https://archive.org/download/kindlegen_linux_2_6_i386_v2_9/kindlegen_linux_2.6_i386_v2_9.tar.gz'
} else if (process.platform === 'win32') {
binUrl = 'https://archive.org/download/kindlegen_win32_v2_9/kindlegen_win32_v2_9.zip'
}
if (kindlegenPath) {
if (!fs.existsSync(kindlegenPath)) {
throw new Error(`KindleGen seems not installed at the location "${kindlegenPath}"`)
}
} else {
if (!fs.existsSync(localKindlegenPath())) {
let binUrl
if (process.platform === 'darwin' && process.arch === 'x32') {
binUrl = 'https://archive.org/download/kindlegen-mac-i386-v2-9/KindleGen_Mac_i386_v2_9.zip'
} else if (process.platform === 'linux') {
binUrl = 'https://archive.org/download/kindlegen_linux_2_6_i386_v2_9/kindlegen_linux_2.6_i386_v2_9.tar.gz'
} else if (process.platform === 'win32') {
binUrl = 'https://archive.org/download/kindlegen_win32_v2_9/kindlegen_win32_v2_9.zip'
} else {
throw new Error(`Unsupported platform ${humanizePlatformArch(process.platform, process.arch)}`)
kindlegenPath = localKindlegenPath()
if (!fs.existsSync(kindlegenPath)) {
if (!binUrl) {
throw new Error(
`Building ebook in mobi format is not compatible with your platform ${humanizePlatformArch(
process.platform,
process.arch,
)}.`,
)
}
console.log(`KindleGen is a tool to convert files to the Kindle format (Mobi) enabling publishers to create great-looking books that work on all Kindle devices and apps.
KindleGen is officially supported by Amazon.
To install KindleGen, you must accept the following terms of use: https://www.amazon.com/gp/feature.html?docId=1000599251`)
let install = forceInstall
let install = options.mobi
if (!install) {
let { startInstall } = await inquirer.prompt([
{
Expand All @@ -142,10 +155,21 @@ To install KindleGen, you must accept the following terms of use: https://www.am
let file = await downloadKindleGen(binUrl)
console.log('* Extract KindleGen in the current directory')
await extractKindleGen(file)
if (process.platform === 'darwin' || process.platform === 'linux') {
fs.chmodSync(kindlegenPath, 0o755)
}
}
console.log()
return install
return install ? kindlegenPath : undefined
}
}
return true
if (!binUrl) {
warn(
`Building ebook in mobi format may produce errors. KindleGen has been detected but it looks like it's not compatible with your platform ${humanizePlatformArch(
process.platform,
process.arch,
)}.`,
)
}
return kindlegenPath
}
3 changes: 3 additions & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports.getOptions = () => {
if (options['_'] && options['_'].length > 0) {
options.config = options['_'][0]
}
if (options['kindlegen-path'] === '') {
delete options['kindlegen-path']
}
return options
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"lint:fix": "eslint . --fix",
"pretest": "node scripts/github-releases.js",
"test": "npm-run-all test:*",
"test:custom-fonts-ttf": "cd tests/custom-fonts-ttf && ./../../index.js --debug --epub --mobi --pdf && java -jar ../../github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar ./*.epub",
"test:custom-fonts-otf": "cd tests/custom-fonts-otf && ./../../index.js --debug --epub --mobi --pdf && java -jar ../../github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar ./*.epub",
"test:custom-fonts-ttf": "./index.js --debug --epub --mobi --pdf tests/custom-fonts-ttf && java -jar github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar tests/custom-fonts-ttf/*.epub",
"test:custom-fonts-otf": "./index.js --debug --epub --mobi --pdf tests/custom-fonts-otf && java -jar github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar tests/custom-fonts-otf/*.epub",
"test:docx-one-file": "./index.js --debug --epub --mobi --pdf tests/docx-one-file && java -jar github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar tests/docx-one-file/*.epub",
"test:latex-one-file": "./index.js --debug --epub --mobi --pdf tests/latex-one-file && java -jar github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar tests/latex-one-file/*.epub",
"test:markdown-one-file": "./index.js --debug --epub --mobi --pdf tests/markdown-one-file && java -jar github_releases/w3c/epubcheck/epubcheck-*/epubcheck.jar tests/latex-one-file/*.epub",
Expand Down

0 comments on commit fc1651d

Please sign in to comment.