import gradio as gr from typing import Dict, List from style import Style class UIManager: """Manages all UI components and styling for Pixcribe""" def __init__(self): # Use centralized Style class for all CSS self.custom_css = Style.get_all_css() def create_header(self): """Create application header""" return gr.HTML("""

✨ Pixcribe

AI-Powered Social Media Caption Generator

""") def create_info_banner(self): """Create informational banner about model loading and processing times""" return gr.HTML("""
⏱️

Please Note: Processing Time

Initial setup and model loading may take a while as multiple AI models are initialized and cached. This includes YOLOv11 object detection, OpenCLIP semantic analysis, Qwen2.5-VL caption generation, and other advanced models.

Processing time varies depending on system resources. Thank you for your patience while we generate high-quality captions!

""") def create_footer(self): """Create application footer""" return gr.HTML(""" """) def format_captions_with_copy(self, captions: List[Dict]) -> str: """Format captions as HTML with copy functionality""" if not captions: return "

No captions generated

" captions_html = "" for i, cap in enumerate(captions): caption_text = cap.get('caption', '') hashtags = cap.get('hashtags', []) tone = cap.get('tone', 'unknown').title() # Create unique ID for each caption caption_id = f"caption_{i}" # Full text to copy (caption + hashtags) full_text = f"{caption_text}\n\n{' '.join([f'#{tag}' for tag in hashtags])}" captions_html += f"""
Caption {i+1} · {tone}
{caption_text}
{' '.join([f'#{tag}' for tag in hashtags])}
""" return captions_html def create_batch_progress_html(self, current: int, total: int, percent: float, estimated_remaining: int) -> str: """ Create HTML for batch processing progress display. Args: current: Number of images completed total: Total number of images percent: Completion percentage (0-100) estimated_remaining: Estimated remaining time in seconds Returns: Formatted HTML string with progress bar and information """ # Convert remaining time to minutes and seconds minutes = int(estimated_remaining // 60) seconds = int(estimated_remaining % 60) time_str = f"{minutes}m {seconds}s" if minutes > 0 else f"{seconds}s" html = f"""
Processing image {current} of {total}
Progress: {percent:.1f}% {f'Estimated time remaining: {time_str}' if estimated_remaining > 0 else ''}
""" return html def format_batch_results_html(self, batch_results: Dict) -> str: """ Format batch processing results as HTML. Args: batch_results: Dictionary containing batch processing results Returns: Formatted HTML string with all batch results """ results = batch_results.get('results', {}) if not results: return "

No results to display

" # Build summary card total_processed = batch_results.get('total_processed', 0) total_success = batch_results.get('total_success', 0) total_failed = batch_results.get('total_failed', 0) total_time = batch_results.get('total_time', 0) avg_time = batch_results.get('average_time_per_image', 0) html_parts = [] # Summary card html_parts.append(f"""
✓ Batch Processing Complete
{total_processed}
Total Processed
{total_success}
Successful
{total_failed}
Failed
{total_time:.1f}s
Total Time
{avg_time:.1f}s
Avg Per Image
""") # Start results container html_parts.append('
') # Process each image result for img_idx in sorted(results.keys()): img_result = results[img_idx] status = img_result.get('status', 'unknown') # Determine status icon and color if status == 'success': status_icon = '✓' status_color = '#27AE60' else: status_icon = '✗' status_color = '#E74C3C' # Build card card_html = f"""
{status_icon} Image {img_idx}
""" if status == 'success': result_data = img_result.get('result', {}) captions = result_data.get('captions', []) # Display captions for cap in captions: tone = cap.get('tone', 'Unknown').upper() caption_text = cap.get('caption', '') hashtags = cap.get('hashtags', []) card_html += f"""
{tone} Style
{caption_text}
{''.join([f'#{tag}' for tag in hashtags])}
""" # Display detected objects detections = result_data.get('detections', []) if detections: object_names = [det.get('class_name', 'unknown') for det in detections] card_html += f"""
Detected Objects: {', '.join(object_names)}
""" # Display detected brands brands = result_data.get('brands', []) if brands: brand_names = [ brand[0] if isinstance(brand, tuple) else brand for brand in brands ] card_html += f"""
Detected Brands: {', '.join(brand_names)}
""" else: # Display error information error = img_result.get('error', {}) error_type = error.get('type', 'Unknown Error') error_message = error.get('message', 'No error message available') card_html += f"""
{error_type}
{error_message}
""" card_html += """
""" html_parts.append(card_html) # Close results container html_parts.append('
') return ''.join(html_parts) def create_export_panel_html(self) -> str: """ Create HTML for export panel with download buttons. Returns: Formatted HTML string for export panel """ return """
📥 Export Batch Results
""" print("✓ UIManager (V5 with Batch Processing Support) defined")