This commit is contained in:
123
src/exporter.py
Normal file
123
src/exporter.py
Normal file
@@ -0,0 +1,123 @@
|
||||
"""Export functionality for Code Pattern Search CLI."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .models import SearchResult
|
||||
|
||||
|
||||
class Exporter:
|
||||
"""Export search results to various formats."""
|
||||
|
||||
@staticmethod
|
||||
def export_results(
|
||||
results: list[SearchResult],
|
||||
output_path: Path,
|
||||
format: str = "json",
|
||||
include_metadata: bool = True,
|
||||
pretty_print: bool = True,
|
||||
) -> None:
|
||||
"""Export results to a file."""
|
||||
if format == "json":
|
||||
Exporter.export_to_json(
|
||||
results,
|
||||
output_path,
|
||||
include_metadata=include_metadata,
|
||||
pretty_print=pretty_print,
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"Unsupported export format: {format}")
|
||||
|
||||
@staticmethod
|
||||
def export_to_json(
|
||||
results: list[SearchResult],
|
||||
output_path: Path,
|
||||
include_metadata: bool = True,
|
||||
pretty_print: bool = True,
|
||||
) -> None:
|
||||
"""Export results to JSON format."""
|
||||
export_data = Exporter._prepare_export_data(results, include_metadata)
|
||||
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
if pretty_print:
|
||||
json.dump(export_data, f, indent=2, ensure_ascii=False)
|
||||
else:
|
||||
json.dump(export_data, f, ensure_ascii=False)
|
||||
|
||||
@staticmethod
|
||||
def export_to_csv(
|
||||
results: list[SearchResult],
|
||||
output_path: Path,
|
||||
) -> None:
|
||||
"""Export results to CSV format."""
|
||||
import csv
|
||||
|
||||
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow([
|
||||
"Repository",
|
||||
"URL",
|
||||
"Stars",
|
||||
"Language",
|
||||
"Total Matches",
|
||||
"Score",
|
||||
"Files",
|
||||
])
|
||||
|
||||
for result in results:
|
||||
files = ", ".join(result.get_match_summary().keys())
|
||||
writer.writerow([
|
||||
result.repo_name,
|
||||
result.repo_url,
|
||||
result.stars,
|
||||
result.language or "",
|
||||
result.total_matches,
|
||||
result.score,
|
||||
files,
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def _prepare_export_data(
|
||||
results: list[SearchResult],
|
||||
include_metadata: bool = True,
|
||||
) -> dict[str, Any]:
|
||||
"""Prepare data structure for export."""
|
||||
data: dict[str, Any] = {
|
||||
"total_repositories": len(results),
|
||||
"total_matches": sum(r.total_matches for r in results),
|
||||
"results": [r.to_dict() for r in results],
|
||||
}
|
||||
|
||||
if include_metadata:
|
||||
data["metadata"] = {
|
||||
"exported_at": Exporter._get_timestamp(),
|
||||
"version": "0.1.0",
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _get_timestamp() -> str:
|
||||
"""Get current timestamp."""
|
||||
from datetime import datetime
|
||||
return datetime.utcnow().isoformat() + "Z"
|
||||
|
||||
@staticmethod
|
||||
def format_summary(results: list[SearchResult]) -> str:
|
||||
"""Format results as a human-readable summary."""
|
||||
lines = []
|
||||
lines.append(f"Found {len(results)} repositories with matches:\n")
|
||||
|
||||
for result in results:
|
||||
lines.append(f"📦 {result.repo_name}")
|
||||
lines.append(f" ⭐ {result.stars} stars")
|
||||
lines.append(f" 🔍 {result.total_matches} matches")
|
||||
lines.append(f" 📊 Score: {result.score}")
|
||||
|
||||
if result.matches:
|
||||
files = result.get_match_summary()
|
||||
lines.append(f" 📁 Files: {', '.join(files.keys())}")
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines)
|
||||
Reference in New Issue
Block a user