127 lines
4.2 KiB
JavaScript
127 lines
4.2 KiB
JavaScript
/**
|
|
* Excel Integration Module
|
|
* Toast notifications and hash export
|
|
*/
|
|
(function() {
|
|
'use strict';
|
|
|
|
/**
|
|
* Thin wrapper over the shared toast helper. Keeps the
|
|
* window.app.modules.excel.showToast call sites in classifier
|
|
* unchanged while delegating to the canonical implementation in
|
|
* shared/toast.js (window.zddc.toast).
|
|
*/
|
|
function showToast(message, type = 'info') {
|
|
if (window.zddc && typeof window.zddc.toast === 'function') {
|
|
window.zddc.toast(message, type);
|
|
} else {
|
|
// shared/toast.js missing from the build — log so the
|
|
// problem is visible without crashing the caller.
|
|
console.warn('[classifier] window.zddc.toast unavailable;', type, message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Export SHA256 hashes in sha256sum format
|
|
*/
|
|
async function exportHashes() {
|
|
const files = window.app.modules.store.getDisplayFiles();
|
|
if (files.length === 0) {
|
|
alert('No files to export');
|
|
return;
|
|
}
|
|
|
|
// Check if SHA256 is enabled
|
|
if (!window.app.calculateSha256) {
|
|
alert('Please enable SHA256 checkbox first and wait for hashes to calculate');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Build sha256sum format: hash *filepath
|
|
const lines = [];
|
|
|
|
// Get root path
|
|
const rootPath = await getFullPath(window.app.rootHandle);
|
|
|
|
for (const file of files) {
|
|
if (!file.sha256 || file.sha256 === 'calculating...' || file.sha256 === 'error') {
|
|
continue; // Skip files without calculated hash
|
|
}
|
|
|
|
// Get full path from root
|
|
const folderPath = await getFullPath(file.folderHandle);
|
|
const fullPath = `${folderPath}/${zddc.joinExtension(file.originalFilename, file.extension)}`;
|
|
|
|
// Format: hash *filepath (asterisk indicates binary mode)
|
|
lines.push(`${file.sha256} *${fullPath}`);
|
|
}
|
|
|
|
if (lines.length === 0) {
|
|
alert('No SHA256 hashes available. Enable SHA256 and wait for calculation to complete.');
|
|
return;
|
|
}
|
|
|
|
// Create output
|
|
const output = lines.join('\n');
|
|
|
|
// Generate filename with timestamp
|
|
const now = new Date();
|
|
const timestamp = now.toISOString().replace(/[:.]/g, '-').slice(0, -5); // YYYY-MM-DDTHH-MM-SS
|
|
const filename = `sha256sums_${timestamp}.txt`;
|
|
|
|
// Download as file
|
|
const blob = new Blob([output], { type: 'text/plain' });
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
URL.revokeObjectURL(url);
|
|
|
|
// Show success message
|
|
showToast(`✓ Downloaded ${lines.length} hash(es) to ${filename}`, 'success');
|
|
|
|
} catch (err) {
|
|
console.error('Error exporting hashes:', err);
|
|
alert('Error exporting hashes: ' + err.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get full path from directory handle (all the way to root)
|
|
*/
|
|
async function getFullPath(dirHandle) {
|
|
const parts = [];
|
|
let current = dirHandle;
|
|
|
|
// Walk up to root - collect ALL parent folders
|
|
while (current) {
|
|
parts.unshift(current.name);
|
|
|
|
try {
|
|
// Try to get parent
|
|
if (typeof current.getParent === 'function') {
|
|
const parent = await current.getParent();
|
|
if (parent && parent !== current) {
|
|
current = parent;
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
} catch {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return parts.join('/');
|
|
}
|
|
|
|
// Export module
|
|
window.app.modules.excel = {
|
|
showToast,
|
|
exportHashes
|
|
};
|
|
})();
|