replace with correct attachments

This commit is contained in:
Salihu
2026-09-27 23:12:15 +01:00
parent a21a834306
commit 7f7e1d1f3f
@@ -15,7 +15,7 @@ import { AttachmentType } from '../../../core/attachment/attachment.constants';
import { unwrapFromParagraph } from '../utils/import-formatter';
import { resolveRelativeAttachmentPath } from '../utils/import.utils';
import { imageDimensionsFromData } from 'image-dimensions';
import { load } from 'cheerio';
import { Cheerio, load } from 'cheerio';
import pLimit from 'p-limit';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
@@ -99,27 +99,79 @@ export class ImportAttachmentService {
{
attachmentId: string;
apiFilePath: string;
fileName: string
fileName: string;
mimeType: string;
size: number;
} | null
>();
const createPdfElement = (
source: Cheerio<any>,
result: {
attachmentId: string;
apiFilePath: string;
fileName: string;
size: number;
},
) => {
const name =
source.attr('title') ||
result.fileName;
const $pdf = $('<div>')
.attr('data-type', 'pdf')
.attr('data-name', name)
.attr('src', result.apiFilePath)
.attr('data-attachment-id', result.attachmentId)
.attr('data-attachment-size', String(result.size))
.attr('width', source.attr('width') || '800')
.attr('height', source.attr('height') || '600');
return $pdf;
};
const createAttachmentElement = (
source: Cheerio<any>,
result: {
attachmentId: string;
apiFilePath: string;
fileName: string;
mimeType: string;
size: number;
},
) => {
const name =
source.attr('title') ||
result.fileName;
return $('<div>')
.attr('data-type', 'attachment')
.attr('data-attachment-url', result.apiFilePath)
.attr('data-attachment-name', name)
.attr('data-attachment-mime', result.mimeType)
.attr('data-attachment-size', String(result.size))
.attr('data-attachment-id', result.attachmentId);
};
const processDataUri = (uri?: string) => {
const normalized = uri?.trim();
if (!normalized || !normalized.toLowerCase().startsWith('data:')) {
return null;
}
if (processed.has(normalized)) {
return processed.get(normalized);
}
const parsed = this.parseDataUri(normalized);
if (!parsed) {
processed.set(normalized, null);
return null;
}
const { buffer, mimeType, fileExt } = parsed;
const { buffer, mimeType, fileExt, encoded } = parsed;
const cacheKey = `${mimeType}:${encoded}`;
if (processed.has(cacheKey)) {
return processed.get(cacheKey);
}
const attachmentId = v7();
const fileName = `${attachmentId}${fileExt}`;
const storageFilePath = `${getAttachmentFolderPath(
@@ -144,14 +196,14 @@ export class ImportAttachmentService {
}),
);
const result = { attachmentId, apiFilePath, fileName };
processed.set(normalized, result);
const result = { attachmentId, apiFilePath, fileName, mimeType, size: buffer.length };
processed.set(cacheKey, result);
return result;
};
// img/video/audio/source/iframe: src attribute
// img/video/audio/source: src attribute
for (const element of $(
'img[src], video[src], audio[src], source[src], iframe[src]',
'img[src], video[src], audio[src], source[src]',
).toArray()) {
const $element = $(element);
const result = processDataUri($element.attr('src'));
@@ -173,26 +225,19 @@ export class ImportAttachmentService {
.attr('data-attachment-id', result.attachmentId);
}
// the client represents embeds as iframes.
// so we convert embeds and objects as iframes
for (const element of $('object[data], embed[src]').toArray()) {
// object, embed, iframes
for (const element of $('object[data], embed[src], iframe[src]').toArray()) {
const $element = $(element);
const sourceAttribute = $element.is('object') ? 'data' : 'src';
const result = processDataUri($element.attr(sourceAttribute));
if (!result) continue;
const $iframe = $('<iframe>')
.attr('src', result.apiFilePath)
.attr('data-attachment-id', result.attachmentId);
for (const attribute of ['width', 'height', 'title']) {
const value = $element.attr(attribute);
if (value) {
$iframe.attr(attribute, value);
}
if (result.mimeType === 'application/pdf') {
$element.replaceWith(createPdfElement($element, result));
} else {
$element.replaceWith(createAttachmentElement($element, result));
}
$element.replaceWith($iframe);
}
// anchors
@@ -860,7 +905,7 @@ export class ImportAttachmentService {
*/
private parseDataUri(
uri: string,
): { buffer: Buffer; mimeType: string; fileExt: string } | null {
): { buffer: Buffer; mimeType: string; fileExt: string, encoded: string } | null {
const commaIndex = uri.indexOf(',');
if (commaIndex === -1) return null;
@@ -918,7 +963,7 @@ export class ImportAttachmentService {
return null;
}
return { buffer, mimeType, fileExt };
return { buffer, mimeType, fileExt, encoded };
}
private analyzeAttachments(