|
|
@@ -350,15 +350,20 @@ export class VideoMediaService {
|
|
|
|
|
|
async importExcelTags(file: MultipartFile) {
|
|
|
const buffer = await this.readUploadBuffer(file);
|
|
|
+ return this.importExcelTagsFromBuffer(buffer, (file as any)?.filename);
|
|
|
+ }
|
|
|
+
|
|
|
+ async importExcelTagsFromBuffer(buffer: Buffer, filename?: string) {
|
|
|
if (!buffer.length) {
|
|
|
throw new BadRequestException('Empty file');
|
|
|
}
|
|
|
this.logger.log(
|
|
|
- `[importExcelTags] upload buffer bytes=${buffer.length} filename=${(file as any)?.filename ?? 'unknown'} mimetype=${(file as any)?.mimetype ?? 'unknown'}`,
|
|
|
+ `[importExcelTags] upload buffer bytes=${buffer.length} filename=${filename ?? 'unknown'}`,
|
|
|
);
|
|
|
|
|
|
const rowsAH: Array<{ idRaw: unknown; tagsRaw: unknown }> = [];
|
|
|
- const filename = (file as any)?.filename ?? '';
|
|
|
+ const maxRows = 100000;
|
|
|
+ const maxCols = 20;
|
|
|
const looksLikeXlsx =
|
|
|
buffer.length >= 4 &&
|
|
|
buffer[0] === 0x50 &&
|
|
|
@@ -366,7 +371,7 @@ export class VideoMediaService {
|
|
|
buffer[2] === 0x03 &&
|
|
|
buffer[3] === 0x04;
|
|
|
|
|
|
- if (looksLikeXlsx || /\.xlsx$/i.test(filename)) {
|
|
|
+ if (looksLikeXlsx || /\.xlsx$/i.test(filename ?? '')) {
|
|
|
const workbook = XLSX.read(buffer, { type: 'buffer' });
|
|
|
const sheetName = workbook.SheetNames[0];
|
|
|
const sheet = sheetName ? workbook.Sheets[sheetName] : undefined;
|
|
|
@@ -377,6 +382,8 @@ export class VideoMediaService {
|
|
|
|
|
|
const rangeRef = sheet['!ref'] ?? 'A1:A1';
|
|
|
const range = XLSX.utils.decode_range(rangeRef);
|
|
|
+ range.e.r = Math.min(range.e.r, range.s.r + maxRows - 1);
|
|
|
+ range.e.c = Math.min(range.e.c, range.s.c + maxCols - 1);
|
|
|
|
|
|
for (let r = range.s.r; r <= range.e.r; r += 1) {
|
|
|
const idCell = sheet[XLSX.utils.encode_cell({ r, c: 0 })];
|
|
|
@@ -415,10 +422,14 @@ export class VideoMediaService {
|
|
|
return cells;
|
|
|
};
|
|
|
|
|
|
- for (let i = 1; i < lines.length; i += 1) {
|
|
|
+ const maxLineIndex = Math.min(lines.length - 1, maxRows);
|
|
|
+ for (let i = 1; i <= maxLineIndex; i += 1) {
|
|
|
const line = lines[i];
|
|
|
if (!line) continue;
|
|
|
const cells = parseCsvLine(line);
|
|
|
+ if (cells.length > maxCols) {
|
|
|
+ cells.length = maxCols;
|
|
|
+ }
|
|
|
rowsAH.push({
|
|
|
idRaw: cells[0] ?? '',
|
|
|
tagsRaw: cells[7] ?? '',
|