feat(app): show generation progress and rename app heading
- Disable the run button and show a "Генерация…" status while a request is processing, then re-enable it. Repeated generations previously gave no visible feedback once the model was cached, so it was unclear whether a request was running. - Append elapsed time to the final status so identical re-runs differ visibly. - Rename the H1 heading and browser/tab title to "генератор аккордовых последовательностей". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import tempfile
|
||||
from dataclasses import replace
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from time import perf_counter
|
||||
from uuid import uuid4
|
||||
|
||||
import gradio as gr
|
||||
@@ -106,6 +107,7 @@ def generate(
|
||||
tempo: int,
|
||||
):
|
||||
"""Run one generation and return (status, bar grid, .chord path, .mid path)."""
|
||||
t0 = perf_counter()
|
||||
try:
|
||||
model = _load_model(checkpoint)
|
||||
except Exception as exc: # noqa: BLE001 — surface any load error to the UI
|
||||
@@ -160,15 +162,37 @@ def generate(
|
||||
write_chord_file(period, chord_path)
|
||||
chord_file_to_midi(chord_path, midi_path, tempo=int(tempo))
|
||||
|
||||
elapsed = perf_counter() - t0
|
||||
status = (
|
||||
f"✅ Готово — {len(period.bars)} тактов · {target_key} · "
|
||||
f"модель: {checkpoint} · seed: {seed_val if seed_val is not None else 'random'}"
|
||||
f"модель: {checkpoint} · seed: {seed_val if seed_val is not None else 'random'} · "
|
||||
f"{elapsed:.2f} с"
|
||||
)
|
||||
if truncated:
|
||||
status += f" · обрезано до {MAX_PERIOD_BARS} тактов (период ≤ 16)"
|
||||
return status, _format_bars(period), str(chord_path), str(midi_path)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Button-state helpers — give immediate, persistent feedback while generating.
|
||||
# Gradio's built-in spinner barely flashes once the model is cached, so we also
|
||||
# disable the button and show a "generating" status until the work completes.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _begin_generation():
|
||||
"""Show a busy state the instant the button is clicked (runs before generate)."""
|
||||
return (
|
||||
gr.update(value="⏳ Генерация…", interactive=False), # run button
|
||||
"⏳ Генерация…", # status message
|
||||
"", # clear the previous grid
|
||||
)
|
||||
|
||||
|
||||
def _end_generation():
|
||||
"""Restore the run button after generation finishes (success or handled error)."""
|
||||
return gr.update(value="Сгенерировать", interactive=True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Russian instructions (rendered inline)
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -220,9 +244,9 @@ def build_ui() -> gr.Blocks:
|
||||
checkpoints[0] if checkpoints else "finetuned"
|
||||
)
|
||||
|
||||
with gr.Blocks(title="hamori — генератор гармонии") as demo:
|
||||
with gr.Blocks(title="hamori — генератор аккордовых последовательностей") as demo:
|
||||
gr.Markdown(
|
||||
"# hamori 🎶 — генератор гармонических периодов\n"
|
||||
"# hamori 🎶 — генератор аккордовых последовательностей\n"
|
||||
"Заполните форму и нажмите **Сгенерировать**. "
|
||||
"Подробности — в разделе «Инструкция» внизу."
|
||||
)
|
||||
@@ -255,7 +279,7 @@ def build_ui() -> gr.Blocks:
|
||||
subdivision = gr.Radio([4, 8], value=4, label="Subdivision")
|
||||
|
||||
with gr.Row():
|
||||
auto_bars = gr.Checkbox(value=False, label="Авто (длина сама)")
|
||||
auto_bars = gr.Checkbox(value=False, label="Авто")
|
||||
n_bars = gr.Slider(4, 16, value=8, step=1, label="Число тактов")
|
||||
|
||||
with gr.Accordion("Сэмплирование", open=True):
|
||||
@@ -290,6 +314,10 @@ def build_ui() -> gr.Blocks:
|
||||
gr.Markdown(INSTRUCTIONS_RU)
|
||||
|
||||
run.click(
|
||||
fn=_begin_generation,
|
||||
inputs=None,
|
||||
outputs=[run, status, bars_out],
|
||||
).then(
|
||||
fn=generate,
|
||||
inputs=[
|
||||
checkpoint, mode, key, style, function, time, subdivision,
|
||||
@@ -297,6 +325,10 @@ def build_ui() -> gr.Blocks:
|
||||
tonic_anchor, prefix_text, seed, tempo,
|
||||
],
|
||||
outputs=[status, bars_out, chord_file, midi_file],
|
||||
).then(
|
||||
fn=_end_generation,
|
||||
inputs=None,
|
||||
outputs=[run],
|
||||
)
|
||||
|
||||
return demo
|
||||
|
||||
Reference in New Issue
Block a user