#!/usr/bin/env python3 """ Storage Saturation Report Export Script Converts JSON report data to PDF or JPG format using weasyprint and Pillow """ import sys import json import argparse import os from datetime import datetime try: from weasyprint import HTML, CSS except ImportError: print("Error: weasyprint module not installed. Please install with: pip3 install weasyprint", file=sys.stderr) sys.exit(1) try: from PIL import Image from pdf2image import convert_from_path except ImportError: print("Error: Pillow or pdf2image module not installed. Please install with: pip3 install Pillow pdf2image", file=sys.stderr) sys.exit(1) def generate_html_template(data): """Generate HTML report from JSON data""" title = data.get('title', 'Storage Saturation Report') date = data.get('date', datetime.now().strftime('%m/%d/%y, %I:%M %p')) services = data.get('services', []) # Determine color class for available space def get_available_class(available_bytes): if available_bytes == 0: return 'text-muted' available_gb = available_bytes / (1024 * 1024 * 1024) if available_gb < 5: return 'text-danger' elif available_gb < 50: return 'text-warning' return 'text-success' # Determine progress bar class def get_progress_class(percent): if percent >= 95: return 'progress-bar-danger' elif percent >= 85: return 'progress-bar-warning' elif percent >= 70: return 'progress-bar-info' return 'progress-bar-success' # Build table rows table_rows = '' if isinstance(services, dict) and 'error' in services: table_rows = f''' Error: {services['error']} ''' elif isinstance(services, list) and len(services) > 0: for service in services: host_name = service.get('host_name', 'N/A') caption = service.get('service_description', service.get('name', 'N/A')) disk_used = service.get('disk_used_display', 'N/A') disk_available = service.get('disk_available_display', 'N/A') disk_percent = service.get('disk_usage_percent', 0) disk_percent_display = service.get('disk_percent_display', 'N/A') # Get color classes available_bytes = service.get('disk_available_bytes', 0) available_class = get_available_class(available_bytes) progress_class = get_progress_class(disk_percent) # Build progress bar HTML if disk_percent > 0 and disk_percent_display != 'N/A': progress_bar = f'''
{disk_percent_display}
''' else: progress_bar = 'N/A' # Determine text color for available available_color = '#d9534f' if available_class == 'text-danger' else '#f0ad4e' if available_class == 'text-warning' else '#5cb85c' table_rows += f''' {host_name} {caption} {disk_used} {disk_available} {progress_bar} ''' else: table_rows = ''' No data available ''' html_template = f''' {title}

{title}

Summary of Tracked Storage: Volumes

Report Date: {date}

Ordered by: Disk Space Available - Ascending

{table_rows}
DISPLAY NAME CAPTION DISK SPACE USED DISK SPACE AVAILABLE PERCENT USED
''' return html_template def convert_to_pdf(html_content, output_file): """Convert HTML to PDF using weasyprint""" try: HTML(string=html_content).write_pdf(output_file) return True except Exception as e: print(f"Error converting to PDF: {e}", file=sys.stderr) return False def convert_pdf_to_jpg(pdf_file, jpg_file): """Convert PDF to JPG using pdf2image""" try: # Convert PDF to images (first page only) images = convert_from_path(pdf_file, first_page=1, last_page=1, dpi=150) if images: # Save as JPG images[0].save(jpg_file, 'JPEG', quality=95) return True return False except Exception as e: print(f"Error converting PDF to JPG: {e}", file=sys.stderr) return False def main(): parser = argparse.ArgumentParser(description='Export Storage Saturation Report to PDF or JPG') parser.add_argument('--input', required=True, help='Input JSON file path') parser.add_argument('--output', required=True, help='Output file path') parser.add_argument('--format', required=True, choices=['pdf', 'jpg'], help='Output format (pdf or jpg)') args = parser.parse_args() # Read JSON input try: with open(args.input, 'r', encoding='utf-8') as f: data = json.load(f) except FileNotFoundError: print(f"Error: Input file not found: {args.input}", file=sys.stderr) sys.exit(1) except json.JSONDecodeError as e: print(f"Error: Invalid JSON in input file: {e}", file=sys.stderr) sys.exit(1) except Exception as e: print(f"Error reading input file: {e}", file=sys.stderr) sys.exit(1) # Generate HTML html_content = generate_html_template(data) # Convert to PDF if args.format == 'pdf': if not convert_to_pdf(html_content, args.output): sys.exit(1) elif args.format == 'jpg': # First convert to PDF, then to JPG temp_pdf = args.output.replace('.jpg', '.pdf').replace('.jpeg', '.pdf') if not convert_to_pdf(html_content, temp_pdf): sys.exit(1) if not convert_pdf_to_jpg(temp_pdf, args.output): # Clean up temp PDF if os.path.exists(temp_pdf): os.remove(temp_pdf) sys.exit(1) # Clean up temp PDF if os.path.exists(temp_pdf): os.remove(temp_pdf) print(f"Successfully created {args.format.upper()}: {args.output}") sys.exit(0) if __name__ == '__main__': main()