ttvdrops/twitch/management/commands/validate_json_files.py

68 lines
2.4 KiB
Python

from __future__ import annotations
import json
import shutil
from pathlib import Path
from django.core.management.base import BaseCommand, CommandError, CommandParser
class Command(BaseCommand):
"""Validate JSON files and move invalid ones to an error directory."""
help = "Validate JSON files and move invalid ones to an error directory."
def add_arguments(self, parser: CommandParser) -> None:
"""Add command arguments.
Args:
parser: The command argument parser.
"""
parser.add_argument(
"path",
type=str,
help="Path to the directory containing JSON files to validate.",
)
parser.add_argument(
"--error-dir",
type=str,
default="error",
help="Name of subdirectory to move files with JSON errors to (default: 'error')",
)
def handle(self, **options: str) -> None:
"""Handle the command.
Args:
**options: Arbitrary keyword arguments.
Raises:
CommandError: If the provided path is not a valid directory.
"""
path = Path(options["path"])
error_dir_name = options["error_dir"]
if not path.is_dir():
msg = f"Path '{path}' is not a valid directory."
raise CommandError(msg)
error_dir = path / error_dir_name
error_dir.mkdir(exist_ok=True)
self.stdout.write(f"Validating JSON files in '{path}'...")
for file_path in path.glob("*.json"):
if file_path.is_file():
try:
with file_path.open("r", encoding="utf-8") as f:
json.load(f)
except json.JSONDecodeError:
self.stdout.write(self.style.WARNING(f"Invalid JSON in '{file_path.name}'. Moving to '{error_dir_name}'."))
try:
shutil.move(str(file_path), str(error_dir / file_path.name))
except Exception as e: # noqa: BLE001
self.stderr.write(self.style.ERROR(f"Could not move file '{file_path.name}': {e}"))
except Exception as e: # noqa: BLE001
self.stderr.write(self.style.ERROR(f"An unexpected error occurred with file '{file_path.name}': {e}"))
self.stdout.write(self.style.SUCCESS("Finished validating JSON files."))