云功能:从云存储压缩多个文档



我已经搜索了很多关于堆栈溢出的问题,但找不到一个合适的答案,我可以从中得出我需要的答案:

我想用云功能从谷歌云存储/Firebase存储中的一个文件夹中压缩多个文件。

我已经找到了从本地文件系统压缩文档的解决方案,但无法在云云存储功能中推导出如何做到这一点。

谷歌云存储支持解压缩形式的转码,但不支持压缩形式的转码。但是,在云存储中,任何用户都可以存储gzip压缩文件。

要使用云功能从云存储压缩多个文档,您可以使用gcs.bucket.file(filePath(将文件从云存储下载到功能实例。下载、压缩文件,然后将文件重新上传到云存储。在这里,您可以找到下载、转换和上传文件的示例。您可以在这个StackOverflow线程中找到一个压缩多个文件的示例。本文档介绍了如何使用Console、Gsutil、Code Sample或RESTAPI将对象上载到云存储。

有点晚了,但我也有同样的问题需要解决。

以下Firebase功能:

  1. 在1 GB/120秒超时的情况下运行(出于良好的衡量标准(
  2. 由WRITE调用触发(仅当您的调用很少时才执行此操作!(
  3. 忽略除background_thumbnail/之外的所有路径
  4. 创建一个随机工作目录,然后将其删除
  5. 从Firebase Storage下载图像
  6. 对文件夹中的这些图像进行Zips:background_thumbnail/<IMAGE>
  7. 将创建的ZIP上载到Firebase存储
  8. 在Firebase Storage中为ZIP文件创建签名的URL
  9. 将签名的URL存储在Firestore中

代码可能会得到改进,变得更优雅,但它(目前(有效。


const {v4: uuidv4} = require("uuid"); // for random working dir
const JSZip = require("jszip");
exports.generateThumbnailZip = functions
.runWith({memory: "1GB", timeoutSeconds: 120})
.region("europe-west3")
.storage.object()
.onFinalize(async (object) => {
// background_thumbnail/ is the watched folder
if (!object.name.startsWith("background_thumbnail/")) {
return functions.logger.log(`Aborting, got: ${object.name}.`);
}
const jszip = new JSZip();
const bucket = admin.storage().bucket();
const fileDir = path.dirname(object.name);
const workingDir = path.join(os.tmpdir(), uuidv4()); 
const localZipPath = path.join(workingDir, `${fileDir}.zip`);
const remoteZipPath = `${fileDir}.zip`;
await mkdirp(workingDir);
// -------------------------------------------------------------------
// DOWNLOAD and ZIP
// -------------------------------------------------------------------
const [files] = await bucket.getFiles({prefix: `${fileDir}/`});
for (let index = 0; index < files.length; index++) {
const file = files[index];
const name = path.basename(file.name);
const tempFileName = path.join(workingDir, name);
functions.logger.log("Downloading tmp file", tempFileName);
await file.download({destination: tempFileName});
jszip.folder(fileDir).file(name, fs.readFileSync(tempFileName));
}
const content = await jszip.generateAsync({
type: "nodebuffer",
compression: "DEFLATE",
compressionOptions: { level: 9 }
});
functions.logger.log("Saving zip file", localZipPath);
fs.writeFileSync(localZipPath, content);
// -------------------------------------------------------------------
// UPLOAD ZIP
// -------------------------------------------------------------------
functions.logger.log("Uploading zip to storage at", remoteZipPath);
const uploadResponse = await bucket
.upload(path.resolve(localZipPath), {destination: remoteZipPath});
// -------------------------------------------------------------------
// GET SIGNED URL FOR ZIP AND STORE IT IN DB
// -------------------------------------------------------------------
functions.logger.log("Getting signed URLs.");
const signedResult = await uploadResponse[0].getSignedUrl({
action: "read",
expires: "03-01-2500",
});
const signedUrl = signedResult[0];
functions.logger.log("Storing signed URL in db", signedUrl);
// Stores the signed URL under "zips/<WATCHED DIR>.signedUrl"
await db.collection("zips").doc(fileDir).set({
signedUrl: signedUrl,
}, {merge: true});
// -------------------------------------------------------------------
// CLEAN UP
// -------------------------------------------------------------------
functions.logger.log("Unlinking working dir", workingDir);
fs.rmSync(workingDir, {recursive: true, force: true});
functions.logger.log("DONE");
return null;
});

最新更新