diff --git a/src/sensorpajen/approve_sensors.py b/src/sensorpajen/approve_sensors.py index 7ae61b9..a7370e3 100644 --- a/src/sensorpajen/approve_sensors.py +++ b/src/sensorpajen/approve_sensors.py @@ -8,6 +8,7 @@ Interactive tool to manage pending and ignored sensors. import sys import json import logging +import argparse from pathlib import Path from typing import List @@ -191,6 +192,9 @@ def process_sensors(sensors: List[DiscoveredSensor], manager: DiscoveryManager): print(f"\nFound {len(sensors)} sensor(s) to review") for i, sensor in enumerate(sensors, 1): + # Mark as reviewed when shown + manager.mark_reviewed(sensor.mac) + display_sensor(sensor, i, len(sensors)) choice = get_user_choice() @@ -209,6 +213,31 @@ def process_sensors(sensors: List[DiscoveredSensor], manager: DiscoveryManager): def main(): """Main entry point for approve-sensors CLI.""" + # Parse command line arguments + parser = argparse.ArgumentParser( + description="Approve or ignore discovered Bluetooth sensors", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s # Show only new pending sensors + %(prog)s --all # Show all pending sensors (including reviewed) + %(prog)s --ignored # Show only ignored sensors + %(prog)s --all --ignored # Show all sensors + """ + ) + parser.add_argument( + '--all', '-a', + action='store_true', + help='Show all pending sensors, including previously reviewed ones' + ) + parser.add_argument( + '--ignored', '-i', + action='store_true', + help='Show ignored sensors' + ) + + args = parser.parse_args() + # Setup logging logging.basicConfig( level=logging.WARNING, @@ -223,27 +252,38 @@ def main(): # Load discovery manager manager = DiscoveryManager() - # Get pending and ignored sensors - pending = manager.get_pending() - ignored = manager.get_ignored() + # Get sensors based on flags + if args.all: + pending = manager.get_pending() + pending_label = "all pending" + else: + pending = manager.get_new_pending() + pending_label = "new pending" + + ignored = manager.get_ignored() if args.ignored else [] if not pending and not ignored: - print("\nāœ… No pending or ignored sensors found") - print("\nDiscovered sensors will appear here when detected.") + if args.all or args.ignored: + print(f"\nāœ… No {pending_label if pending else 'ignored'} sensors found") + else: + print("\nāœ… No new sensors to review") + all_pending = manager.get_pending() + if all_pending: + print(f"\nThere are {len(all_pending)} previously reviewed pending sensor(s).") + print("Run with --all to review them again.") return 0 - # Process pending sensors first + # Process pending sensors if pending: - print(f"\nšŸ“‹ Processing {len(pending)} pending sensor(s)...") + print(f"\nšŸ“‹ Processing {len(pending)} {pending_label} sensor(s)...") process_sensors(pending, manager) - # Ask about ignored sensors + # Process ignored sensors if requested if ignored: - print(f"\n\nThere are {len(ignored)} ignored sensor(s).") - review = input("Review ignored sensors? [y/N]: ").strip().lower() - - if review == 'y': - process_sensors(ignored, manager) + if pending: + print("\n" + "=" * 70) + print(f"\nšŸ“‹ Processing {len(ignored)} ignored sensor(s)...") + process_sensors(ignored, manager) print("\n" + "=" * 70) print("Done!") diff --git a/src/sensorpajen/discovery_manager.py b/src/sensorpajen/discovery_manager.py index ed8263b..27891dc 100644 --- a/src/sensorpajen/discovery_manager.py +++ b/src/sensorpajen/discovery_manager.py @@ -27,6 +27,7 @@ class DiscoveredSensor: last_seen: str sample_reading: Dict[str, float] status: str = "pending" # pending, approved, ignored + reviewed: bool = False # Has been shown in approval CLI ignored_at: Optional[str] = None ignore_reason: Optional[str] = None @@ -195,10 +196,26 @@ class DiscoveryManager: """Get list of sensors with status 'pending'.""" return [s for s in self.sensors.values() if s.status == "pending"] + def get_new_pending(self) -> List[DiscoveredSensor]: + """Get list of pending sensors that haven't been reviewed yet.""" + return [s for s in self.sensors.values() if s.status == "pending" and not s.reviewed] + def get_ignored(self) -> List[DiscoveredSensor]: """Get list of sensors with status 'ignored'.""" return [s for s in self.sensors.values() if s.status == "ignored"] + def mark_reviewed(self, mac: str): + """ + Mark a sensor as reviewed (shown in approval CLI). + + Args: + mac: MAC address + """ + mac = mac.upper() + if mac in self.sensors: + self.sensors[mac].reviewed = True + self.save() + def send_ntfy_notification(self, sensor: DiscoveredSensor): """ Send ntfy notification for a newly discovered sensor.