SQE6BJ4BAANJ4N5HT6QC6DIQQEMNXGR46HVAFJUAX4WIVW352KKQC import { createFileImportData } from "../utils/audioMothParser";
import { createFileImportData, isAudioMothFile } from "../utils/audioMothParser";import { parseClusterFilenames, type FilenameParsing } from "../utils/filenameParser";import { extractAudioMetadata } from "../utils/fileUtils";
// Fetch cluster data to get timezoneuseEffect(() => {const fetchClusterData = async () => {if (!isAuthenticated || !isOpen || !locationId) {return;}try {const accessToken = await getAccessToken();const response = await fetch(`/api/clusters?locationId=${encodeURIComponent(locationId)}`, {headers: {Authorization: `Bearer ${accessToken}`,},});
if (response.ok) {const result = await response.json();const clusters = result.data || [];const targetCluster = clusters.find((cluster: { id: string; timezoneId?: string }) => cluster.id === clusterId);if (targetCluster?.timezoneId) {setClusterTimezone(targetCluster.timezoneId);console.log(`Cluster timezone: ${targetCluster.timezoneId}`);} else {console.warn(`No timezone found for cluster ${clusterId}, using UTC as fallback`);setClusterTimezone('UTC');}} else {console.error('Failed to fetch cluster data');setClusterTimezone('UTC'); // Fallback to UTC}} catch (error) {console.error('Error fetching cluster data:', error);setClusterTimezone('UTC'); // Fallback to UTC}};fetchClusterData();}, [isAuthenticated, getAccessToken, isOpen, locationId, clusterId]);
// Process files one by one to extract metadata
// First, identify AudioMoth vs non-AudioMoth files and batch parse filenames if neededconsole.log('Identifying file types and parsing filenames...');const nonAudioMothFiles: string[] = [];const fileTypeMap = new Map<string, boolean>(); // filename -> isAudioMoth// Quick scan to identify file typesfor (const fileHandle of scannedFiles) {const file = await fileHandle.getFile();try {const metadata = await extractAudioMetadata(file);const isAudioMoth = isAudioMothFile({artist: metadata.artist,comment: metadata.comment,});fileTypeMap.set(file.name, isAudioMoth);if (!isAudioMoth) {nonAudioMothFiles.push(file.name);}} catch (error) {console.warn(`Could not determine file type for ${file.name}:`, error);// Assume non-AudioMoth if we can't determinefileTypeMap.set(file.name, false);nonAudioMothFiles.push(file.name);}}// Batch parse non-AudioMoth filenames if we have any and timezone is availableconst timestampMap = new Map<string, FilenameParsing>();if (nonAudioMothFiles.length > 0 && clusterTimezone) {try {console.log(`Batch parsing ${nonAudioMothFiles.length} non-AudioMoth filenames with timezone ${clusterTimezone}`);const parsedTimestamps = parseClusterFilenames(nonAudioMothFiles, clusterTimezone);// Create lookup mapparsedTimestamps.forEach(parsed => {timestampMap.set(parsed.fileName, parsed);});console.log(`Successfully parsed timestamps for ${parsedTimestamps.length} files`);} catch (error) {console.error('Error parsing filenames:', error);console.warn('Continuing without filename timestamps - files will use current time');}} else if (nonAudioMothFiles.length > 0) {console.warn(`Found ${nonAudioMothFiles.length} non-AudioMoth files but no cluster timezone available`);}// Now process files one by one with precomputed timestamp data
// Use the locationId from propsconst fileImportData = await createFileImportData(file, locationId, clusterId);
// Get precomputed timestamp for non-AudioMoth filesconst precomputedTimestamp = timestampMap.get(file.name)?.timestamp;// Use the locationId from props and pass precomputed timestampconst fileImportData = await createFileImportData(file, locationId, clusterId, precomputedTimestamp);
}, [selectedFolder, folderPath, scanAudioFiles, onImportComplete, handleClose, clusterId, datasetId, locationId, processedFiles]);
}, [selectedFolder, folderPath, scanAudioFiles, onImportComplete, handleClose, clusterId, datasetId, locationId, processedFiles, clusterTimezone]);