From 8ccc6f74e5eb94fb9b052b697cfc8a5be81847bc Mon Sep 17 00:00:00 2001 From: daniel-j Date: Sun, 21 Jul 2024 16:24:08 +0200 Subject: [PATCH] show errors from kepubify and kindlegen, scrap flash cookie --- index.js | 73 ++++++++++++++++++++++++++++++++++++++++------ static/style.css | 1 + static/upload.html | 47 ++++++++++++++++------------- 3 files changed, 91 insertions(+), 30 deletions(-) diff --git a/index.js b/index.js index d06bc76..1a23609 100644 --- a/index.js +++ b/index.js @@ -78,12 +78,12 @@ function expireKey (key) { function flash (ctx, data) { console.log(data) - ctx.cookies.set('flash', encodeURIComponent(JSON.stringify(data)), {overwrite: true, httpOnly: false, sameSite: 'strict', maxAge: 10 * 1000}) + //ctx.cookies.set('flash', encodeURIComponent(JSON.stringify(data)), {overwrite: true, httpOnly: false, sameSite: 'strict', maxAge: 10 * 1000}) ctx.response.status = data.success ? 200 : 400 if (!data.success) { ctx.set("Connection", "close") } - ctx.body = data + ctx.body = data.message } const app = new Koa() @@ -315,12 +315,24 @@ router.post('/upload', async (ctx, next) => { conversion = 'kindlegen' const outname = ctx.request.file.path.replace(/\.epub$/i, '.mobi') filename = filename.replace(/\.kepub\.epub$/i, '.epub').replace(/\.epub$/i, '.mobi') + let stderr = '' - data = await new Promise((resolve, reject) => { + let p = new Promise((resolve, reject) => { const kindlegen = spawn('kindlegen', [basename(ctx.request.file.path), '-dont_append_source', '-c1', '-o', basename(outname)], { - stdio: 'inherit', + // stdio: 'inherit', cwd: dirname(ctx.request.file.path) }) + kindlegen.once('error', function (err) { + fs.unlink(ctx.request.file.path, (err) => { + if (err) console.error(err) + else console.log('Removed file', ctx.request.file.path) + }) + fs.unlink(ctx.request.file.path.replace(/\.epub$/i, '.mobi8'), (err) => { + if (err) console.error(err) + else console.log('Removed file', ctx.request.file.path.replace(/\.epub$/i, '.mobi8')) + }) + reject('kindlegen error: ' + err) + }) kindlegen.once('close', (code) => { fs.unlink(ctx.request.file.path, (err) => { if (err) console.error(err) @@ -330,13 +342,31 @@ router.post('/upload', async (ctx, next) => { if (err) console.error(err) else console.log('Removed file', ctx.request.file.path.replace(/\.epub$/i, '.mobi8')) }) - if (code !== 0) { - console.warn('kindlegen error code ' + code) + if (code !== 0 && code !== 1) { + reject('kindlegen error code: ' + code + '\n' + stderr) + return } resolve(outname) }) + kindlegen.stdout.on('data', function (str) { + stderr += str + console.log('kindlegen: ' + str) + }) + kindlegen.stderr.on('data', function (str) { + stderr += str + console.log('kindlegen: ' + str) + }) }) + try { + data = await p + } catch (err) { + flash(ctx, { + success: false, + message: err.replaceAll(basename(ctx.request.file.path), "infile.epub").replaceAll(basename(outname), "outfile.mobi") + }) + return + } } else if (mimetype === TYPE_EPUB && (info.agent.includes('Kobo') || info.agent.toLowerCase().includes('tolino')) && ctx.request.body.kepubify) { // convert to Kobo EPUB @@ -344,24 +374,49 @@ router.post('/upload', async (ctx, next) => { const outname = ctx.request.file.path.replace(/\.epub$/i, '.kepub.epub') filename = filename.replace(/\.kepub\.epub$/i, '.epub').replace(/\.epub$/i, '.kepub.epub') - data = await new Promise((resolve, reject) => { + let p = new Promise((resolve, reject) => { + let stderr = '' const kepubify = spawn('kepubify', ['-v', '-u', '-o', basename(outname), basename(ctx.request.file.path)], { - stdio: 'inherit', + //stdio: 'inherit', cwd: dirname(ctx.request.file.path) }) + kepubify.once('error', function (err) { + fs.unlink(ctx.request.file.path, (err) => { + if (err) console.error(err) + else console.log('Removed file', ctx.request.file.path) + }) + reject('kepubify error: ' + err) + }) kepubify.once('close', (code) => { fs.unlink(ctx.request.file.path, (err) => { if (err) console.error(err) else console.log('Removed file', ctx.request.file.path) }) if (code !== 0) { - reject('kepubify error code ' + code) + reject('Kepubify error code: ' + code + '\n' + stderr) return } resolve(outname) }) + kepubify.stdout.on('data', function (str) { + stderr += str + console.log('kepubify: ' + str) + }) + kepubify.stderr.on('data', function (str) { + stderr += str + console.log('kepubify: ' + str) + }) }) + try { + data = await p + } catch (err) { + flash(ctx, { + success: false, + message: err.replaceAll(basename(ctx.request.file.path), "infile.epub").replaceAll(basename(outname), "outfile.kepub.epub") + }) + return + } } else { // No conversion data = ctx.request.file.path diff --git a/static/style.css b/static/style.css index 303d9c8..edd5170 100644 --- a/static/style.css +++ b/static/style.css @@ -94,6 +94,7 @@ input[type="url"], input[type="text"] { text-align: center; cursor: pointer; line-height: 1.7; + white-space: pre; } #uploadstatus.success { diff --git a/static/upload.html b/static/upload.html index fd6e4f3..b0d62f2 100644 --- a/static/upload.html +++ b/static/upload.html @@ -50,19 +50,27 @@ var siteurl = document.getElementById('siteurl') var flashtimer = null -function handleFlash(flashFallback) { - var flash = getCookies().flash - if (!flash) flash = flashFallback +function hideUploadStatus() { + uploadstatus.style.opacity = 0 + clearTimeout(flashtimer) + flashtimer = setTimeout(function () { + uploadstatus.textContent = '' + uploadstatus.className = '' + }, 500) +} + +function handleFlash(flash) { + // if (!flash) getCookies().flash console.log(flash) clearTimeout(flashtimer) if (flash) { if (flash.message) { if (flash.success) { uploadstatus.className = " success" - uploadstatus.innerHTML = flash.message + uploadstatus.innerHTML = flash.message.trim() } else { uploadstatus.className = " error" - uploadstatus.textContent = flash.message + uploadstatus.textContent = flash.message.trim() } uploadstatus.style.opacity = 1 } @@ -73,24 +81,14 @@ function handleFlash(flashFallback) { urlinput.value = flash.url } } else { - uploadstatus.style.opacity = 0 - - flashtimer = setTimeout(function () { - uploadstatus.textContent = '' - uploadstatus.className = '' - }, 500) + hideUploadStatus() } } -handleFlash() +// handleFlash() uploadstatus.addEventListener('click', function () { - uploadstatus.style.opacity = 0 - clearTimeout(flashtimer) - flashtimer = setTimeout(function () { - uploadstatus.textContent = '' - uploadstatus.className = '' - }, 500) + hideUploadStatus() }, false) @@ -135,6 +133,7 @@ if (isIOS) { } uploadform.addEventListener('submit', function (e) { + hideUploadStatus() e.preventDefault() var fd = new FormData(uploadform) var req = new XMLHttpRequest() @@ -149,10 +148,13 @@ uploadform.addEventListener('submit', function (e) { } req.onload = function () { console.log('upload ok', req.status, req.responseText, req.responseType) - handleFlash() + handleFlash({ + success: req.status == 200, + message: req.responseText + }) } req.onerror = function () { - console.log('upload error', req.status) + console.log('upload error', req.status, req.responseText, req.responseType) handleFlash({ success: false, message: "Upload error - is the key correct?" @@ -160,7 +162,10 @@ uploadform.addEventListener('submit', function (e) { } req.onabort = function () { console.log('aborted', req.status) - handleFlash() + handleFlash({ + success: false, + message: "Upload aborted" + }) } req.send(fd) return false