Skip to content

Instantly share code, notes, and snippets.

@pindlebot
Created September 3, 2018 14:46
Show Gist options
  • Select an option

  • Save pindlebot/3adad9252ddefafbb98f070c12d640c3 to your computer and use it in GitHub Desktop.

Select an option

Save pindlebot/3adad9252ddefafbb98f070c12d640c3 to your computer and use it in GitHub Desktop.
const got = require('got')
const Canvas = require('canvas')
const assert = require('assert')
const AWS = require('aws-sdk')
const PassThrough = require('stream').PassThrough
require('pdftk-lambda')
function NodeCanvasFactory () {}
global.HTMLElement = class {}
process.on('unhandledRejection', r => console.log(r))
function streamToBuffer (stream) {
return new Promise((resolve, reject) => {
let buffers = []
stream.on('error', reject)
stream.on('data', (data) => buffers.push(data))
stream.on('end', () => resolve(Buffer.concat(buffers)))
})
}
NodeCanvasFactory.prototype = {
create: function (width, height) {
assert(width > 0 && height > 0, 'Invalid canvas size')
var canvas = Canvas.createCanvas(width, height)
var context = canvas.getContext('2d')
return {
canvas: canvas,
context: context
}
},
reset: function (canvasAndContext, width, height) {
assert(canvasAndContext.canvas, 'Canvas is not specified')
assert(width > 0 && height > 0, 'Invalid canvas size')
canvasAndContext.canvas.width = width
canvasAndContext.canvas.height = height
},
destroy: function (canvasAndContext) {
assert(canvasAndContext.canvas, 'Canvas is not specified')
canvasAndContext.canvas.width = 0
canvasAndContext.canvas.height = 0
canvasAndContext.canvas = null
canvasAndContext.context = null
}
}
async function pdfScissors (stream) {
const scissors = require('scissors')
let passA = new PassThrough()
let passB = new PassThrough()
stream.pipe(passB)
stream.pipe(passB)
let propertyStream = scissors(passA).propertyStream()
let data = await streamToBuffer(propertyStream).catch(err => {
throw err
})
let jpgStream = scissors(passB).jpgStream(300)
let body = await streamToBuffer(jpgStream).catch(err => {
throw err
})
console.log({ data, body })
return { data, body }
}
async function upload (body, { key }) {
const s3 = new AWS.S3({
region: 'us-east-1'
})
await s3.putObject({
Body: body,
Key: key,
Bucket: ''
}).promise()
}
async function fallback (buffer) {
const data = {}
const PDFJS = require('pdfjs-dist/build/pdf')
data.version = PDFJS.version
PDFJS.disableWorker = true
let resolve
let reject
let promise = new Promise((res, rej) => {
resolve = res
reject = rej
})
let doc = await PDFJS.getDocument({
data: buffer,
disableFontFace: true,
nativeImageDecoderSupport: 'none',
stopAtErrors: false,
ignoreErrors: true,
pdfBug: true
}).catch(reject)
data.numpages = doc.numPages
let metaData = await doc.getMetadata().catch(() => null)
data.info = metaData ? metaData.info : null
data.metadata = metaData ? metaData.metadata : null
const page = await doc.getPage(1)
const scale = 1.0
const viewport = page.getViewport(scale)
const canvasFactory = new NodeCanvasFactory()
const canvasAndContext = canvasFactory.create(viewport.width, viewport.height);
const canvasContext = canvasAndContext.context
await page.render({ canvasContext, viewport, canvasFactory })
.catch(reject)
const body = canvasAndContext.canvas.toBuffer('image/jpg')
console.log({ body, data })
resolve({ body, data })
return promise
}
module.exports.handler = async (event, context, callback) => {
const { url, key } = JSON.parse(event.body)
let stream = got.stream(url)
// let { data, body } = await pdfScissors(stream)
// .catch(() => fallback(stream))
let passA = new PassThrough()
let passB = new PassThrough()
stream.pipe(passA)
stream.pipe(passB)
let buffer = await streamToBuffer(passA)
let result = await fallback(buffer).catch(() => pdfScissors(passB))
console.log(result)
await upload(result.body, { key })
callback(
null, {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(result.data)
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment