|
434 | 434 | gtfsState.selectedFileId = null; |
435 | 435 | gtfsState.selectedFileName = null; |
436 | 436 | gtfsState.rows = []; |
437 | | - gtfsState.uploadProgressPercent = 5; |
438 | | - gtfsState.currentProcessingFile = 'Starting...'; |
439 | | - gtfsState.uploadProgress = 'Initializing...'; |
| 437 | + gtfsState.uploadProgressPercent = 10; |
| 438 | + gtfsState.uploadProgress = 'Processing on server...'; |
440 | 439 |
|
441 | 440 | await yieldToUI(); |
442 | 441 |
|
443 | 442 | try { |
444 | | - console.log('Processing zip file, size:', file.size); |
445 | | - gtfsState.uploadProgress = 'Extracting ZIP file...'; |
446 | | - gtfsState.currentProcessingFile = 'Reading ZIP file...'; |
447 | | - gtfsState.uploadProgressPercent = 10; |
| 443 | + gtfsState.uploadProgressPercent = 30; |
| 444 | + gtfsState.uploadProgress = 'Sending file to server...'; |
448 | 445 | await yieldToUI(); |
449 | 446 |
|
450 | | - const JSZip = (await import('jszip')).default; |
451 | | - const zip = await JSZip.loadAsync(file); |
452 | | -
|
453 | | - const zipFileNames = Object.keys(zip.files); |
454 | | -
|
455 | | - if (zipFileNames.length === 0) { |
456 | | - throw new Error('The ZIP file appears to be empty'); |
457 | | - } |
458 | | -
|
459 | | - const txtFiles = Object.entries(zip.files).filter(([filename, entry]) => { |
460 | | - if (entry.dir) return false; |
461 | | - const baseName = filename.split('/').pop() || filename; |
462 | | - return baseName.endsWith('.txt'); |
463 | | - }); |
464 | | -
|
465 | | - const totalFiles = txtFiles.length; |
466 | | - const rawFiles: Array<{ filename: string; content: string }> = []; |
467 | | -
|
468 | | - for (let i = 0; i < txtFiles.length; i++) { |
469 | | - const [filename, zipEntry] = txtFiles[i]; |
470 | | - const baseName = filename.split('/').pop() || filename; |
471 | | -
|
472 | | - gtfsState.currentProcessingFile = baseName; |
473 | | - gtfsState.uploadProgressPercent = Math.round(((i + 1) / totalFiles) * 40); |
474 | | - gtfsState.uploadProgress = `Reading ${baseName} (${i + 1}/${totalFiles})...`; |
475 | | -
|
476 | | - await yieldToUI(); |
477 | | -
|
478 | | - try { |
479 | | - const content = await zipEntry.async('string'); |
480 | | - if (content.trim()) { |
481 | | - rawFiles.push({ |
482 | | - filename: baseName, |
483 | | - content |
484 | | - }); |
485 | | - } |
486 | | - } catch (readError) { |
487 | | - console.warn(`Failed to read ${baseName}:`, readError); |
488 | | - } |
489 | | - } |
490 | | -
|
491 | | - if (rawFiles.length === 0) { |
492 | | - throw new Error('No valid GTFS files found in the ZIP'); |
493 | | - } |
| 447 | + const formData = new FormData(); |
| 448 | + formData.append('file', file); |
494 | 449 |
|
495 | | - gtfsState.uploadProgress = 'Uploading to server for processing...'; |
496 | | - gtfsState.uploadProgressPercent = 50; |
497 | | - gtfsState.currentProcessingFile = 'Sending to server...'; |
498 | | - await yieldToUI(); |
499 | | -
|
500 | | - const response = await fetch('/api/gtfs-static-db', { |
| 450 | + const response = await fetch('/api/gtfs-static', { |
501 | 451 | method: 'POST', |
502 | | - headers: { 'Content-Type': 'application/json' }, |
503 | | - body: JSON.stringify({ |
504 | | - action: 'uploadRaw', |
505 | | - name: sourceUrl || 'Uploaded GTFS', |
506 | | - sourceUrl, |
507 | | - files: rawFiles |
508 | | - }) |
| 452 | + body: formData |
509 | 453 | }); |
510 | 454 |
|
511 | | - gtfsState.uploadProgressPercent = 90; |
| 455 | + gtfsState.uploadProgressPercent = 80; |
512 | 456 | await yieldToUI(); |
513 | 457 |
|
514 | 458 | const result = await response.json(); |
515 | 459 |
|
516 | 460 | if (!response.ok || result.error) { |
517 | | - throw new Error(result.error || 'Failed to upload to database'); |
| 461 | + throw new Error(result.error || 'Failed to process GTFS file'); |
518 | 462 | } |
519 | 463 |
|
520 | 464 | gtfsState.gtfsFiles = result.files.map( |
521 | | - (f: { id: number; filename: string; columns: string[]; rowCount: number }) => ({ |
| 465 | + (f: { id: number; filename: string; rowCount: number }) => ({ |
522 | 466 | id: f.id, |
523 | 467 | name: f.filename, |
524 | | - columns: f.columns, |
| 468 | + columns: [], |
525 | 469 | rowCount: f.rowCount |
526 | 470 | }) |
527 | 471 | ); |
|
543 | 487 |
|
544 | 488 | gtfsState.uploadProgress = ''; |
545 | 489 | gtfsState.uploadProgressPercent = 0; |
546 | | - gtfsState.currentProcessingFile = ''; |
547 | 490 | gtfsState.showGtfsInput = false; |
548 | 491 | } catch (e) { |
549 | 492 | console.error('Error processing zip:', e); |
550 | 493 | gtfsState.error = e instanceof Error ? e.message : 'Failed to process GTFS file'; |
551 | 494 | gtfsState.uploadProgress = ''; |
552 | 495 | gtfsState.uploadProgressPercent = 0; |
553 | | - gtfsState.currentProcessingFile = ''; |
554 | 496 | } finally { |
555 | 497 | gtfsState.loading = false; |
556 | 498 | } |
|
596 | 538 | gtfsState.selectedFileId = null; |
597 | 539 | gtfsState.selectedFileName = null; |
598 | 540 | gtfsState.rows = []; |
599 | | - gtfsState.uploadProgressPercent = 5; |
600 | | - gtfsState.currentProcessingFile = 'Starting...'; |
601 | | - gtfsState.uploadProgress = 'Fetching GTFS file...'; |
| 541 | + gtfsState.uploadProgressPercent = 10; |
| 542 | + gtfsState.uploadProgress = 'Processing on server...'; |
602 | 543 |
|
603 | 544 | await yieldToUI(); |
604 | 545 |
|
605 | 546 | try { |
606 | | - gtfsState.uploadProgress = 'Fetching GTFS file...'; |
607 | | - gtfsState.uploadProgressPercent = 10; |
608 | | - gtfsState.currentProcessingFile = 'Downloading from URL...'; |
| 547 | + gtfsState.uploadProgressPercent = 30; |
| 548 | + gtfsState.uploadProgress = 'Fetching and processing...'; |
609 | 549 | await yieldToUI(); |
610 | 550 |
|
611 | | - console.log('Fetching from URL:', gtfsState.feedUrl); |
612 | | -
|
613 | 551 | const response = await fetch('/api/gtfs-static', { |
614 | 552 | method: 'POST', |
615 | 553 | headers: { 'Content-Type': 'application/json' }, |
616 | 554 | body: JSON.stringify({ url: gtfsState.feedUrl }) |
617 | 555 | }); |
618 | 556 |
|
619 | | - console.log('Response received'); |
620 | | - gtfsState.uploadProgressPercent = 30; |
621 | | - await yieldToUI(); |
622 | | -
|
623 | | - const contentType = response.headers.get('content-type') || ''; |
| 557 | + const result = await response.json(); |
624 | 558 |
|
625 | | - if (contentType.includes('application/json')) { |
626 | | - const data = await response.json(); |
627 | | - throw new Error(data.error || 'Failed to fetch GTFS file'); |
| 559 | + if (!response.ok || result.error) { |
| 560 | + throw new Error(result.error || 'Failed to fetch GTFS file'); |
628 | 561 | } |
629 | 562 |
|
630 | | - if (!response.ok) { |
631 | | - throw new Error(`Failed to fetch GTFS file: ${response.status} ${response.statusText}`); |
632 | | - } |
| 563 | + gtfsState.gtfsFiles = result.files.map( |
| 564 | + (f: { id: number; filename: string; rowCount: number }) => ({ |
| 565 | + id: f.id, |
| 566 | + name: f.filename, |
| 567 | + columns: [], |
| 568 | + rowCount: f.rowCount |
| 569 | + }) |
| 570 | + ); |
633 | 571 |
|
634 | | - gtfsState.uploadProgress = 'Downloading file...'; |
635 | | - gtfsState.uploadProgressPercent = 40; |
636 | | - await yieldToUI(); |
| 572 | + gtfsState.gtfsFiles.sort((a, b) => { |
| 573 | + const aRequired = GTFS_FILES[a.name]?.required ?? false; |
| 574 | + const bRequired = GTFS_FILES[b.name]?.required ?? false; |
| 575 | + if (aRequired !== bRequired) return bRequired ? 1 : -1; |
| 576 | + return a.name.localeCompare(b.name); |
| 577 | + }); |
637 | 578 |
|
638 | | - const blob = await response.blob(); |
639 | | - console.log('Blob received, size:', blob.size); |
| 579 | + gtfsState.uploadProgressPercent = 100; |
| 580 | + gtfsState.uploadProgress = 'Complete!'; |
| 581 | + saveUrl(gtfsState.feedUrl); |
640 | 582 |
|
641 | | - if (blob.size === 0) { |
642 | | - throw new Error('Received empty file from server'); |
| 583 | + if (gtfsState.gtfsFiles.length > 0) { |
| 584 | + await selectFile(gtfsState.gtfsFiles[0]); |
643 | 585 | } |
644 | 586 |
|
645 | | - await processZipFile(blob, gtfsState.feedUrl); |
646 | | - saveUrl(gtfsState.feedUrl); |
| 587 | + gtfsState.uploadProgress = ''; |
| 588 | + gtfsState.uploadProgressPercent = 0; |
| 589 | + gtfsState.showGtfsInput = false; |
647 | 590 | } catch (e) { |
648 | 591 | console.error('fetchFromUrl error:', e); |
649 | 592 | gtfsState.error = e instanceof Error ? e.message : 'Failed to fetch GTFS file'; |
| 593 | + } finally { |
650 | 594 | gtfsState.loading = false; |
651 | 595 | gtfsState.uploadProgress = ''; |
652 | 596 | gtfsState.uploadProgressPercent = 0; |
653 | | - gtfsState.currentProcessingFile = ''; |
654 | 597 | } |
655 | 598 | } |
656 | 599 |
|
|
0 commit comments