This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
outline/server/utils/zip.js

80 lines
2.1 KiB
JavaScript

// @flow
import fs from "fs";
import JSZip from "jszip";
import tmp from "tmp";
import * as Sentry from "@sentry/node";
import { Attachment, Collection, Document } from "../models";
import { getImageByKey } from "./s3";
async function addToArchive(zip, documents) {
for (const doc of documents) {
const document = await Document.findByPk(doc.id);
let text = document.toMarkdown();
const attachments = await Attachment.findAll({
where: { documentId: document.id },
});
for (const attachment of attachments) {
await addImageToArchive(zip, attachment.key);
text = text.replace(attachment.redirectUrl, encodeURI(attachment.key));
}
zip.file(`${document.title || "Untitled"}.md`, text);
if (doc.children && doc.children.length) {
const folder = zip.folder(document.title);
await addToArchive(folder, doc.children);
}
}
}
async function addImageToArchive(zip, key) {
try {
const img = await getImageByKey(key);
zip.file(key, img, { createFolders: true });
} catch (err) {
if (process.env.SENTRY_DSN) {
Sentry.captureException(err);
}
// error during file retrieval
console.error(err);
}
}
async function archiveToPath(zip) {
return new Promise((resolve, reject) => {
tmp.file({ prefix: "export-", postfix: ".zip" }, (err, path) => {
if (err) return reject(err);
zip
.generateNodeStream({ type: "nodebuffer", streamFiles: true })
.pipe(fs.createWriteStream(path))
.on("finish", () => resolve(path))
.on("error", reject);
});
});
}
export async function archiveCollection(collection: Collection) {
const zip = new JSZip();
if (collection.documentStructure) {
await addToArchive(zip, collection.documentStructure);
}
return archiveToPath(zip);
}
export async function archiveCollections(collections: Collection[]) {
const zip = new JSZip();
for (const collection of collections) {
if (collection.documentStructure) {
const folder = zip.folder(collection.name);
await addToArchive(folder, collection.documentStructure);
}
}
return archiveToPath(zip);
}