mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-11 06:11:15 +00:00
feat: add support for 7z, PDF, STL, and other document types
- Add 7Z and DOCUMENT to ArchiveType enum - Detect .7z, .pdf, .stl, .obj, .3mf, .step, .blend, .gcode, .svg, .dxf, .ai, .eps, .psd files as fetchable documents - Handle DOCUMENT and 7Z formats in worker pipeline (skip extraction, record file as single entry) - Add Prisma migration for new enum values
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
-- AlterEnum
|
||||||
|
ALTER TYPE "ArchiveType" ADD VALUE 'SEVEN_Z';
|
||||||
|
ALTER TYPE "ArchiveType" ADD VALUE 'DOCUMENT';
|
||||||
@@ -377,6 +377,8 @@ enum ChannelRole {
|
|||||||
enum ArchiveType {
|
enum ArchiveType {
|
||||||
ZIP
|
ZIP
|
||||||
RAR
|
RAR
|
||||||
|
SEVEN_Z
|
||||||
|
DOCUMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
enum IngestionStatus {
|
enum IngestionStatus {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export type ArchiveFormat = "ZIP" | "RAR";
|
export type ArchiveFormat = "ZIP" | "RAR" | "7Z" | "DOCUMENT";
|
||||||
|
|
||||||
export interface MultipartInfo {
|
export interface MultipartInfo {
|
||||||
baseName: string;
|
baseName: string;
|
||||||
@@ -48,6 +48,9 @@ const patterns: {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** Extensions we recognize as fetchable documents (archives + standalone files) */
|
||||||
|
const DOCUMENT_EXTENSIONS = /\.(pdf|stl|obj|3mf|step|stp|blend|gcode|svg|dxf|ai|eps|psd)$/i;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect if a filename is an archive and extract multipart info.
|
* Detect if a filename is an archive and extract multipart info.
|
||||||
*/
|
*/
|
||||||
@@ -85,11 +88,32 @@ export function detectArchive(fileName: string): MultipartInfo | null {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Single .7z file
|
||||||
|
if (/\.7z$/i.test(fileName)) {
|
||||||
|
return {
|
||||||
|
baseName: fileName.replace(/\.7z$/i, ""),
|
||||||
|
partNumber: -1,
|
||||||
|
format: "7Z",
|
||||||
|
pattern: "SINGLE",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standalone documents (PDFs, STLs, 3D files, etc.)
|
||||||
|
if (DOCUMENT_EXTENSIONS.test(fileName)) {
|
||||||
|
const ext = fileName.match(DOCUMENT_EXTENSIONS)![0];
|
||||||
|
return {
|
||||||
|
baseName: fileName.replace(DOCUMENT_EXTENSIONS, ""),
|
||||||
|
partNumber: -1,
|
||||||
|
format: "DOCUMENT",
|
||||||
|
pattern: "SINGLE",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a filename looks like any archive attachment we should process.
|
* Check if a filename looks like any attachment we should process.
|
||||||
*/
|
*/
|
||||||
export function isArchiveAttachment(fileName: string): boolean {
|
export function isArchiveAttachment(fileName: string): boolean {
|
||||||
return detectArchive(fileName) !== null;
|
return detectArchive(fileName) !== null;
|
||||||
|
|||||||
@@ -873,8 +873,21 @@ async function processOneArchiveSet(
|
|||||||
try {
|
try {
|
||||||
if (archiveSet.type === "ZIP") {
|
if (archiveSet.type === "ZIP") {
|
||||||
entries = await readZipCentralDirectory(tempPaths);
|
entries = await readZipCentralDirectory(tempPaths);
|
||||||
} else {
|
} else if (archiveSet.type === "RAR") {
|
||||||
entries = await readRarContents(tempPaths[0]);
|
entries = await readRarContents(tempPaths[0]);
|
||||||
|
} else if (archiveSet.type === "DOCUMENT" || archiveSet.type === "7Z") {
|
||||||
|
// Standalone documents (PDF, STL, etc.) and 7z files — no extraction needed,
|
||||||
|
// just record the file itself as the single entry
|
||||||
|
const part = archiveSet.parts[0];
|
||||||
|
const ext = part.fileName.match(/\.([^.]+)$/)?.[1] ?? null;
|
||||||
|
entries = [{
|
||||||
|
path: part.fileName,
|
||||||
|
fileName: part.fileName,
|
||||||
|
extension: ext,
|
||||||
|
compressedSize: part.fileSize,
|
||||||
|
uncompressedSize: part.fileSize,
|
||||||
|
crc32: null,
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
accountLog.warn({ err, baseName: archiveSet.baseName }, "Failed to read archive metadata, ingesting without file list");
|
accountLog.warn({ err, baseName: archiveSet.baseName }, "Failed to read archive metadata, ingesting without file list");
|
||||||
@@ -975,7 +988,7 @@ async function processOneArchiveSet(
|
|||||||
contentHash,
|
contentHash,
|
||||||
fileName: archiveName,
|
fileName: archiveName,
|
||||||
fileSize: totalSize,
|
fileSize: totalSize,
|
||||||
archiveType: archiveSet.type,
|
archiveType: archiveSet.type === "7Z" ? "SEVEN_Z" : archiveSet.type,
|
||||||
sourceChannelId: channel.id,
|
sourceChannelId: channel.id,
|
||||||
sourceMessageId: archiveSet.parts[0].id,
|
sourceMessageId: archiveSet.parts[0].id,
|
||||||
sourceTopicId,
|
sourceTopicId,
|
||||||
|
|||||||
Reference in New Issue
Block a user