72 lines
2.9 KiB
Python
72 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from app.mailer.campaign.loader import CampaignLoadError, CampaignSchemaError, load_campaign_config
|
|
from app.mailer.campaign.validation import Severity, validate_campaign_config
|
|
|
|
|
|
def _default_campaign_path() -> Path:
|
|
return Path(__file__).resolve().parents[1] / "examples" / "campaign.json"
|
|
|
|
|
|
def _print_text_report(report) -> None:
|
|
print(f"Campaign: {report.campaign_name} ({report.campaign_id})")
|
|
print(f"Entries: {report.entries_mode}" + (f", {report.entries_count} item(s)" if report.entries_count is not None else ""))
|
|
print(f"Attachments base path: {report.attachments_base_path}")
|
|
print(f"Rate limit: {report.rate_limit}")
|
|
print(f"IMAP append: {'enabled' if report.imap_append_enabled else 'disabled'}")
|
|
print(f"Issues: {report.error_count} error(s), {report.warning_count} warning(s)")
|
|
if report.issues:
|
|
print()
|
|
for issue in report.issues:
|
|
location = f" [{issue.path}]" if issue.path else ""
|
|
print(f"- {issue.severity.upper()} {issue.code}{location}: {issue.message}")
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
parser = argparse.ArgumentParser(description="Validate a MultiMailer campaign JSON file.")
|
|
parser.add_argument("--campaign", default=str(_default_campaign_path()), help="Path to campaign JSON file")
|
|
parser.add_argument("--schema", default=None, help="Optional path to campaign.schema.json")
|
|
parser.add_argument("--no-schema", action="store_true", help="Skip JSON Schema validation")
|
|
parser.add_argument("--check-files", action="store_true", help="Check referenced local files and CSV headers")
|
|
parser.add_argument("--json", action="store_true", help="Print machine-readable validation report")
|
|
args = parser.parse_args(argv)
|
|
|
|
campaign_path = Path(args.campaign).resolve()
|
|
try:
|
|
config = load_campaign_config(
|
|
campaign_path,
|
|
validate_schema=not args.no_schema,
|
|
schema_path=args.schema,
|
|
)
|
|
report = validate_campaign_config(config, campaign_file=campaign_path, check_files=args.check_files)
|
|
except CampaignSchemaError as exc:
|
|
if args.json:
|
|
print(json.dumps({"ok": False, "schema_errors": [error.__dict__ for error in exc.errors]}, indent=2), file=sys.stdout)
|
|
else:
|
|
print(str(exc), file=sys.stderr)
|
|
for error in exc.errors:
|
|
print(f"- {error.path}: {error.message}", file=sys.stderr)
|
|
return 2
|
|
except CampaignLoadError as exc:
|
|
print(str(exc), file=sys.stderr)
|
|
return 2
|
|
except Exception as exc:
|
|
print(f"campaign validation failed: {exc}", file=sys.stderr)
|
|
return 2
|
|
|
|
if args.json:
|
|
print(report.model_dump_json(indent=2))
|
|
else:
|
|
_print_text_report(report)
|
|
|
|
return 0 if report.ok else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|