From 7f7e1d1f3f9adddb5be805780ae2e9dd49fb0eba Mon Sep 17 00:00:00 2001 From: Salihu Date: Sun, 27 Sep 2026 23:12:15 +0100 Subject: [PATCH] replace with correct attachments --- .../services/import-attachment.service.ts | 99 ++++++++++++++----- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/apps/server/src/integrations/import/services/import-attachment.service.ts b/apps/server/src/integrations/import/services/import-attachment.service.ts index a1ecde74a..436bdb4b0 100644 --- a/apps/server/src/integrations/import/services/import-attachment.service.ts +++ b/apps/server/src/integrations/import/services/import-attachment.service.ts @@ -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, + result: { + attachmentId: string; + apiFilePath: string; + fileName: string; + size: number; + }, + ) => { + const name = + source.attr('title') || + result.fileName; + + const $pdf = $('
') + .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, + result: { + attachmentId: string; + apiFilePath: string; + fileName: string; + mimeType: string; + size: number; + }, + ) => { + const name = + source.attr('title') || + result.fileName; + + return $('
') + .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 = $('