#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Command-line interface utilities for the chorus detection system.""" import argparse import os import sys from pathlib import Path from typing import Dict, Any, Optional, Tuple from chorus_detection.config import MODEL_PATH from chorus_detection.utils.logging import logger def parse_arguments() -> argparse.Namespace: """Parse command-line arguments. Returns: Parsed command-line arguments """ parser = argparse.ArgumentParser( description="Chorus Finder - Detect choruses in songs from YouTube URLs or local audio files") input_group = parser.add_mutually_exclusive_group() input_group.add_argument("--url", type=str, help="YouTube URL of a song") input_group.add_argument("--file", type=str, help="Path to a local audio file") parser.add_argument("--model_path", type=str, default=str(MODEL_PATH), help=f"Path to the pretrained model (default: {MODEL_PATH})") parser.add_argument("--verbose", action="store_true", help="Verbose output", default=True) parser.add_argument("--plot", action="store_true", help="Display plot of the audio waveform", default=True) parser.add_argument("--no-plot", dest="plot", action="store_false", help="Disable plot display (useful for headless environments)") return parser.parse_args() def get_input_source(args: argparse.Namespace) -> Optional[str]: """Get input source from arguments or user input. Args: args: Parsed command-line arguments Returns: Input source (URL or file path) """ input_source = args.url or args.file if not input_source: print("\nChorus Detection Tool") print("====================") print("\nNote: YouTube download functionality may be temporarily unavailable") print("due to YouTube's restrictions. If download fails, please use a local audio file.\n") print("Choose input method:") print("1. YouTube URL") print("2. Local audio file") choice = input("Enter choice (1 or 2): ") if choice == "1": input_source = input("Please enter the YouTube URL of the song: ") elif choice == "2": input_source = input("Please enter the path to the audio file: ") else: logger.error("Invalid choice") sys.exit(1) return input_source def is_youtube_url(input_source: str) -> bool: """Check if the input source is a YouTube URL. Args: input_source: Input source to check Returns: True if the input source is a YouTube URL, False otherwise """ return input_source.startswith(('http://', 'https://')) def validate_input_file(file_path: str) -> bool: """Validate that the input file exists and is readable. Args: file_path: Path to the input file Returns: True if the file is valid, False otherwise """ if not os.path.exists(file_path): logger.error(f"Error: File not found at {file_path}") return False if not os.path.isfile(file_path): logger.error(f"Error: {file_path} is not a file") return False if not os.access(file_path, os.R_OK): logger.error(f"Error: No permission to read {file_path}") return False return True