mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-04 02:20:19 +01:00
Unified extraction method
This commit is contained in:
@@ -25,13 +25,13 @@ export const extractImagesOperationConfig = {
|
||||
|
||||
export const useExtractImagesOperation = () => {
|
||||
const { t } = useTranslation();
|
||||
const { extractAllZipFiles } = useToolResources();
|
||||
const { extractZipFiles } = useToolResources();
|
||||
|
||||
// Response handler that respects auto-unzip preferences
|
||||
const responseHandler = useCallback(async (blob: Blob, _originalFiles: File[]): Promise<File[]> => {
|
||||
// Extract images returns a ZIP file - use preference-aware extraction
|
||||
return await extractAllZipFiles(blob);
|
||||
}, [extractAllZipFiles]);
|
||||
return await extractZipFiles(blob);
|
||||
}, [extractZipFiles]);
|
||||
|
||||
return useToolOperation<ExtractImagesParameters>({
|
||||
...extractImagesOperationConfig,
|
||||
|
||||
@@ -27,14 +27,14 @@ export const scannerImageSplitOperationConfig = {
|
||||
|
||||
export const useScannerImageSplitOperation = () => {
|
||||
const { t } = useTranslation();
|
||||
const { extractAllZipFiles } = useToolResources();
|
||||
const { extractZipFiles } = useToolResources();
|
||||
|
||||
// Custom response handler that extracts ZIP files containing images
|
||||
// Can't add to exported config because it requires access to the hook so must be part of the hook
|
||||
const responseHandler = useCallback(async (blob: Blob, originalFiles: File[]): Promise<File[]> => {
|
||||
try {
|
||||
// Scanner image split returns ZIP files with multiple images
|
||||
const extractedFiles = await extractAllZipFiles(blob);
|
||||
const extractedFiles = await extractZipFiles(blob);
|
||||
|
||||
// If extraction succeeded and returned files, use them
|
||||
if (extractedFiles.length > 0) {
|
||||
@@ -49,7 +49,7 @@ export const useScannerImageSplitOperation = () => {
|
||||
const baseFileName = inputFileName.replace(/\.[^.]+$/, '');
|
||||
const singleFile = new File([blob], `${baseFileName}.png`, { type: 'image/png' });
|
||||
return [singleFile];
|
||||
}, [extractAllZipFiles]);
|
||||
}, [extractZipFiles]);
|
||||
|
||||
const config: ToolOperationConfig<ScannerImageSplitParameters> = {
|
||||
...scannerImageSplitOperationConfig,
|
||||
|
||||
@@ -151,7 +151,7 @@ export const useToolOperation = <TParams>(
|
||||
const { state, actions } = useToolState();
|
||||
const { actions: fileActions } = useFileContext();
|
||||
const { processFiles, cancelOperation: cancelApiCalls } = useToolApiCalls<TParams>();
|
||||
const { generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles, extractAllZipFiles } = useToolResources();
|
||||
const { generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles } = useToolResources();
|
||||
|
||||
// Track last operation for undo functionality
|
||||
const lastOperationRef = useRef<{
|
||||
@@ -259,11 +259,6 @@ export const useToolOperation = <TParams>(
|
||||
// Default: assume ZIP response for multi-file endpoints
|
||||
// Note: extractZipFiles will check preferences.autoUnzip setting
|
||||
processedFiles = await extractZipFiles(response.data);
|
||||
|
||||
if (processedFiles.length === 0) {
|
||||
// Try the generic extraction as fallback
|
||||
processedFiles = await extractAllZipFiles(response.data);
|
||||
}
|
||||
}
|
||||
// Assume all inputs succeeded together unless server provided an error earlier
|
||||
successSourceIds = validFiles.map(f => (f as any).fileId) as any;
|
||||
@@ -446,7 +441,7 @@ export const useToolOperation = <TParams>(
|
||||
actions.setLoading(false);
|
||||
actions.setProgress(null);
|
||||
}
|
||||
}, [t, config, actions, addFiles, consumeFiles, processFiles, generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles, extractAllZipFiles]);
|
||||
}, [t, config, actions, addFiles, consumeFiles, processFiles, generateThumbnails, createDownloadInfo, cleanupBlobUrls, extractZipFiles]);
|
||||
|
||||
const cancelOperation = useCallback(() => {
|
||||
cancelApiCalls();
|
||||
|
||||
@@ -85,66 +85,17 @@ export const useToolResources = () => {
|
||||
|
||||
const extractZipFiles = useCallback(async (zipBlob: Blob, skipAutoUnzip = false): Promise<File[]> => {
|
||||
try {
|
||||
// Check if ZIP contains HTML files - if so, keep as ZIP
|
||||
const zipFile = new File([zipBlob], 'temp.zip', { type: 'application/zip' });
|
||||
const containsHtml = await zipFileService.containsHtmlFiles(zipFile);
|
||||
|
||||
if (containsHtml) {
|
||||
// HTML files should stay zipped
|
||||
return [new File([zipBlob], 'result.zip', { type: 'application/zip' })];
|
||||
}
|
||||
|
||||
// Check if we should extract based on preferences
|
||||
const shouldExtract = await zipFileService.shouldUnzip(
|
||||
zipBlob,
|
||||
preferences.autoUnzip,
|
||||
preferences.autoUnzipFileLimit,
|
||||
return await zipFileService.extractWithPreferences(zipBlob, {
|
||||
autoUnzip: preferences.autoUnzip,
|
||||
autoUnzipFileLimit: preferences.autoUnzipFileLimit,
|
||||
skipAutoUnzip
|
||||
);
|
||||
|
||||
if (!shouldExtract) {
|
||||
return [new File([zipBlob], 'result.zip', { type: 'application/zip' })];
|
||||
}
|
||||
|
||||
const extractionResult = await zipFileService.extractAllFiles(zipFile);
|
||||
return extractionResult.success ? extractionResult.extractedFiles : [];
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('useToolResources.extractZipFiles - Error:', error);
|
||||
return [];
|
||||
}
|
||||
}, [preferences.autoUnzip, preferences.autoUnzipFileLimit]);
|
||||
|
||||
const extractAllZipFiles = useCallback(async (zipBlob: Blob, skipAutoUnzip = false): Promise<File[]> => {
|
||||
try {
|
||||
// Check if ZIP contains HTML files - if so, keep as ZIP
|
||||
const zipFile = new File([zipBlob], 'temp.zip', { type: 'application/zip' });
|
||||
const containsHtml = await zipFileService.containsHtmlFiles(zipFile);
|
||||
|
||||
if (containsHtml) {
|
||||
// HTML files should stay zipped
|
||||
return [new File([zipBlob], 'result.zip', { type: 'application/zip' })];
|
||||
}
|
||||
|
||||
// Check if we should extract based on preferences
|
||||
const shouldExtract = await zipFileService.shouldUnzip(
|
||||
zipBlob,
|
||||
preferences.autoUnzip,
|
||||
preferences.autoUnzipFileLimit,
|
||||
skipAutoUnzip
|
||||
);
|
||||
|
||||
if (!shouldExtract) {
|
||||
return [new File([zipBlob], 'result.zip', { type: 'application/zip' })];
|
||||
}
|
||||
|
||||
const extractionResult = await zipFileService.extractAllFiles(zipFile);
|
||||
return extractionResult.success ? extractionResult.extractedFiles : [];
|
||||
} catch (error) {
|
||||
console.error('useToolResources.extractAllZipFiles - Error:', error);
|
||||
return [];
|
||||
}
|
||||
}, [preferences.autoUnzip, preferences.autoUnzipFileLimit]);
|
||||
|
||||
const createDownloadInfo = useCallback(async (
|
||||
files: File[],
|
||||
operationType: string
|
||||
@@ -168,7 +119,6 @@ export const useToolResources = () => {
|
||||
generateThumbnailsWithMetadata,
|
||||
createDownloadInfo,
|
||||
extractZipFiles,
|
||||
extractAllZipFiles,
|
||||
cleanupBlobUrls,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -401,6 +401,62 @@ export class ZipFileService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract files from ZIP with HTML detection and preference checking
|
||||
* This is the unified method that handles the common pattern of:
|
||||
* 1. Check for HTML files → keep zipped if present
|
||||
* 2. Check user preferences → respect autoUnzipFileLimit
|
||||
* 3. Extract files if appropriate
|
||||
*
|
||||
* @param zipBlob - The ZIP blob to process
|
||||
* @param options - Extraction options
|
||||
* @returns Array of files (either extracted or the ZIP itself)
|
||||
*/
|
||||
async extractWithPreferences(
|
||||
zipBlob: Blob,
|
||||
options: {
|
||||
autoUnzip: boolean;
|
||||
autoUnzipFileLimit: number;
|
||||
skipAutoUnzip?: boolean;
|
||||
}
|
||||
): Promise<File[]> {
|
||||
try {
|
||||
// Create File object if not already
|
||||
const zipFile = zipBlob instanceof File
|
||||
? zipBlob
|
||||
: new File([zipBlob], 'result.zip', { type: 'application/zip' });
|
||||
|
||||
// Check if ZIP contains HTML files - if so, keep as ZIP
|
||||
const containsHtml = await this.containsHtmlFiles(zipFile);
|
||||
if (containsHtml) {
|
||||
return [zipFile];
|
||||
}
|
||||
|
||||
// Check if we should extract based on preferences
|
||||
const shouldExtract = await this.shouldUnzip(
|
||||
zipBlob,
|
||||
options.autoUnzip,
|
||||
options.autoUnzipFileLimit,
|
||||
options.skipAutoUnzip || false
|
||||
);
|
||||
|
||||
if (!shouldExtract) {
|
||||
return [zipFile];
|
||||
}
|
||||
|
||||
// Extract all files
|
||||
const extractionResult = await this.extractAllFiles(zipFile);
|
||||
return extractionResult.success ? extractionResult.extractedFiles : [zipFile];
|
||||
} catch (error) {
|
||||
console.error('Error in extractWithPreferences:', error);
|
||||
// On error, return ZIP as-is
|
||||
const zipFile = zipBlob instanceof File
|
||||
? zipBlob
|
||||
: new File([zipBlob], 'result.zip', { type: 'application/zip' });
|
||||
return [zipFile];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all files from a ZIP archive (not limited to PDFs)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user