#!/usr/bin/python3 import argparse import json import os from pathlib import Path from alarm_api_client import AlarmApiClient CONFIG_FILE = Path.home() / ".alarms.json" def load_config() -> dict: """Load configuration from the config file.""" if CONFIG_FILE.exists(): with CONFIG_FILE.open() as f: return json.load(f) return {} def save_config(config: dict) -> None: """Save configuration to the config file.""" with CONFIG_FILE.open("w") as f: json.dump(config, f, indent=4) print(f"Configuration saved to {CONFIG_FILE}") def main(): parser = argparse.ArgumentParser(description="CLI for interacting with the Alarm API") parser.add_argument("--host", type=str, help="Alarm API host URL (overrides saved config)") parser.add_argument("--save-config", action="store_true", help="Save the provided host URL to the config file") subparsers = parser.add_subparsers(title="Commands", dest="command") # Create alarm create_parser = subparsers.add_parser("create", help="Create a new alarm") create_parser.add_argument("--name", required=False, help="Name of the alarm") create_parser.add_argument("--time", required=False, help="Alarm time in HH:MM:SS format") create_parser.add_argument("--repeat-type", choices=["daily", "weekly", "once"], help="Repeat type") create_parser.add_argument("--days", nargs="*", help="Days of the week for weekly repeat (e.g., monday tuesday)") create_parser.add_argument("--enabled", type=bool, default=True, help="Enable or disable the alarm") create_parser.add_argument("--snooze-duration", type=int, default=10, help="Snooze duration in minutes") create_parser.add_argument("--snooze-count", type=int, default=3, help="Maximum snooze count") create_parser.add_argument("--volume", type=int, default=80, help="Volume level (0-100)") create_parser.add_argument("--notes", type=str, default="", help="Notes for the alarm") create_parser.add_argument("--file", type=str, help="Path to the alarm sound file") create_parser.add_argument("--from-file", type=str, help="Path to JSON file containing alarm configuration") # Get alarms subparsers.add_parser("list", help="List all alarms") # Update alarm update_parser = subparsers.add_parser("update", help="Update an existing alarm") update_parser.add_argument("--id", type=int, required=True, help="ID of the alarm to update") update_parser.add_argument("--name", help="Updated name of the alarm") update_parser.add_argument("--time", help="Updated time in HH:MM:SS format") update_parser.add_argument("--repeat-type", choices=["daily", "weekly"], help="Updated repeat type") update_parser.add_argument("--days", nargs="*", help="Updated days of the week for weekly repeat") update_parser.add_argument("--enabled", type=bool, help="Enable or disable the alarm") update_parser.add_argument("--snooze-duration", type=int, help="Updated snooze duration in minutes") update_parser.add_argument("--snooze-count", type=int, help="Updated maximum snooze count") update_parser.add_argument("--volume", type=int, help="Updated volume level (0-100)") update_parser.add_argument("--notes", type=str, help="Updated notes for the alarm") update_parser.add_argument("--file", type=str, help="Updated path to the alarm sound file") # Delete alarm delete_parser = subparsers.add_parser("delete", help="Delete an alarm") delete_parser.add_argument("--id", type=int, required=True, help="ID of the alarm to delete") args = parser.parse_args() # Load saved config config = load_config() host = args.host or config.get("host", "http://localhost:8000") if args.save_config: config["host"] = host save_config(config) client = AlarmApiClient(host) try: if args.command == "create": if args.from_file: with open(args.from_file, "r") as f: alarm_data = json.load(f) print(f"Creating alarm from file: {args.from_file}") else: repeat_rule = {"type": args.repeat_type} if args.repeat_type == "weekly": repeat_rule["days_of_week"] = args.days or [] alarm_data = { "name": args.name, "time": args.time, "repeat_rule": repeat_rule, "enabled": args.enabled, "snooze": {"enabled": True, "duration": args.snooze_duration, "max_count": args.snooze_count}, "metadata": {"volume": args.volume, "notes": args.notes}, } if args.file: alarm_data["file_to_play"] = args.file alarm_id = client.create_alarm(alarm_data) print(f"Alarm created with ID: {alarm_id}") elif args.command == "list": alarms = client.get_alarms() if not alarms: print("No alarms found.") else: for alarm in alarms: print(json.dumps(alarm, indent=4)) elif args.command == "update": alarm_data = {} if args.name: alarm_data["name"] = args.name if args.time: alarm_data["time"] = args.time if args.repeat_type: alarm_data["repeat_rule"] = {"type": args.repeat_type} if args.repeat_type == "weekly" and args.days: alarm_data["repeat_rule"]["days_of_week"] = args.days if args.enabled is not None: alarm_data["enabled"] = args.enabled if args.snooze_duration: alarm_data.setdefault("snooze", {})["duration"] = args.snooze_duration if args.snooze_count: alarm_data.setdefault("snooze", {})["max_count"] = args.snooze_count if args.volume: alarm_data.setdefault("metadata", {})["volume"] = args.volume if args.notes: alarm_data.setdefault("metadata", {})["notes"] = args.notes if args.file: alarm_data["file_to_play"] = args.file if client.update_alarm(args.id, alarm_data): print(f"Alarm ID {args.id} updated successfully.") elif args.command == "delete": if client.delete_alarm(args.id): print(f"Alarm ID {args.id} deleted successfully.") else: parser.print_help() except Exception as e: print(f"Error: {e}") if __name__ == "__main__": main()