要求に応じてPDFファイルを操作するFirebase機能を作成しました。いくつかの操作を行い、ストレージに保存してデータベースにハッシュをアーカイブします。Firebase機能で、同期/非同期Messをきれいにします。ES6
私はそれをうまく動作させることができましたが、ES6以前のコールバックで作業する方法を実際には学んだことはありません。私はこのすべてに慣れていないし、矢印の機能と約束を働くことを学んだ。しかし、ここで私は純粋なjavascriptとその作業を何とかしているパッケージを使用する必要がありますが、本当にこの同期/非同期の混乱をきれいに処理して、関数を処理した後にfirebaseへの約束を返す必要があります。
私の関数には、pdfライブラリ用に別のファイルを用意するための奇妙なファイルハンドリングも含まれています: たとえば、QMPコードを作成してtmpファイルに保存し、別のライブラリを使用してpngのjpgを作成しますtmpに再度保存します。私は何かよりスマートなことをすることができれば、何か示唆やヒントに触れることができます。
機能がまだ実行中に数ミリ秒で完了しているため、チェーンに何か問題があります。
私は自分のコードにいくつかのコメントを追加しましたが、私はES6に変更する手がかりがなく、この大きな混乱を取り除く手助けができれば非常に感謝しています。
const hummus = require('hummus');
const request = require('request');
const fs = require('fs');
const sha1 = require('sha1');
const images = require("images");
exports.handleDocSignRequests = functions.database.ref('/user_writeable/docrequests/{uid}').onWrite(event => {
var userReq = event.data.val();
var userRef = event.data.ref;
if (!userReq) return Promise.resolve();
if (!userReq.docpath) return Promise.resolve();
let uid = event.params.uid;
let filename = userReq.docpath; // File to sign and hash
return bucket.file(filename).getSignedUrl({ // getting downloadurl from Firebase Storage
action: 'read'
}).then(
(downloadpath) => {
downloadpath = downloadpath[0];
//download pdf - how to turn this into a promise?
download = function (uri, filename, callback) {
request.head(uri, function (err, res, body) {
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
let pdfsourse = LOCAL_TMP_FOLDER + 'downloadedfile.pdf';
return download(downloadpath, pdfsourse, function() { // download callback turn this into ES6
console.log('download finished');
let qrjpg = LOCAL_TMP_FOLDER + 'qrcode.jpg';
var qrpng = LOCAL_TMP_FOLDER + 'qrcode.png';
let qrurl = 'https://some.url/' + userReq.docid;
let pdfdest = LOCAL_TMP_FOLDER + 'newpdf.pdf';
let logfile = './hummus.log';
QRCode.toFile(qrpng, qrurl, { // how to make this a part of the "chain" and go on when finished
version: 4, type: "png", scale: 2, margin: 0
}, function (err) {
if (err) throw err;
console.log('qr png ready');
images(qrpng).save(qrjpg, {operation: 100}); // save png as jpg
console.log('qr jpg ready');
});
// Doing stuff to PDF with HummusJs
let pdfWriter = hummus.createWriterToModify(pdfsourse, {
modifiedFilePath: pdfdest,
log: logfile,
userPassword: 'user',
ownerPassword: 'owner',
userProtectionFlag: 4
});
let pdfReader = pdfWriter.getModifiedFileParser();
let arialFont = pdfWriter.getFontForFile(ariallocal);
let textOptions = {font: arialFont, size: 5, colorspace: 'gray', color: 0x00};
for (let i = 0; i < pdfReader.getPagesCount(); ++i) {
let pageBox = pdfReader.parsePage(i).getMediaBox();
let pageModifier = new hummus.PDFPageModifier(pdfWriter, i, true);
let ctx = pageModifier.startContext().getContext();
ctx.writeText('Document saved', 5, 110, textOptions);
ctx.drawImage(5, 52, qrfile,
{
transformation: {
width: 40,
height: 40,
fit: 'always'
}
});
pageModifier.endContext().writePage();
}
pdfWriter.end();
// How can I be sure PDF is done and written to tmp file? Or is this given by sync function?
// Reading finished PDF from file again, to get base64 for hashing - is there a better way?
let newpdf = fs.readFileSync(pdfdest);
let base64pdf = newpdf.toString('base64');
let hash = sha1(base64pdf);
let signobj = {};
signobj['hash'] = hash;
// Check if document already in database, if not write hash to database,
// upload finished pdf to original place and archive
// and return remove request
let sign_ref = docsign_ref.child(userReq.docid);
return sign_ref.once('value').then(function (snap) {
if (!snap.val()) { //Document is new
let upload1 = bucket.upload(destcry, {destination: filename}).then
(suc => {
console.log('uploaded');
});
//
let upload2 = bucket.upload(destcry, {destination: 'signed/' + userReq.docid + '.pdf'}).then
(suc => {
console.log('uploaded');
});
return Promise.all([upload1, upload2]).then(// When both uploads are finished go on
(suc) => {
return sign_ref.set(signobj).then(
(suc) => {
// Remove Request and return Promise
return userRef.remove();
});
});
}
else {
//Document already in database, this should never happen, only for seq reasons
console.log('doc already in database);
return Promise.resolve();
}
});
});
});
});
は、私の機能が働いている、判明います時々起こった。それでもこの機能は永遠に続く。私のローカルノードでは、envは約3秒間実行され、クラウド機能では約2分かかります。 – jbb
ここではあまりにも多くの質問があります:(1)パフォーマンスを改善する方法? (2)PDFをtmpファイルに書き込んで書き込む方法を教えてください。 (3)「同期/非同期の混乱を取り除く」方法(4)よりスマートなファイル処理方法1つの質問に集中し、もっと質問があれば新しい質問を投稿してください。あなたが今質問を持っている方法はあまりにも広すぎます。 – trincot