Files
dl-organizer/src/vlm/commands/plan.py
T

87 lines
3.2 KiB
Python
Raw Normal View History

"""Plan command implementation."""
import json
from pathlib import Path
from typing import Optional
import click
from vlm.context import CLIContext
from vlm.io import identities_to_plan_input, load_identities_json, load_analysis_json
from vlm.planner import generate_plan, save_plan
def plan_cmd(ctx: CLIContext, input: Path, output: Path, analysis: Optional[Path] = None) -> None:
"""Generate execution plan from identities; optionally use analysis for duplicate handling."""
config = ctx.config
logger = ctx.logger
click.echo(f"Generating execution plan from: {input}")
if analysis:
click.echo(f"Using analysis: {analysis}")
click.echo()
identities_data = load_identities_json(input)
movies_data = identities_data.get("movies", [])
series_data = identities_data.get("series", [])
anime_data = identities_data.get("anime", [])
other_data = identities_data.get("other", [])
click.echo(
f"Loaded {len(movies_data)} movies, {len(series_data)} series, "
f"{len(anime_data)} anime, {len(other_data)} other"
)
click.echo()
identities_list = identities_to_plan_input(identities_data)
analysis_data = None
if analysis:
if not analysis.exists():
click.echo(f"Error: Analysis file not found: {analysis}", err=True)
click.echo("Run 'vlm analyze' first to generate analysis.json.", err=True)
raise FileNotFoundError(analysis)
try:
analysis_data = load_analysis_json(analysis)
except (json.JSONDecodeError, KeyError) as e:
click.echo(f"Error: Invalid or incomplete analysis file: {e}", err=True)
click.echo("Run 'vlm analyze' to regenerate analysis.json.", err=True)
raise
click.echo("Generating execution plan...")
execution_plan = generate_plan(identities_list, config, analysis_data=analysis_data)
click.echo()
click.echo("Plan generation complete!")
click.echo()
click.echo("Operation summary:")
click.echo(f" Total operations: {execution_plan.summary['total']}")
click.echo(f" Move operations: {execution_plan.summary['move']}")
click.echo(f" Rename operations: {execution_plan.summary['rename']}")
click.echo(f" Quarantine operations: {execution_plan.summary['quarantine']}")
click.echo(f" No-op (skipped): {execution_plan.summary['no-op']}")
conflicts = sum(1 for op in execution_plan.operations if op.has_conflict)
if conflicts > 0:
click.echo()
click.echo(f" ⚠️ Conflicts detected: {conflicts}")
click.echo(" Review the plan file for details on conflicting operations.")
click.echo()
click.echo(f"Saving execution plan to: {output}")
output.parent.mkdir(parents=True, exist_ok=True)
save_plan(execution_plan, output)
click.echo("Execution plan saved successfully!")
click.echo()
click.echo("Next steps:")
click.echo(f" 1. Review the plan: {output}")
click.echo(" 2. Edit the plan if needed (it's JSON)")
click.echo(f" 3. Dry-run: vlm execute --plan {output}")
click.echo(f" 4. Execute: vlm execute --plan {output} --confirm")
logger.info(
f"Plan generated: {execution_plan.summary['total']} operations, "
f"{conflicts} conflicts, saved to {output}"
)