2
0
mirror of https://github.com/frappe/books.git synced 2024-12-26 12:28:12 +00:00

-Use puppeteer core for smaller app size

This commit is contained in:
thefalconx33 2019-08-14 15:09:55 +05:30
parent 4cbb99ed2d
commit d352e39082
6 changed files with 107 additions and 69 deletions

View File

@ -51,9 +51,9 @@
"octicons": "^7.2.0", "octicons": "^7.2.0",
"passport": "^0.4.0", "passport": "^0.4.0",
"passport-jwt": "^4.0.0", "passport-jwt": "^4.0.0",
"puppeteer": "^1.2.0", "puppeteer-core": "^1.19.0",
"sass-loader": "^7.0.3", "sass-loader": "^7.0.3",
"sharp": "^0.22.1", "sharp": "^0.23.0",
"showdown": "^1.8.6", "showdown": "^1.8.6",
"socket.io": "^2.0.4", "socket.io": "^2.0.4",
"sqlite3": "^4.0.9", "sqlite3": "^4.0.9",

View File

@ -1,5 +1,5 @@
const frappe = require('frappejs'); const frappe = require('frappejs');
const puppeteer = require('puppeteer'); const puppeteer = require('puppeteer-core');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { getTmpDir } = require('frappejs/server/utils'); const { getTmpDir } = require('frappejs/server/utils');
@ -7,87 +7,97 @@ const { getHTML } = require('frappejs/common/print');
const { getRandomString } = require('frappejs/utils'); const { getRandomString } = require('frappejs/utils');
async function makePDF(html, filepath) { async function makePDF(html, filepath) {
const browser = await puppeteer.launch(); const browser = await puppeteer.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent(html); await page.setContent(html);
await page.addStyleTag({ await page.addStyleTag({
url: 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css' url:
}) 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css'
await page.pdf({ });
path: filepath, await page.pdf({
format: 'A4' path: filepath,
}); format: 'A4'
await browser.close(); });
await browser.close();
} }
async function getPDFForElectron(doctype, name, destination, htmlContent) { async function getPDFForElectron(doctype, name, destination, htmlContent) {
const { remote, shell } = require('electron'); const { remote, shell } = require('electron');
const { BrowserWindow } = remote; const { BrowserWindow } = remote;
const html = htmlContent || await getHTML(doctype, name); const html = htmlContent || (await getHTML(doctype, name));
const filepath = path.join(destination, name + '.pdf'); const filepath = path.join(destination, name + '.pdf');
const fs = require('fs') const fs = require('fs');
let printWindow = new BrowserWindow({ let printWindow = new BrowserWindow({
width: 600, width: 600,
height: 800, height: 800,
show: false show: false
}) });
printWindow.loadURL(`file://${path.join(__static, 'print.html')}`); printWindow.loadURL(`file://${path.join(__static, 'print.html')}`);
printWindow.on('closed', () => { printWindow.on('closed', () => {
printWindow = null; printWindow = null;
}); });
const code = ` const code = `
document.body.innerHTML = \`${html}\`; document.body.innerHTML = \`${html}\`;
`; `;
printWindow.webContents.executeJavaScript(code); printWindow.webContents.executeJavaScript(code);
const printPromise = new Promise(resolve => { const printPromise = new Promise(resolve => {
printWindow.webContents.on('did-finish-load', () => { printWindow.webContents.on('did-finish-load', () => {
printWindow.webContents.printToPDF({ printWindow.webContents.printToPDF(
{
marginsType: 1, // no margin marginsType: 1, // no margin
pageSize: 'A4', pageSize: 'A4',
printBackground: true printBackground: true
}, (error, data) => { },
if (error) throw error (error, data) => {
if (error) throw error;
printWindow.close(); printWindow.close();
fs.writeFile(filepath, data, (error) => { fs.writeFile(filepath, data, error => {
if (error) throw error if (error) throw error;
resolve(shell.openItem(filepath)); resolve(shell.openItem(filepath));
}) });
}) }
}) );
}) });
});
await printPromise; await printPromise;
// await makePDF(html, filepath); // await makePDF(html, filepath);
} }
function setupExpressRoute() { function setupExpressRoute() {
if (!frappe.app) return; if (!frappe.app) return;
frappe.app.post('/api/method/pdf', frappe.asyncHandler(handlePDFRequest)); frappe.app.post('/api/method/pdf', frappe.asyncHandler(handlePDFRequest));
} }
async function handlePDFRequest(req, res) { async function handlePDFRequest(req, res) {
const args = req.body; const args = req.body;
const { doctype, name } = args; const { doctype, name } = args;
const html = await getHTML(doctype, name); const html = await getHTML(doctype, name);
const filepath = path.join(getTmpDir(), `frappe-pdf-${getRandomString()}.pdf`); const filepath = path.join(
await makePDF(html, filepath); getTmpDir(),
`frappe-pdf-${getRandomString()}.pdf`
);
await makePDF(html, filepath);
const file = fs.createReadStream(filepath); const file = fs.createReadStream(filepath);
const stat = fs.statSync(filepath); const stat = fs.statSync(filepath);
res.setHeader('Content-Length', stat.size); res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', `attachment; filename=${path.basename(filepath)}`); res.setHeader(
file.pipe(res); 'Content-Disposition',
`attachment; filename=${path.basename(filepath)}`
);
file.pipe(res);
} }
module.exports = { module.exports = {
makePDF, makePDF,
setupExpressRoute, setupExpressRoute,
getPDFForElectron getPDFForElectron
} };

View File

@ -73,7 +73,7 @@ export default {
this.doc.set('name', ''); this.doc.set('name', '');
} }
if (this.defaults) { if (this.doc.isNew() && this.defaults) {
for (let fieldname in this.defaults) { for (let fieldname in this.defaults) {
const value = this.defaults[fieldname]; const value = this.defaults[fieldname];
await this.doc.set(fieldname, value); await this.doc.set(fieldname, value);
@ -123,13 +123,23 @@ export default {
}, },
async submit() { async submit() {
this.doc.set('submitted', 1); await this.doc.set('submitted', 1);
await this.save(); try {
await this.save();
} catch (e) {
await this.doc.set('submitted', 0);
await this.doc.set('_dirty', false);
}
}, },
async revert() { async revert() {
this.doc.set('submitted', 0); await this.doc.set('submitted', 0);
await this.save(); try {
await this.save();
} catch (e) {
await this.doc.set('submitted', 1);
await this.doc.set('_dirty', false);
}
}, },
print() { print() {

View File

@ -75,6 +75,19 @@ export default {
: true; : true;
this.disableSave = this.doc.isNew() ? false : !this.isDirty; this.disableSave = this.doc.isNew() ? false : !this.isDirty;
},
getFormTitle() {
const _ = this._;
try {
return _(
this.meta.getFormTitle(this.doc) ||
this.meta.label ||
this.doc.doctype
);
} catch (e) {
return _(this.meta.label || this.doc.doctype);
}
} }
}, },
computed: { computed: {
@ -85,7 +98,7 @@ export default {
const _ = this._; const _ = this._;
if (this.doc.isNew()) { if (this.doc.isNew()) {
return _('New {0}', _(this.meta.label || this.doc.doctype)); return _('New {0}', this.getFormTitle());
} }
const titleField = this.meta.titleField || 'name'; const titleField = this.meta.titleField || 'name';

View File

@ -14,7 +14,7 @@
:docfield="getDocField(fieldname)" :docfield="getDocField(fieldname)"
:value="$data[fieldname]" :value="$data[fieldname]"
:doc="doc" :doc="doc"
:autofocus="doc.isNew() && (i === currentSection || i === 0) && j === 0 && k === 0" :autofocus="doc.isNew() && (i === currentSection || i === 0) && j === 0 && k === 0 && !$data[fieldname]"
@change="value => updateDoc(fieldname, value)" @change="value => updateDoc(fieldname, value)"
/> />
</div> </div>

View File

@ -1,6 +1,11 @@
<script> <script>
import Float from './Float'; import Float from './Float';
export default { export default {
extends: Float extends: Float,
} methods: {
parse(value) {
return frappe.format(value, 'Currency');
}
}
};
</script> </script>