소스 검색

phantom -> puppeteer

Alan Colon 7 년 전
부모
커밋
103ce62ba7
5개의 변경된 파일115개의 추가작업 그리고 46개의 파일을 삭제
  1. 83 0
      package-lock.json
  2. 1 3
      package.json
  3. 5 9
      public/edit.js
  4. 26 34
      server.js
  5. 0 0
      temp/dummy.txt

+ 83 - 0
package-lock.json

@@ -46,6 +46,14 @@
         "negotiator": "0.6.1"
       }
     },
+    "agent-base": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+      "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+      "requires": {
+        "es6-promisify": "5.0.0"
+      }
+    },
     "aglob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/aglob/-/aglob-3.0.1.tgz",
@@ -500,6 +508,14 @@
       "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
       "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
     },
+    "es6-promisify": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "requires": {
+        "es6-promise": "4.2.4"
+      }
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -797,6 +813,25 @@
         "sshpk": "1.14.2"
       }
     },
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+      "requires": {
+        "agent-base": "4.2.1",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
     "iconv-lite": {
       "version": "0.4.23",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
@@ -3901,6 +3936,11 @@
         "ipaddr.js": "1.8.0"
       }
     },
+    "proxy-from-env": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+      "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4="
+    },
     "psl": {
       "version": "1.1.29",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
@@ -3911,6 +3951,49 @@
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
       "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
     },
+    "puppeteer": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.7.0.tgz",
+      "integrity": "sha512-f+1DxKHPqce6CXUBz2eVO2WcATeVeQSOPG9GYaGObEZDCiCEUwG+gogjMsrvn7he2wHTqNVb5p6RUrwmr8XFBA==",
+      "requires": {
+        "debug": "3.1.0",
+        "extract-zip": "1.6.7",
+        "https-proxy-agent": "2.2.1",
+        "mime": "2.3.1",
+        "progress": "2.0.0",
+        "proxy-from-env": "1.0.0",
+        "rimraf": "2.6.2",
+        "ws": "5.2.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "mime": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+          "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg=="
+        },
+        "progress": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+          "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
+        },
+        "ws": {
+          "version": "5.2.2",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+          "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+          "requires": {
+            "async-limiter": "1.0.0"
+          }
+        }
+      }
+    },
     "qs": {
       "version": "6.5.1",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",

+ 1 - 3
package.json

@@ -15,10 +15,8 @@
     "cors": "^2.8.4",
     "data-urls": "^1.0.1",
     "express": "^4.16.3",
-    "html-pdf-chrome": "^0.5.0",
     "multer": "^1.3.1",
-    "phantom": "^6.0.3",
-    "phantom-html2pdf": "^4.0.1",
+    "puppeteer": "^1.7.0",
     "uuid": "^3.3.2"
   }
 }

+ 5 - 9
public/edit.js

@@ -50,15 +50,11 @@ document.addEventListener('DOMContentLoaded', () => {
         const body = `html=${encodeURIComponent(document.documentElement.outerHTML)}`
 
         req.onload = () => {
-            resolve(req.response)
-            //const reader = new FileReader()
-            // reader.readAsDataURL(req.response)
-            // reader.addEventListener('load', () => {
-            //     resolve(reader.result)
-            // })
-            // reader.addEventListener('error', (ev) => {
-            //     reject(ev.error)
-            // })
+            if (req.status > 299) {
+                reject(new Error(req.statusText))
+            } else {
+                resolve(req.response)
+            }
         }
 
         req.onerror = (ev) => {

+ 26 - 34
server.js

@@ -5,10 +5,13 @@ const multer = require('multer')
 const childProcess = require('child_process')
 const bodyParser = require('body-parser')
 const pdf2htmlexPath = `${__dirname}/node_modules/@alancnet/pdf2htmlex/bin-win/pdf2htmlEX.exe`
-const phantom = require('phantom')
+const puppeteer = require('puppeteer')
 const uuid = require('uuid')
 const parseDataUrl = require('data-urls')
 const cors = require('cors')
+const path = require('path')
+
+const chromePromise = puppeteer.launch()
 
 const upload = multer({
     dest: 'temp/'
@@ -42,17 +45,17 @@ app.post('/edit', upload.single('document'), async (req, res) => {
     */
     childProcess.exec(`"${pdf2htmlexPath}" --hdpi 200 --vdpi 200 --font-format ttf --no-drm 1 "${pdfFile}" "${htmlFile}"`, (err, stdout, stderr) => {
         if (err) {
-            res.status(500).send(`<pre>${err}\n\n${stdout}\n\n${stderr}</pre>`)
+            res.status(500).send(`<pre>${stderr}</pre>`)
         } else {
             fs.readFile('public/edit.html', (err, editHtml) => {
-                fs.readFile(htmlFile, 'utf8', (err, data) => {
+                fs.readFile(htmlFile, 'utf8', async (err, data) => {
                     if (err) {
-                        res.status(500).send(`<pre>${err}\n\n${stdout}\n\n${stderr}</pre>`)
+                        res.status(500).send(`<pre>${err}</pre>`)
                     } else {
                         res.status(200).send(data.replace('</body>', `${editHtml}</body>`))
                     }
-                    fs.unlink(pdfFile)
-                    fs.unlink(htmlFile)
+                    await asfs.unlinkAsync(htmlFile)
+                    await asfs.unlinkAsync(pdfFile)
                 })
             })
         }
@@ -62,42 +65,31 @@ app.post('/edit', upload.single('document'), async (req, res) => {
 
 
 app.post('/save', (req, res) => {
-    console.log(req.body.html)
-
     const tmpUuid = uuid()
-    const htmlPath = `temp/${tmpUuid}.html`
-    const pdfPath = `temp/${tmpUuid}.pdf`
+    const htmlFile = `temp/${tmpUuid}.html`
+    const htmlUrl = `file://${path.join(process.cwd(), htmlFile)}`
+    const pdfFile = `temp/${tmpUuid}.pdf`
 
     const pageWidth = /\.w0{width:([\d\.]*)pt/.exec(req.body.html)[1]
     const pageHeight = /\.h0{height:([\d\.]*)pt/.exec(req.body.html)[1]
 
 
-    fs.writeFile(htmlPath, req.body.html, 'utf8', async (err) => {
-        const instance = await phantom.create()
-
-        const page = await instance.createPage()
-        page.property('paperSize', {
-            width: pageWidth,
-            height: pageHeight,
-            margin: '0px'
+    fs.writeFile(htmlFile, req.body.html, 'utf8', async (err) => {
+        const chrome = await chromePromise
+        const page = await chrome.newPage()
+        await page.goto(htmlUrl)
+        await page.pdf({
+            path: pdfFile,
+            preferCSSPageSize: true
         })
-        page.open(htmlPath)
-        page.on('onLoadFinished', function(status) {
-            if (status === 'success') {
-                page.render(pdfPath, {format: 'pdf'})
-                setTimeout(() => {
-                    res.download(pdfPath, 'todo-preserve-filename.pdf', (err) => {
-                        if (err) {
-                            console.error(err)
-                            res.status(500).send(err)
-                        }
-                        //fs.unlink(htmlPath)
-                        //fs.unlink(pdfPath)
-                    })
-                }, 5000)
-            } else {
-                res.status(500).send('Failed: ' + status)
+        await page.close()
+        res.download(pdfFile, 'todo-preserve-filename.pdf', async (err) => {
+            if (err) {
+                console.error(err)
+                res.status(500).send(err)
             }
+            await asfs.unlinkAsync(htmlFile)
+            await asfs.unlinkAsync(pdfFile)
         })
     })
 })

+ 0 - 0
temp/dummy.txt