Files
upscale-ui/src/ui/components/history_tab.py

209 lines
6.4 KiB
Python
Raw Normal View History

"""History gallery tab component."""
import logging
from pathlib import Path
from typing import Optional
import gradio as gr
from src.storage.history import history_manager, HistoryItem
logger = logging.getLogger(__name__)
def get_history_gallery() -> list[tuple[str, str]]:
"""Get history items for gallery display."""
items = history_manager.get_recent(limit=100)
gallery_items = []
for item in items:
# Use output path for display
output_path = Path(item.output_path)
if output_path.exists() and item.type == "image":
caption = f"{item.output_filename}\n{item.output_width}x{item.output_height}"
gallery_items.append((str(output_path), caption))
return gallery_items
def get_history_stats() -> str:
"""Get history statistics."""
stats = history_manager.get_statistics()
return (
f"**History Statistics**\n\n"
f"- Total Items: {stats['total_items']}\n"
f"- Images: {stats['images']}\n"
f"- Videos: {stats['videos']}\n"
f"- Total Processing Time: {stats['total_processing_time']/60:.1f} min\n"
f"- Total Input Size: {stats['total_input_size_mb']:.1f} MB\n"
f"- Total Output Size: {stats['total_output_size_mb']:.1f} MB"
)
def search_history(query: str) -> list[tuple[str, str]]:
"""Search history by filename."""
if not query:
return get_history_gallery()
items = history_manager.search(query)
gallery_items = []
for item in items:
output_path = Path(item.output_path)
if output_path.exists() and item.type == "image":
caption = f"{item.output_filename}\n{item.output_width}x{item.output_height}"
gallery_items.append((str(output_path), caption))
return gallery_items
def get_item_details(evt: gr.SelectData) -> tuple[Optional[tuple], str]:
"""Get details for selected history item."""
if evt.index is None:
return None, "Select an item to view details"
items = history_manager.get_recent(limit=100)
# Filter to only images (same as gallery)
image_items = [i for i in items if i.type == "image" and Path(i.output_path).exists()]
if evt.index >= len(image_items):
return None, "Item not found"
item = image_items[evt.index]
# Load images for slider
input_path = Path(item.input_path)
output_path = Path(item.output_path)
slider_images = None
if input_path.exists() and output_path.exists():
slider_images = (str(input_path), str(output_path))
# Format details
details = (
f"**{item.output_filename}**\n\n"
f"- **Type:** {item.type.title()}\n"
f"- **Model:** {item.model}\n"
f"- **Scale:** {item.scale}x\n"
f"- **Face Enhancement:** {'Yes' if item.face_enhance else 'No'}\n"
f"- **Input:** {item.input_width}x{item.input_height}\n"
f"- **Output:** {item.output_width}x{item.output_height}\n"
f"- **Processing Time:** {item.processing_time_seconds:.1f}s\n"
f"- **Input Size:** {item.input_size_bytes/1024:.1f} KB\n"
f"- **Output Size:** {item.output_size_bytes/1024:.1f} KB\n"
f"- **Created:** {item.created_at.strftime('%Y-%m-%d %H:%M')}"
)
return slider_images, details
def delete_selected(evt: gr.SelectData) -> tuple[list, str]:
"""Delete selected history item."""
if evt.index is None:
return get_history_gallery(), "No item selected"
items = history_manager.get_recent(limit=100)
image_items = [i for i in items if i.type == "image" and Path(i.output_path).exists()]
if evt.index >= len(image_items):
return get_history_gallery(), "Item not found"
item = image_items[evt.index]
history_manager.delete_item(item.id)
return get_history_gallery(), f"Deleted: {item.output_filename}"
def create_history_tab():
"""Create the history gallery tab component."""
with gr.Tab("History", id="history-tab"):
gr.Markdown("## Processing History")
with gr.Row():
# Search
search_box = gr.Textbox(
label="Search",
placeholder="Search by filename...",
scale=2,
)
filter_dropdown = gr.Dropdown(
choices=["All", "Images", "Videos"],
value="All",
label="Filter",
scale=1,
)
with gr.Row():
# Gallery
with gr.Column(scale=2):
gallery = gr.Gallery(
value=get_history_gallery(),
label="History",
columns=4,
object_fit="cover",
height=400,
allow_preview=True,
)
# Details panel
with gr.Column(scale=1):
stats_display = gr.Markdown(
get_history_stats(),
elem_classes=["info-card"],
)
# Selected item details
with gr.Row():
with gr.Column(scale=2):
try:
from gradio_imageslider import ImageSlider
comparison_slider = ImageSlider(
label="Before / After",
type="filepath",
)
except ImportError:
comparison_slider = gr.Image(
label="Selected Image",
type="filepath",
)
with gr.Column(scale=1):
item_details = gr.Markdown(
"Select an item to view details",
elem_classes=["info-card"],
)
with gr.Row():
download_btn = gr.Button("Download", variant="secondary")
delete_btn = gr.Button("Delete", variant="stop")
status_text = gr.Markdown("")
# Event handlers
search_box.change(
fn=search_history,
inputs=[search_box],
outputs=[gallery],
)
gallery.select(
fn=get_item_details,
outputs=[comparison_slider, item_details],
)
delete_btn.click(
fn=lambda: (get_history_gallery(), get_history_stats()),
outputs=[gallery, stats_display],
)
return {
"gallery": gallery,
"comparison_slider": comparison_slider,
"item_details": item_details,
"stats_display": stats_display,
}