grafana
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import typer
|
||||
from rich.console import Console
|
||||
from .wrap_cli import wrap_app
|
||||
from .grafana_cli import grafana_app
|
||||
|
||||
app = typer.Typer()
|
||||
console = Console()
|
||||
@@ -8,5 +9,8 @@ console = Console()
|
||||
# Add the wrap subcommand to the main app
|
||||
app.add_typer(wrap_app, name="wrap")
|
||||
|
||||
# Add the grafana subcommand to the main app
|
||||
app.add_typer(grafana_app, name="grafana")
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
@@ -0,0 +1,132 @@
|
||||
import typer
|
||||
from rich.console import Console
|
||||
import json
|
||||
import pyperclip
|
||||
from typing import Dict, Any, List, Optional
|
||||
from pathlib import Path
|
||||
|
||||
console = Console()
|
||||
|
||||
# Create the main grafana subcommand
|
||||
grafana_app = typer.Typer()
|
||||
|
||||
def safe_get(data: Dict[str, Any], key: str, default: Any = None) -> Any:
|
||||
"""Safely get a value from a dictionary."""
|
||||
return data.get(key, default)
|
||||
|
||||
def mutate_panel(panel: Dict[str, Any]) -> None:
|
||||
"""Mutate a single panel by setting repeat and repeatDirection fields."""
|
||||
# Check if type is "row" and remove repeat key if it exists
|
||||
if safe_get(panel, 'type') == 'row':
|
||||
if 'repeat' in panel:
|
||||
del panel['repeat']
|
||||
else:
|
||||
# For non-row panels, set repeat and repeatDirection
|
||||
panel['repeat'] = 'instance'
|
||||
panel['repeatDirection'] = 'h'
|
||||
panel['maxPerRow'] = 12
|
||||
|
||||
def mutate_panels_recursive(panels: List[Dict[str, Any]]) -> None:
|
||||
"""Recursively mutate panels, handling nested panels."""
|
||||
for panel in panels:
|
||||
if not isinstance(panel, dict):
|
||||
continue
|
||||
|
||||
# Mutate current panel
|
||||
mutate_panel(panel)
|
||||
|
||||
# Check for nested panels
|
||||
nested_panels = safe_get(panel, 'panels', [])
|
||||
if nested_panels and isinstance(nested_panels, list):
|
||||
mutate_panels_recursive(nested_panels)
|
||||
|
||||
def mutate_grafana_json(data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Mutate Grafana JSON by setting repeat and repeatDirection fields.
|
||||
|
||||
Args:
|
||||
data: The Grafana dashboard JSON data
|
||||
|
||||
Returns:
|
||||
The mutated JSON data
|
||||
"""
|
||||
# Make a copy to avoid mutating the original
|
||||
mutated_data = json.loads(json.dumps(data))
|
||||
|
||||
# Get panels safely
|
||||
panels = safe_get(mutated_data, 'panels', [])
|
||||
|
||||
if panels and isinstance(panels, list):
|
||||
mutate_panels_recursive(panels)
|
||||
|
||||
return mutated_data
|
||||
|
||||
@grafana_app.command("mutate", short_help="Mutate Grafana JSON to set repeat fields.")
|
||||
def mutate_dashboard(
|
||||
input_file: Optional[Path] = typer.Option(
|
||||
None, "--input-file", "-i", help="Input JSON file path. If not provided, reads from clipboard."
|
||||
),
|
||||
output_file: Optional[Path] = typer.Option(
|
||||
None, "--output-file", "-o", help="Output JSON file path. If not provided, outputs to clipboard."
|
||||
)
|
||||
):
|
||||
"""
|
||||
Mutate Grafana JSON by setting repeat="instance" and repeatDirection="h".
|
||||
|
||||
This command processes Grafana dashboard JSON and modifies panels to:
|
||||
- Set repeat field to "instance"
|
||||
- Set repeatDirection field to "h"
|
||||
- Set maxPerRow to 12
|
||||
- Remove repeat field from row-type panels
|
||||
"""
|
||||
console.print("[blue]Processing Grafana dashboard JSON...[/blue]")
|
||||
|
||||
# Read input
|
||||
try:
|
||||
if input_file:
|
||||
console.print(f"[blue]Reading from file: {input_file}[/blue]")
|
||||
if not input_file.exists():
|
||||
console.print(f"[red]Error: Input file '{input_file}' not found[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
json_content = input_file.read_text(encoding='utf-8')
|
||||
else:
|
||||
console.print("[blue]Reading from clipboard...[/blue]")
|
||||
json_content = pyperclip.paste()
|
||||
if not json_content.strip():
|
||||
console.print("[red]Error: Clipboard is empty or contains no text.[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error reading input: {e}[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
# Parse JSON
|
||||
try:
|
||||
data = json.loads(json_content)
|
||||
except json.JSONDecodeError as e:
|
||||
console.print(f"[red]Error parsing JSON: {e}[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
# Mutate the data
|
||||
try:
|
||||
mutated_data = mutate_grafana_json(data)
|
||||
console.print("[green]Successfully mutated Grafana JSON![/green]")
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error mutating JSON: {e}[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
# Output result
|
||||
try:
|
||||
output_json = json.dumps(mutated_data, indent=2, ensure_ascii=False)
|
||||
|
||||
if output_file:
|
||||
console.print(f"[blue]Writing to file: {output_file}[/blue]")
|
||||
output_file.write_text(output_json, encoding='utf-8')
|
||||
console.print(f"[green]Output written to {output_file}[/green]")
|
||||
else:
|
||||
console.print("[blue]Copying to clipboard...[/blue]")
|
||||
pyperclip.copy(output_json)
|
||||
console.print("[green]Output copied to clipboard![/green]")
|
||||
except Exception as e:
|
||||
console.print(f"[red]Error writing output: {e}[/red]")
|
||||
raise typer.Exit(code=1)
|
||||
Reference in New Issue
Block a user