clio/clio-api/cli.py

152 lines
4.6 KiB
Python
Raw Normal View History

2026-05-19 17:56:12 -04:00
#!/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()