Export a zipped file of the translations on a project

This commit is contained in:
kngako
2023-01-19 00:40:13 +02:00
parent 83c282bc73
commit eebf9266a9
6 changed files with 813 additions and 104 deletions

View File

@@ -1,6 +1,11 @@
const express = require('express')
const XL = require('excel4node');
const XLSX = require("xlsx");
const markdownProducer = require("../../../lib/markdown-producer")
const fs = require("fs")
const archiver = require('archiver');
const path = require("path")
const os = require("os")
module.exports = function (options) {
const db = options.db;
@@ -1181,7 +1186,7 @@ module.exports = function (options) {
{
association: db.TranslationChapter.Chapter,
},
request.query.sheets ? {
request.query.sheets || request.query.markdown ? {
association: db.TranslationChapter.TranslationChunks,
include: [
{
@@ -1366,6 +1371,98 @@ module.exports = function (options) {
} else {
response.redirect(`/projects/${request.params.id}`)
}
} else if (request.query.markdown) {
// Create temporary directory for export...
const directoryNamePrefix = `${project.name}-`
const tempExportDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), directoryNamePrefix)
)
console.log("Saving to: ", tempExportDirectory)
translationChapters.forEach((translationChapter, index) => {
// Save to files to temp directory...
const translationChapterTextContent = markdownProducer.produceMarkdownString(translationChapter)
// TODO: Create artifact sub directory...
// Create lang sub directory...
const dialectDirectoryPath = path.join(
tempExportDirectory,
translationChapter.translationArtifactVersion.dialect.name
)
if (!fs.existsSync(dialectDirectoryPath)) {
fs.mkdirSync(
dialectDirectoryPath
)
}
fs.writeFileSync(
path.join(dialectDirectoryPath, `${translationChapter.chapter.name}${translationChapter.chapter.name.endsWith(".md") ? "" : ".md"}`),
translationChapterTextContent
)
});
// Zip tempExportDirectory and download the zipped file...
const tempZipDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), directoryNamePrefix)
)
const zippedFilePath = path.join(tempZipDirectory, `${project.name}.zip`)
const zippedFile = fs.createWriteStream(
zippedFilePath
);
const archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});
// listen for all archive data to be written
// 'close' event is fired only when a file descriptor is involved
zippedFile.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the zippedFile file descriptor has closed.');
response.set('Content-Disposition', `attachment; filename="${project.name}.zip"`);
response.sendFile(
zippedFilePath
)
});
// This event is fired when the data source is drained no matter what was the data source.
// It is not part of this library but rather from the NodeJS Stream API.
// @see: https://nodejs.org/api/stream.html#stream_event_end
zippedFile.on('end', function() {
console.log('Data has been drained');
});
// good practice to catch warnings (ie stat failures and other non-blocking errors)
archive.on('warning', function(err) {
console.log("Waring: ", err)
if (err.code === 'ENOENT') {
// log warning
} else {
// throw error
throw err;
}
});
// good practice to catch this error explicitly
archive.on('error', function(err) {
console.log("Error: ", err)
throw err;
});
// pipe archive data to the file
archive.pipe(zippedFile);
// append files from a sub-directory, putting its contents at the root of archive
archive.directory(tempExportDirectory, false);
// finalize the archive (ie we are done appending files but streams have to finish yet)
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
archive.finalize();
} else {
response.display("project-tracker", {
user: request.user,