#!/usr/bin/env python3 """ CLI for managing recordings database. Usage: python cli.py import-transcriptions /path/to/transcriptions --source phone python cli.py import-audio /path/to/audio --source portable python cli.py link-audio /path/to/audio python cli.py list [--source phone] [--limit 10] python cli.py stats """ import argparse from pathlib import Path import database import importer def cmd_import_transcriptions(args): """Import transcription JSON files.""" database.init_db() path = Path(args.path) audio_path = Path(args.audio_path) if args.audio_path else None if path.is_file(): result = importer.import_transcription_json( path, source_name=args.source, audio_base_path=audio_path, ) print(f"{result['status']}: {result['message']}") else: result = importer.import_transcription_directory( path, source_name=args.source, audio_base_path=audio_path, ) print(f"Import complete:") print(f" Created: {result['created']}") print(f" Already existed: {result['exists']}") print(f" Errors: {result['errors']}") if args.verbose: for d in result['details']: print(f" - {d['file']}: {d['status']}") def cmd_import_audio(args): """Import audio files without transcriptions.""" database.init_db() path = Path(args.path) if path.is_file(): result = importer.import_audio_file(path, source_name=args.source) print(f"{result['status']}: {result['message']}") else: result = importer.import_audio_directory(path, source_name=args.source) print(f"Import complete:") print(f" Created: {result['created']}") print(f" Already existed: {result['exists']}") print(f" Errors: {result['errors']}") def cmd_link_audio(args): """Link audio files to existing transcription records.""" database.init_db() path = Path(args.path) result = importer.link_audio_to_transcriptions(path) print(result['message']) def cmd_list(args): """List recordings in database.""" database.init_db() recordings = database.list_recordings( source_name=args.source, limit=args.limit, ) if not recordings: print("No recordings found.") return print(f"{'ID':>4} {'Source':<10} {'Duration':>8} {'Recorded':<20} Filename") print("-" * 80) for r in recordings: duration = f"{r['duration']/60:.1f}m" if r['duration'] else "?" recorded = r['recorded_at'][:19] if r['recorded_at'] else "?" print(f"{r['id']:>4} {r['source_name']:<10} {duration:>8} {recorded:<20} {r['filename']}") def cmd_stats(args): """Show database statistics.""" database.init_db() total = database.get_recordings_count() sources = database.list_sources() print(f"Total recordings: {total}") print() print("By source:") for s in sources: hours = s['total_hours'] or 0 print(f" {s['source_name']}: {s['recording_count']} recordings, {hours:.1f} hours") def main(): parser = argparse.ArgumentParser(description="Recordings database CLI") subparsers = parser.add_subparsers(dest="command", required=True) # import-transcriptions p = subparsers.add_parser("import-transcriptions", help="Import transcription JSON files") p.add_argument("path", help="Path to JSON file or directory") p.add_argument("--source", "-s", default="phone", help="Source name (default: phone)") p.add_argument("--audio-path", "-a", help="Path to audio files") p.add_argument("--verbose", "-v", action="store_true") p.set_defaults(func=cmd_import_transcriptions) # import-audio p = subparsers.add_parser("import-audio", help="Import audio files") p.add_argument("path", help="Path to audio file or directory") p.add_argument("--source", "-s", required=True, help="Source name") p.set_defaults(func=cmd_import_audio) # link-audio p = subparsers.add_parser("link-audio", help="Link audio files to transcriptions") p.add_argument("path", help="Directory containing audio files") p.set_defaults(func=cmd_link_audio) # list p = subparsers.add_parser("list", help="List recordings") p.add_argument("--source", "-s", help="Filter by source") p.add_argument("--limit", "-n", type=int, default=20) p.set_defaults(func=cmd_list) # stats p = subparsers.add_parser("stats", help="Show statistics") p.set_defaults(func=cmd_stats) args = parser.parse_args() args.func(args) if __name__ == "__main__": main()