reorganize file structure, add sending urls
This commit is contained in:
251
index.js
251
index.js
@@ -5,6 +5,8 @@ const Router = require('@koa/router')
|
||||
const multer = require('@koa/multer')
|
||||
const logger = require('koa-logger')
|
||||
const sendfile = require('koa-sendfile')
|
||||
const serve = require('koa-static')
|
||||
const mount = require('koa-mount')
|
||||
const { mkdirp } = require('mkdirp')
|
||||
const fs = require('fs')
|
||||
const { spawn } = require('child_process')
|
||||
@@ -76,7 +78,7 @@ function expireKey (key) {
|
||||
|
||||
function flash (ctx, data) {
|
||||
console.log(data)
|
||||
ctx.cookies.set('flash', encodeURIComponent(JSON.stringify(data)), {overwrite: true, httpOnly: false})
|
||||
ctx.cookies.set('flash', encodeURIComponent(JSON.stringify(data)), {overwrite: true, httpOnly: false, sameSite: 'strict', maxAge: 10 * 1000})
|
||||
}
|
||||
|
||||
const app = new Koa()
|
||||
@@ -142,7 +144,8 @@ router.post('/generate', async ctx => {
|
||||
const info = {
|
||||
created: new Date(),
|
||||
agent: agent,
|
||||
file: null
|
||||
file: null,
|
||||
urls: []
|
||||
}
|
||||
ctx.keys.set(key, info)
|
||||
expireKey(key)
|
||||
@@ -200,123 +203,153 @@ router.post('/upload', upload.single('file'), async ctx => {
|
||||
return
|
||||
}
|
||||
|
||||
if (!ctx.request.file || ctx.request.file.size === 0) {
|
||||
flash(ctx, {
|
||||
message: 'Invalid file submitted',
|
||||
success: false,
|
||||
key: key
|
||||
})
|
||||
ctx.redirect('back', '/')
|
||||
if (ctx.request.file) {
|
||||
const info = ctx.keys.get(key)
|
||||
expireKey(key)
|
||||
|
||||
let url = null
|
||||
if (ctx.request.body.url) {
|
||||
url = ctx.request.body.url.trim()
|
||||
if (url.length > 0 && !info.urls.includes(url)) {
|
||||
info.urls.push(url)
|
||||
}
|
||||
}
|
||||
|
||||
let conversion = null
|
||||
let filename = ""
|
||||
|
||||
if (ctx.request.file) {
|
||||
if (ctx.request.file.size === 0) {
|
||||
flash(ctx, {
|
||||
message: 'Invalid file submitted',
|
||||
success: false,
|
||||
key: key
|
||||
})
|
||||
ctx.redirect('back', '/')
|
||||
fs.unlink(ctx.request.file.path, (err) => {
|
||||
if (err) console.error(err)
|
||||
else console.log('Removed file', ctx.request.file.path)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const mimetype = ctx.request.file.mimetype
|
||||
|
||||
const type = await FileType.fromFile(ctx.request.file.path)
|
||||
|
||||
if ((!type || !allowedTypes.includes(type.mime)) && !allowedTypes.includes(mimetype)) {
|
||||
flash(ctx, {
|
||||
message: 'Uploaded file is of an invalid type: ' + ctx.request.file.originalname + ' (' + (type? type.mime : 'unknown mimetype') + ')',
|
||||
success: false,
|
||||
key: key
|
||||
})
|
||||
ctx.redirect('back', '/')
|
||||
fs.unlink(ctx.request.file.path, (err) => {
|
||||
if (err) console.error(err)
|
||||
else console.log('Removed file', ctx.request.file.path)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let data = null
|
||||
filename = ctx.request.file.originalname
|
||||
|
||||
if (mimetype === TYPE_EPUB && info.agent.includes('Kindle')) {
|
||||
// convert to .mobi
|
||||
conversion = 'kindlegen'
|
||||
const outname = ctx.request.file.path.replace(/\.epub$/i, '.mobi')
|
||||
filename = filename.replace(/\.kepub\.epub$/i, '.epub').replace(/\.epub$/i, '.mobi')
|
||||
|
||||
data = await new Promise((resolve, reject) => {
|
||||
const kindlegen = spawn('kindlegen', [basename(ctx.request.file.path), '-dont_append_source', '-c1', '-o', basename(outname)], {
|
||||
stdio: 'inherit',
|
||||
cwd: dirname(ctx.request.file.path)
|
||||
})
|
||||
kindlegen.once('close', (code) => {
|
||||
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'))
|
||||
})
|
||||
if (code !== 0) {
|
||||
console.warn('kindlegen error code ' + code)
|
||||
}
|
||||
|
||||
resolve(outname)
|
||||
})
|
||||
})
|
||||
|
||||
} else if (mimetype === TYPE_EPUB && info.agent.includes('Kobo') && ctx.request.body.kepubify) {
|
||||
// convert to Kobo EPUB
|
||||
conversion = 'kepubify'
|
||||
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) => {
|
||||
const kepubify = spawn('kepubify', ['-v', '-u', '-o', basename(outname), basename(ctx.request.file.path)], {
|
||||
stdio: 'inherit',
|
||||
cwd: dirname(ctx.request.file.path)
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
resolve(outname)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// No conversion
|
||||
data = ctx.request.file.path
|
||||
}
|
||||
|
||||
expireKey(key)
|
||||
if (info.file && info.file.path) {
|
||||
await new Promise((resolve, reject) => fs.unlink(info.file.path, (err) => {
|
||||
if (err) return reject(err)
|
||||
else console.log('Removed previously uploaded file', info.file.path)
|
||||
resolve()
|
||||
}))
|
||||
}
|
||||
info.file = {
|
||||
name: filename,
|
||||
path: data,
|
||||
// size: ctx.request.file.size,
|
||||
uploaded: new Date()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const mimetype = ctx.request.file.mimetype
|
||||
let messages = []
|
||||
if (ctx.request.file) {
|
||||
messages.push('Upload successful! ' + (conversion ? ' Ebook was converted with ' + conversion + ' and sent' : ' Sent')+' to '+(info.agent.includes('Kobo') ? 'a Kobo device.' : (info.agent.includes('Kindle') ? 'a Kindle device.' : 'a device.')))
|
||||
messages.push('Filename: ' + filename)
|
||||
}
|
||||
if (url) {
|
||||
messages.push("Added url: " + url)
|
||||
}
|
||||
|
||||
const type = await FileType.fromFile(ctx.request.file.path)
|
||||
|
||||
if ((!type || !allowedTypes.includes(type.mime)) && !allowedTypes.includes(mimetype)) {
|
||||
if (messages.length === 0) {
|
||||
flash(ctx, {
|
||||
message: 'Uploaded file is of an invalid type: ' + ctx.request.file.originalname + ' (' + (type? type.mime : 'unknown mimetype') + ')',
|
||||
message: 'No file or url selected',
|
||||
success: false,
|
||||
key: key
|
||||
})
|
||||
ctx.redirect('back', '/')
|
||||
fs.unlink(ctx.request.file.path, (err) => {
|
||||
if (err) console.error(err)
|
||||
else console.log('Removed file', ctx.request.file.path)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const info = ctx.keys.get(key)
|
||||
expireKey(key)
|
||||
|
||||
let data = null
|
||||
let filename = ctx.request.file.originalname
|
||||
let conversion = null
|
||||
|
||||
if (mimetype === TYPE_EPUB && info.agent.includes('Kindle')) {
|
||||
// convert to .mobi
|
||||
conversion = 'kindlegen'
|
||||
const outname = ctx.request.file.path.replace(/\.epub$/i, '.mobi')
|
||||
filename = filename.replace(/\.kepub\.epub$/i, '.epub').replace(/\.epub$/i, '.mobi')
|
||||
|
||||
data = await new Promise((resolve, reject) => {
|
||||
const kindlegen = spawn('kindlegen', [basename(ctx.request.file.path), '-dont_append_source', '-c1', '-o', basename(outname)], {
|
||||
stdio: 'inherit',
|
||||
cwd: dirname(ctx.request.file.path)
|
||||
})
|
||||
kindlegen.once('close', (code) => {
|
||||
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'))
|
||||
})
|
||||
if (code !== 0) {
|
||||
console.warn('kindlegen error code ' + code)
|
||||
}
|
||||
|
||||
resolve(outname)
|
||||
})
|
||||
})
|
||||
|
||||
} else if (mimetype === TYPE_EPUB && info.agent.includes('Kobo') && ctx.request.body.kepubify) {
|
||||
// convert to Kobo EPUB
|
||||
conversion = 'kepubify'
|
||||
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) => {
|
||||
const kepubify = spawn('kepubify', ['-v', '-u', '-o', basename(outname), basename(ctx.request.file.path)], {
|
||||
stdio: 'inherit',
|
||||
cwd: dirname(ctx.request.file.path)
|
||||
})
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
resolve(outname)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// No conversion
|
||||
data = ctx.request.file.path
|
||||
}
|
||||
|
||||
expireKey(key)
|
||||
if (info.file && info.file.path) {
|
||||
await new Promise((resolve, reject) => fs.unlink(info.file.path, (err) => {
|
||||
if (err) return reject(err)
|
||||
else console.log('Removed previously uploaded file', info.file.path)
|
||||
resolve()
|
||||
}))
|
||||
}
|
||||
info.file = {
|
||||
name: filename,
|
||||
path: data,
|
||||
// size: ctx.request.file.size,
|
||||
uploaded: new Date()
|
||||
}
|
||||
|
||||
flash(ctx, {
|
||||
message: 'Upload successful!<br/>'+(conversion ? ' Ebook was converted with ' + conversion + ' and sent' : ' Sent')+' to '+(info.agent.includes('Kobo') ? 'a Kobo device.' : (info.agent.includes('Kindle') ? 'a Kindle device.' : 'a device.'))+'<br/>Filename: ' + filename,
|
||||
message: messages.join("<br/>"),
|
||||
success: true,
|
||||
key: key
|
||||
key: key,
|
||||
url: url
|
||||
})
|
||||
ctx.redirect('back', '/')
|
||||
})
|
||||
@@ -349,28 +382,30 @@ router.get('/status/:key', async ctx => {
|
||||
file: info.file ? {
|
||||
name: info.file.name,
|
||||
// size: info.file.size
|
||||
} : null
|
||||
} : null,
|
||||
urls: info.urls
|
||||
}
|
||||
})
|
||||
|
||||
router.get('/style.css', async ctx => {
|
||||
await sendfile(ctx, 'style.css')
|
||||
})
|
||||
|
||||
router.get('/receive', async ctx => {
|
||||
await sendfile(ctx, 'download.html')
|
||||
await sendfile(ctx, 'static/download.html')
|
||||
})
|
||||
|
||||
router.get('/', async ctx => {
|
||||
const agent = ctx.get('user-agent')
|
||||
console.log(ctx.ip, agent)
|
||||
await sendfile(ctx, agent.includes('Kobo') || agent.includes('Kindle')? 'download.html' : 'upload.html')
|
||||
await sendfile(ctx, agent.includes('Kobo') || agent.includes('Kindle')? 'static/download.html' : 'static/upload.html')
|
||||
})
|
||||
|
||||
|
||||
app.use(router.routes())
|
||||
app.use(router.allowedMethods())
|
||||
|
||||
app.use(serve("static"))
|
||||
|
||||
app.use(mount("/node_modules/crypto-js", serve("node_modules/crypto-js")))
|
||||
|
||||
|
||||
fs.rm('uploads', {recursive: true}, (err) => {
|
||||
if (err) throw err
|
||||
mkdirp('uploads').then (() => {
|
||||
|
||||
Reference in New Issue
Block a user