mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
feat: use confluence real file names
This commit is contained in:
@@ -190,13 +190,32 @@ export class ImportAttachmentService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build a map from resolved archive path → real filename from Confluence
|
||||||
|
// metadata. Confluence Server archives often store files under numeric IDs
|
||||||
|
// (e.g. "attachments/65601/65602") instead of the original filename.
|
||||||
|
const pageDir = path.dirname(pageRelativePath);
|
||||||
|
const attachmentNameByRelPath = new Map<string, string>();
|
||||||
|
for (const attachment of pageAttachments) {
|
||||||
|
const relPath = resolveRelativeAttachmentPath(
|
||||||
|
attachment.href,
|
||||||
|
pageDir,
|
||||||
|
attachmentCandidates,
|
||||||
|
);
|
||||||
|
if (relPath && attachment.fileName) {
|
||||||
|
attachmentNameByRelPath.set(relPath, attachment.fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const uploadOnce = (relPath: string) => {
|
const uploadOnce = (relPath: string) => {
|
||||||
const abs = attachmentCandidates.get(relPath)!;
|
const abs = attachmentCandidates.get(relPath)!;
|
||||||
const attachmentId = v7();
|
const attachmentId = v7();
|
||||||
const ext = path.extname(abs);
|
|
||||||
|
const realName = attachmentNameByRelPath.get(relPath);
|
||||||
|
const baseName = realName || path.basename(abs);
|
||||||
|
const ext = path.extname(baseName);
|
||||||
|
|
||||||
const fileNameWithExt =
|
const fileNameWithExt =
|
||||||
sanitizeFileName(path.basename(abs, ext)) + ext.toLowerCase();
|
sanitizeFileName(path.basename(baseName, ext)) + ext.toLowerCase();
|
||||||
|
|
||||||
const storageFilePath = `${getAttachmentFolderPath(
|
const storageFilePath = `${getAttachmentFolderPath(
|
||||||
AttachmentType.File,
|
AttachmentType.File,
|
||||||
@@ -240,7 +259,6 @@ export class ImportAttachmentService {
|
|||||||
return fresh;
|
return fresh;
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageDir = path.dirname(pageRelativePath);
|
|
||||||
const $ = load(html);
|
const $ = load(html);
|
||||||
|
|
||||||
// image
|
// image
|
||||||
|
|||||||
@@ -41,6 +41,15 @@ export function resolveRelativeAttachmentPath(
|
|||||||
'ImportUtils',
|
'ImportUtils',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Confluence Server uses "/download/attachments/..." in HTML but the ZIP
|
||||||
|
// stores files under "attachments/...". Strip the "download/" prefix so
|
||||||
|
// the path can match candidates from the archive.
|
||||||
|
const confluenceStripped = mainRel.replace(
|
||||||
|
/^download\/attachments\//,
|
||||||
|
'attachments/',
|
||||||
|
);
|
||||||
|
|
||||||
const fallback = path
|
const fallback = path
|
||||||
.normalize(path.join(pageDir, mainRel))
|
.normalize(path.join(pageDir, mainRel))
|
||||||
.split(path.sep)
|
.split(path.sep)
|
||||||
@@ -49,9 +58,13 @@ export function resolveRelativeAttachmentPath(
|
|||||||
if (attachmentCandidates.has(mainRel)) {
|
if (attachmentCandidates.has(mainRel)) {
|
||||||
return mainRel;
|
return mainRel;
|
||||||
}
|
}
|
||||||
|
if (confluenceStripped !== mainRel && attachmentCandidates.has(confluenceStripped)) {
|
||||||
|
return confluenceStripped;
|
||||||
|
}
|
||||||
if (attachmentCandidates.has(fallback)) {
|
if (attachmentCandidates.has(fallback)) {
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user