Browse Source

feat: encoding for export stream

nc-feat/export-csv-delimiters
mertmit 1 day ago
parent
commit
020c8bdbdc
  1. 13
      packages/nocodb/src/controllers/attachments.controller.ts
  2. 10
      packages/nocodb/src/models/PresignedUrl.ts
  3. 14
      packages/nocodb/src/modules/jobs/jobs/data-export/data-export.processor.ts

13
packages/nocodb/src/controllers/attachments.controller.ts

@ -168,6 +168,7 @@ export class AttachmentsController {
let queryResponseContentType = null;
let queryResponseContentDisposition = null;
let queryResponseContentEncoding = null;
if (queryHelper.length > 1) {
const query = new URLSearchParams(queryHelper[1]);
@ -175,6 +176,7 @@ export class AttachmentsController {
queryResponseContentDisposition = query.get(
'ResponseContentDisposition',
);
queryResponseContentEncoding = query.get('ResponseContentEncoding');
}
const targetParam = param.split('/')[2];
@ -191,12 +193,23 @@ export class AttachmentsController {
if (queryResponseContentType) {
res.setHeader('Content-Type', queryResponseContentType);
if (queryResponseContentEncoding) {
res.setHeader(
'Content-Type',
`${queryResponseContentType}; charset=${queryResponseContentEncoding}`,
);
}
}
if (queryResponseContentDisposition) {
res.setHeader('Content-Disposition', queryResponseContentDisposition);
}
if (queryResponseContentEncoding) {
res.setHeader('Content-Encoding', queryResponseContentEncoding);
}
res.sendFile(file.path);
} catch (e) {
res.status(404).send('Not found');

10
packages/nocodb/src/models/PresignedUrl.ts

@ -96,6 +96,7 @@ export default class PresignedUrl {
filename?: string;
preview?: boolean;
mimetype?: string;
encoding?: string;
},
ncMeta = Noco.ncMeta,
) {
@ -109,6 +110,7 @@ export default class PresignedUrl {
expireSeconds = DEFAULT_EXPIRE_SECONDS,
filename,
mimetype,
encoding,
} = param;
const preview = param.preview
@ -152,6 +154,14 @@ export default class PresignedUrl {
if (mimetype) {
pathParameters.ResponseContentType = mimetype;
if (encoding) {
pathParameters.ResponseContentType = `${mimetype}; charset=${encoding}`;
}
}
if (encoding) {
pathParameters.ResponseContentEncoding = encoding;
}
// append query params to the cache path

14
packages/nocodb/src/modules/jobs/jobs/data-export/data-export.processor.ts

@ -1,5 +1,6 @@
import { Readable } from 'stream';
import path from 'path';
import iconv from 'iconv-lite';
import { Injectable, Logger } from '@nestjs/common';
import moment from 'moment';
import type { Job } from 'bull';
@ -61,10 +62,19 @@ export class DataExportProcessor {
dataStream.setEncoding('utf8');
const encodedStream =
options?.encoding &&
options.encoding !== 'utf-8' &&
iconv.encodingExists(options.encoding)
? dataStream
.pipe(iconv.decodeStream('utf-8'))
.pipe(iconv.encodeStream(options?.encoding || 'utf-8'))
: dataStream;
let error = null;
const uploadFilePromise = (storageAdapter as any)
.fileCreateByStream(destPath, dataStream)
.fileCreateByStream(destPath, encodedStream)
.catch((e) => {
this.logger.error(e);
error = e;
@ -97,6 +107,7 @@ export class DataExportProcessor {
expireSeconds: 3 * 60 * 60, // 3 hours
preview: false,
mimetype: 'text/csv',
encoding: options?.encoding || 'utf-8',
});
} else {
url = await PresignedUrl.getSignedUrl({
@ -105,6 +116,7 @@ export class DataExportProcessor {
expireSeconds: 3 * 60 * 60, // 3 hours
preview: false,
mimetype: 'text/csv',
encoding: options?.encoding || 'utf-8',
});
}

Loading…
Cancel
Save