2020-11-25 06:57:23 -05:00
|
|
|
const metrics = require('@overleaf/metrics')
|
2021-07-12 12:47:19 -04:00
|
|
|
const Settings = require('@overleaf/settings')
|
2019-12-19 05:41:41 -05:00
|
|
|
const { callbackify } = require('util')
|
2014-02-14 11:39:05 -05:00
|
|
|
|
2019-12-19 05:41:41 -05:00
|
|
|
const safeExec = require('./SafeExec').promises
|
|
|
|
const { ConversionError } = require('./Errors')
|
2014-02-19 08:02:53 -05:00
|
|
|
|
2019-12-19 05:41:41 -05:00
|
|
|
const APPROVED_FORMATS = ['png']
|
|
|
|
const FOURTY_SECONDS = 40 * 1000
|
|
|
|
const KILL_SIGNAL = 'SIGTERM'
|
2014-03-04 07:44:16 -05:00
|
|
|
|
2019-12-16 05:24:35 -05:00
|
|
|
module.exports = {
|
2019-12-19 05:41:41 -05:00
|
|
|
convert: callbackify(convert),
|
|
|
|
thumbnail: callbackify(thumbnail),
|
|
|
|
preview: callbackify(preview),
|
|
|
|
promises: {
|
|
|
|
convert,
|
|
|
|
thumbnail,
|
2021-07-13 07:04:46 -04:00
|
|
|
preview,
|
|
|
|
},
|
2019-12-19 05:41:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
async function convert(sourcePath, requestedFormat) {
|
|
|
|
const width = '600x'
|
2024-05-22 05:37:08 -04:00
|
|
|
return await _convert(sourcePath, requestedFormat, [
|
2019-12-19 05:41:41 -05:00
|
|
|
'convert',
|
|
|
|
'-define',
|
|
|
|
`pdf:fit-page=${width}`,
|
|
|
|
'-flatten',
|
|
|
|
'-density',
|
|
|
|
'300',
|
2021-07-13 07:04:46 -04:00
|
|
|
`${sourcePath}[0]`,
|
2019-12-19 05:41:41 -05:00
|
|
|
])
|
|
|
|
}
|
|
|
|
|
|
|
|
async function thumbnail(sourcePath) {
|
|
|
|
const width = '260x'
|
2024-05-22 05:37:08 -04:00
|
|
|
return await convert(sourcePath, 'png', [
|
2019-12-19 05:41:41 -05:00
|
|
|
'convert',
|
|
|
|
'-flatten',
|
|
|
|
'-background',
|
|
|
|
'white',
|
|
|
|
'-density',
|
|
|
|
'300',
|
|
|
|
'-define',
|
|
|
|
`pdf:fit-page=${width}`,
|
|
|
|
`${sourcePath}[0]`,
|
|
|
|
'-resize',
|
2021-07-13 07:04:46 -04:00
|
|
|
width,
|
2019-12-19 05:41:41 -05:00
|
|
|
])
|
|
|
|
}
|
2014-02-14 11:39:05 -05:00
|
|
|
|
2019-12-19 05:41:41 -05:00
|
|
|
async function preview(sourcePath) {
|
|
|
|
const width = '548x'
|
2024-05-22 05:37:08 -04:00
|
|
|
return await convert(sourcePath, 'png', [
|
2019-12-19 05:41:41 -05:00
|
|
|
'convert',
|
|
|
|
'-flatten',
|
|
|
|
'-background',
|
|
|
|
'white',
|
|
|
|
'-density',
|
|
|
|
'300',
|
|
|
|
'-define',
|
|
|
|
`pdf:fit-page=${width}`,
|
|
|
|
`${sourcePath}[0]`,
|
|
|
|
'-resize',
|
2021-07-13 07:04:46 -04:00
|
|
|
width,
|
2019-12-19 05:41:41 -05:00
|
|
|
])
|
|
|
|
}
|
|
|
|
|
|
|
|
async function _convert(sourcePath, requestedFormat, command) {
|
|
|
|
if (!APPROVED_FORMATS.includes(requestedFormat)) {
|
2020-04-30 08:20:40 -04:00
|
|
|
throw new ConversionError('invalid format requested', {
|
2021-07-13 07:04:46 -04:00
|
|
|
format: requestedFormat,
|
2019-12-16 05:42:31 -05:00
|
|
|
})
|
2019-12-19 05:41:41 -05:00
|
|
|
}
|
2014-02-14 11:39:05 -05:00
|
|
|
|
2019-12-19 05:41:41 -05:00
|
|
|
const timer = new metrics.Timer('imageConvert')
|
|
|
|
const destPath = `${sourcePath}.${requestedFormat}`
|
|
|
|
|
|
|
|
command.push(destPath)
|
|
|
|
command = Settings.commands.convertCommandPrefix.concat(command)
|
|
|
|
|
|
|
|
try {
|
|
|
|
await safeExec(command, {
|
|
|
|
killSignal: KILL_SIGNAL,
|
2021-07-13 07:04:46 -04:00
|
|
|
timeout: FOURTY_SECONDS,
|
2019-12-16 05:42:31 -05:00
|
|
|
})
|
2019-12-19 05:41:41 -05:00
|
|
|
} catch (err) {
|
2020-07-07 08:49:54 -04:00
|
|
|
throw new ConversionError(
|
|
|
|
'something went wrong converting file',
|
|
|
|
{ stderr: err.stderr, sourcePath, requestedFormat, destPath },
|
|
|
|
err
|
|
|
|
)
|
2019-12-16 05:42:31 -05:00
|
|
|
}
|
2019-12-19 05:41:41 -05:00
|
|
|
|
|
|
|
timer.done()
|
|
|
|
return destPath
|
2019-12-16 05:42:31 -05:00
|
|
|
}
|