457e7794a0
Modules: - parser.py: Full Excel parser (1,848 machines, Disney mapping, Pattern A+B parsing) - db_writer.py: SQLite writer with per-field update policy (seed + update modes) - backup.py: GPS/photo backup, restore, and compare - reporter.py: Comprehensive validation report generator - main.py: CLI entry point Database: assets.db with 1,848 machines across 36 columns Handbook: reference_handbook.md v2.0 — all sections finalized Report: validation_report.md — 184 OCR corrections, 143 unknown machines
110 lines
3.1 KiB
Python
110 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
🌱 Canteen Seed Data Import Tool
|
|
|
|
CLI entry point for the seed data import pipeline.
|
|
Parses Cantaloupe Excel exports and writes to SQLite database.
|
|
|
|
Usage:
|
|
python3 main.py seed-data/Machine_List.xlsx --output seed-data/assets.db
|
|
python3 main.py seed-data/Machine_List.xlsx --output seed-data/assets.db --mode=update
|
|
python3 main.py seed-data/Machine_List.xlsx -o seed-data/assets.db -m seed
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
import os
|
|
|
|
# Import pipeline modules
|
|
from parser import parse_excel
|
|
from db_writer import write_seed, write_update
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="🌱 Canteen Seed Data Import Tool",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog=(
|
|
"Examples:\n"
|
|
" %(prog)s seed-data/Machine_List.xlsx -o seed-data/assets.db\n"
|
|
" %(prog)s seed-data/Machine_List.xlsx -o seed-data/assets.db --mode=update\n"
|
|
),
|
|
)
|
|
|
|
parser.add_argument(
|
|
"input",
|
|
type=str,
|
|
help="Path to the input Excel file (Machine_List.xlsx)",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-o", "--output",
|
|
type=str,
|
|
default="seed-data/assets.db",
|
|
help="Output SQLite database path (default: seed-data/assets.db)",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-m", "--mode",
|
|
type=str,
|
|
choices=["seed", "update"],
|
|
default="seed",
|
|
help="Import mode: 'seed' for first import (fresh insert), 'update' for incremental (default: seed)",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Resolve input path
|
|
input_path = os.path.abspath(args.input)
|
|
if not os.path.exists(input_path):
|
|
print(f"❌ Error: Input file not found: {input_path}")
|
|
sys.exit(1)
|
|
|
|
output_path = os.path.abspath(args.output)
|
|
|
|
print("🌱 Canteen Seed Data Import Tool")
|
|
print("═" * 50)
|
|
print(f" 📄 Input: {input_path}")
|
|
print(f" 📁 Output: {output_path}")
|
|
print(f" 🔧 Mode: {args.mode}")
|
|
print()
|
|
|
|
# ── Step 1: Parse Excel ──
|
|
print("📋 Parsing Excel file...")
|
|
try:
|
|
machines = parse_excel(input_path)
|
|
except Exception as e:
|
|
print(f"❌ Error parsing Excel file: {e}")
|
|
sys.exit(1)
|
|
|
|
print(f" ✅ Parsed {len(machines)} machines from Excel")
|
|
print()
|
|
|
|
# ── Step 2: Write to database ──
|
|
print("💾 Writing to database...")
|
|
if args.mode == "seed":
|
|
stats = write_seed(machines, output_path)
|
|
else:
|
|
stats = write_update(machines, output_path)
|
|
|
|
print()
|
|
print("═" * 50)
|
|
print("✅ Import complete!")
|
|
print(f" Mode: {args.mode}")
|
|
print(f" Records: {stats.get('inserted', 0) + stats.get('updated', 0)} processed")
|
|
if "inserted" in stats:
|
|
print(f" Inserted: {stats['inserted']}")
|
|
if "updated" in stats:
|
|
print(f" Updated: {stats['updated']}")
|
|
if "preserved" in stats:
|
|
print(f" Preserved: {stats['preserved']}")
|
|
if "errors" in stats and stats["errors"]:
|
|
print(f" Errors: {stats['errors']}")
|
|
print("═" * 50)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|