1ripon1's picture
Upload folder using huggingface_hub
7344bef verified
Raw
History Blame Contribute Delete
6.35 kB
from __future__ import annotations
import html
import time
from shared.api import extract_status_phase_label
def phase_label_from_status(status: str = "") -> str:
return extract_status_phase_label(status)
def phase_label_from_update(update=None, *, status: str = "", phase: str = "", raw_phase: str = "") -> str:
status_phase = phase_label_from_status(status or getattr(update, "status", ""))
raw_phase_text = str(raw_phase or getattr(update, "raw_phase", "") or phase or "").strip()
if len(status_phase) > 0:
return status_phase
return raw_phase_text
def _format_elapsed(seconds: float | None) -> str:
if seconds is None:
return "--"
total_seconds = int(round(float(seconds)))
if total_seconds < 0:
total_seconds = 0
hours, rem = divmod(total_seconds, 3600)
minutes, seconds_only = divmod(rem, 60)
return f"{hours:02d}:{minutes:02d}:{seconds_only:02d}" if hours > 0 else f"{minutes:02d}:{seconds_only:02d}"
class ChunkCallbacks:
def __init__(self) -> None:
self.phase_label = "Queued in WanGP..."
self.status_text = "Queued in WanGP..."
self.current_step = None
self.total_steps = None
self._last_explicit_status_at = 0.0
def on_status(self, status):
status_text = str(status or "").strip()
if len(status_text) == 0:
return
self.status_text = status_text
status_phase = phase_label_from_status(self.status_text)
if len(status_phase) > 0:
if status_phase != self.phase_label:
self.current_step = None
self.total_steps = None
self.phase_label = status_phase
self._last_explicit_status_at = time.time()
def on_progress(self, update):
incoming_status = str(getattr(update, "status", "") or "").strip()
incoming_phase = phase_label_from_update(update, status=incoming_status or self.status_text)
incoming_step = getattr(update, "current_step", None)
incoming_total = getattr(update, "total_steps", None)
if time.time() - self._last_explicit_status_at <= 1.0 and len(self.phase_label) > 0 and len(incoming_phase) > 0 and incoming_phase.lower() != self.phase_label.lower() and incoming_step is None:
return
if len(incoming_status) > 0:
self.status_text = incoming_status
if len(incoming_phase) > 0:
self.phase_label = incoming_phase
self.current_step = incoming_step
self.total_steps = incoming_total
def render_chunk_status_html(total_chunks: int, completed_chunks: int, current_chunk: int, phase_label: str, status_text: str, *, continued: bool = False, phase_current_step=None, phase_total_steps=None, elapsed_seconds: float | None = None, eta_seconds: float | None = None, prefer_status_phase: bool = False) -> str:
total_chunks = int(total_chunks)
completed_chunks = int(completed_chunks)
current_chunk = int(current_chunk)
if total_chunks > 0:
top_ratio = completed_chunks / total_chunks
chunks_text = f"{completed_chunks} / {total_chunks}"
else:
top_ratio = 0.0
chunks_text = "- / -"
top_width = f"{100.0 * top_ratio:.2f}%"
raw_status_text = status_text.strip()
raw_phase_text = phase_label.strip()
if prefer_status_phase:
derived_phase = phase_label_from_status(raw_status_text)
if len(derived_phase) > 0:
raw_phase_text = derived_phase
phase_html = html.escape(raw_phase_text or "Queued in WanGP...")
status_html = html.escape(raw_status_text or raw_phase_text or "")
continued_suffix = " (Continued)" if continued else ""
has_phase_progress = phase_current_step is not None and phase_total_steps is not None and phase_total_steps > 0
phase_ratio = float(phase_current_step) / float(phase_total_steps) if has_phase_progress else None
phase_width = f"{100.0 * phase_ratio:.2f}%" if phase_ratio is not None else "0%"
phase_suffix = f" ({phase_current_step} / {phase_total_steps})" if has_phase_progress else ""
elapsed_html = html.escape(_format_elapsed(elapsed_seconds))
eta_html = html.escape(_format_elapsed(eta_seconds))
normalized_phase = raw_phase_text.lower()
normalized_status = raw_status_text
show_status_line = (not prefer_status_phase) and len(normalized_status) > 0 and (len(normalized_phase) == 0 or normalized_phase not in normalized_status.lower())
status_line_html = f"<div style='font-size:0.9em;color:#4b5563'>{status_html}</div>" if show_status_line else ""
return (
"<div style='display:flex;flex-direction:column;gap:8px'>"
f"<div style='font-weight:600'>Chunks Processed: {chunks_text}{continued_suffix}</div>"
"<div style='height:12px;border-radius:999px;background:#d7dce3;overflow:hidden'>"
f"<div style='height:100%;width:{top_width};background:linear-gradient(90deg,#2f7de1,#5db0ff)'></div>"
"</div>"
f"<div style='font-size:0.95em'><b>Phase:</b> {phase_html}{phase_suffix}</div>"
"<div style='height:12px;border-radius:999px;background:#d7dce3;overflow:hidden'>"
f"<div style='height:100%;width:{phase_width};background:linear-gradient(90deg,#e37a2f,#ffb05d)'></div>"
"</div>"
f"<div style='font-size:0.9em;color:#4b5563'><b>Elapsed:</b> {elapsed_html} <span style='padding-left:12px'><b>ETA:</b> {eta_html}</span></div>"
f"{status_line_html}"
"</div>"
)
def render_output_file_html(output_path: str) -> str:
value = html.escape(output_path, quote=False)
return (
"<div style='display:flex;flex-direction:column;gap:6px'>"
"<div style='font-size:var(--block-label-text-size);font-weight:var(--block-label-text-weight);line-height:var(--line-sm)'>Output File</div>"
f"<textarea readonly onclick='this.select()' spellcheck='false' rows='1' "
"style='width:100%;min-height:35.64px;resize:none;overflow:hidden;padding:calc(8px * var(--wangp-ui-scale)) calc(12px * var(--wangp-ui-scale));"
"border:1px solid var(--input-border-color);border-radius:var(--input-radius);background:var(--input-background-fill);color:var(--body-text-color);"
"font:inherit;line-height:1.5;box-sizing:border-box'>"
f"{value}</textarea>"
"</div>"
)