Spaces:
Running
Running
Upload app.py
Browse files
app.py
CHANGED
|
@@ -281,6 +281,18 @@ def delete_sample(sample_id):
|
|
| 281 |
conn.execute("DELETE FROM samples WHERE id = ?", (sample_id,))
|
| 282 |
|
| 283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
# --------------------------------------------------------------------------- #
|
| 285 |
# Ratings
|
| 286 |
# --------------------------------------------------------------------------- #
|
|
@@ -490,6 +502,9 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 490 |
|
| 491 |
rate_audio = gr.Audio(label="βΆ Listen to the full sample",
|
| 492 |
type="filepath", interactive=False)
|
|
|
|
|
|
|
|
|
|
| 493 |
gr.Markdown(
|
| 494 |
"Use headphones in a quiet room. "
|
| 495 |
"**1** Very Poor Β· **2** Poor Β· **3** Fair Β· **4** Good Β· **5** Excellent",
|
|
@@ -554,6 +569,16 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 554 |
allow_custom_value=True, scale=3)
|
| 555 |
del_btn = gr.Button("Delete selected", variant="stop", scale=0, size="sm")
|
| 556 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
gr.Markdown("### Users")
|
| 558 |
refresh_users_btn = gr.Button("Refresh users", size="sm")
|
| 559 |
users_tbl = gr.Dataframe(
|
|
@@ -646,18 +671,19 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 646 |
|
| 647 |
def load_sample(sess, sample_id):
|
| 648 |
if not sample_id:
|
| 649 |
-
return (None, None, *[None] * len(CRITERIA_KEYS), "")
|
| 650 |
with get_conn() as conn:
|
| 651 |
row = conn.execute("SELECT * FROM samples WHERE id=?", (sample_id,)).fetchone()
|
| 652 |
if not row:
|
| 653 |
-
return (None, None, *[None] * len(CRITERIA_KEYS), "")
|
|
|
|
| 654 |
existing = get_rating(sess["id"], sample_id) if sess else None
|
| 655 |
scores = [existing[k] if existing else None for k in CRITERIA_KEYS]
|
| 656 |
comments = existing["comments"] if existing else ""
|
| 657 |
-
return (row["file_path"], sample_id, *scores, comments)
|
| 658 |
rate_sample.change(
|
| 659 |
load_sample, [session, rate_sample],
|
| 660 |
-
[rate_audio, current_sample, *rate_outputs, rate_comments],
|
| 661 |
)
|
| 662 |
|
| 663 |
def go_next_unrated(sess, language_id):
|
|
@@ -742,11 +768,11 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 742 |
|
| 743 |
def admin_upload(sess, language_id, files, model, is_ref, transcript):
|
| 744 |
if not sess or sess["role"] != "admin":
|
| 745 |
-
return "β Admin only.", _samples_table(), gr.update()
|
| 746 |
if not language_id:
|
| 747 |
-
return "β Choose a language first.", _samples_table(), gr.update()
|
| 748 |
if not files:
|
| 749 |
-
return "β No files selected.", _samples_table(), gr.update()
|
| 750 |
count = 0
|
| 751 |
for f in files:
|
| 752 |
path = f if isinstance(f, str) else getattr(f, "name", None)
|
|
@@ -754,23 +780,44 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 754 |
add_sample(language_id, path, model_name=model, is_reference=is_ref, transcript=transcript)
|
| 755 |
count += 1
|
| 756 |
except Exception as e: # noqa
|
|
|
|
| 757 |
return (f"β Error on a file: {e}", _samples_table(),
|
| 758 |
-
gr.update(choices=
|
|
|
|
| 759 |
return (f"β
Uploaded {count} sample(s).", _samples_table(),
|
| 760 |
-
gr.update(choices=
|
| 761 |
up_btn.click(admin_upload, [session, up_lang, up_files, up_model, up_isref, up_transcript],
|
| 762 |
-
[up_msg, samples_tbl, del_sample])
|
| 763 |
|
| 764 |
def admin_delete_sample(sess, sid):
|
| 765 |
if not sess or sess["role"] != "admin":
|
| 766 |
-
return "β Admin only.", _samples_table(), gr.update()
|
| 767 |
if not sid:
|
|
|
|
| 768 |
return ("β Select a sample to delete.", _samples_table(),
|
| 769 |
-
gr.update(choices=
|
| 770 |
delete_sample(int(sid))
|
|
|
|
| 771 |
return (f"β
Deleted sample #{int(sid)} (and any ratings it had).", _samples_table(),
|
| 772 |
-
gr.update(choices=
|
| 773 |
-
del_btn.click(admin_delete_sample, [session, del_sample],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 774 |
|
| 775 |
# ---- Admin: users ----
|
| 776 |
def _users_table():
|
|
@@ -816,11 +863,12 @@ with gr.Blocks(title="Plotweaver AI β TTS MOS Evaluation",
|
|
| 816 |
return export_results(language_id)
|
| 817 |
export_btn.click(admin_export, [session, res_lang], [res_file])
|
| 818 |
|
| 819 |
-
# Populate admin tables +
|
| 820 |
li_btn.click(lambda s: (_languages_table(), _samples_table(), _users_table(),
|
|
|
|
| 821 |
gr.update(choices=_sample_delete_choices()))
|
| 822 |
-
if s and s["role"] == "admin" else ([], [], [], gr.update(choices=[])),
|
| 823 |
-
[session], [langs_tbl, samples_tbl, users_tbl, del_sample])
|
| 824 |
|
| 825 |
# Refresh language-dependent choices on every page load, so newly added
|
| 826 |
# languages appear in the signup form (and admin dropdowns) without a restart.
|
|
|
|
| 281 |
conn.execute("DELETE FROM samples WHERE id = ?", (sample_id,))
|
| 282 |
|
| 283 |
|
| 284 |
+
def set_sample_transcript(sample_id, transcript):
|
| 285 |
+
with get_conn() as conn:
|
| 286 |
+
conn.execute("UPDATE samples SET transcript = ? WHERE id = ?",
|
| 287 |
+
((transcript or "").strip(), sample_id))
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
def get_sample_transcript(sample_id):
|
| 291 |
+
with get_conn() as conn:
|
| 292 |
+
row = conn.execute("SELECT transcript FROM samples WHERE id = ?", (sample_id,)).fetchone()
|
| 293 |
+
return (row["transcript"] if row else "") or ""
|
| 294 |
+
|
| 295 |
+
|
| 296 |
# --------------------------------------------------------------------------- #
|
| 297 |
# Ratings
|
| 298 |
# --------------------------------------------------------------------------- #
|
|
|
|
| 502 |
|
| 503 |
rate_audio = gr.Audio(label="βΆ Listen to the full sample",
|
| 504 |
type="filepath", interactive=False)
|
| 505 |
+
rate_transcript = gr.Textbox(
|
| 506 |
+
label="π Reference text (what the speaker should be saying)",
|
| 507 |
+
interactive=False, lines=2, elem_id="ref-text")
|
| 508 |
gr.Markdown(
|
| 509 |
"Use headphones in a quiet room. "
|
| 510 |
"**1** Very Poor Β· **2** Poor Β· **3** Fair Β· **4** Good Β· **5** Excellent",
|
|
|
|
| 569 |
allow_custom_value=True, scale=3)
|
| 570 |
del_btn = gr.Button("Delete selected", variant="stop", scale=0, size="sm")
|
| 571 |
|
| 572 |
+
gr.Markdown("#### Reference text per sample")
|
| 573 |
+
gr.Markdown("Pick a sample to view its current reference text, edit it, and save. "
|
| 574 |
+
"This text is shown to reviewers beside the audio.")
|
| 575 |
+
with gr.Row():
|
| 576 |
+
tr_sample = gr.Dropdown(label="Sample", choices=[],
|
| 577 |
+
allow_custom_value=True, scale=2)
|
| 578 |
+
tr_text = gr.Textbox(label="Reference text", lines=2, scale=3)
|
| 579 |
+
tr_btn = gr.Button("Save text", scale=0, size="sm")
|
| 580 |
+
tr_msg = gr.Markdown()
|
| 581 |
+
|
| 582 |
gr.Markdown("### Users")
|
| 583 |
refresh_users_btn = gr.Button("Refresh users", size="sm")
|
| 584 |
users_tbl = gr.Dataframe(
|
|
|
|
| 671 |
|
| 672 |
def load_sample(sess, sample_id):
|
| 673 |
if not sample_id:
|
| 674 |
+
return (None, "", None, *[None] * len(CRITERIA_KEYS), "")
|
| 675 |
with get_conn() as conn:
|
| 676 |
row = conn.execute("SELECT * FROM samples WHERE id=?", (sample_id,)).fetchone()
|
| 677 |
if not row:
|
| 678 |
+
return (None, "", None, *[None] * len(CRITERIA_KEYS), "")
|
| 679 |
+
transcript = row["transcript"] or "β No reference text provided for this sample β"
|
| 680 |
existing = get_rating(sess["id"], sample_id) if sess else None
|
| 681 |
scores = [existing[k] if existing else None for k in CRITERIA_KEYS]
|
| 682 |
comments = existing["comments"] if existing else ""
|
| 683 |
+
return (row["file_path"], transcript, sample_id, *scores, comments)
|
| 684 |
rate_sample.change(
|
| 685 |
load_sample, [session, rate_sample],
|
| 686 |
+
[rate_audio, rate_transcript, current_sample, *rate_outputs, rate_comments],
|
| 687 |
)
|
| 688 |
|
| 689 |
def go_next_unrated(sess, language_id):
|
|
|
|
| 768 |
|
| 769 |
def admin_upload(sess, language_id, files, model, is_ref, transcript):
|
| 770 |
if not sess or sess["role"] != "admin":
|
| 771 |
+
return "β Admin only.", _samples_table(), gr.update(), gr.update()
|
| 772 |
if not language_id:
|
| 773 |
+
return "β Choose a language first.", _samples_table(), gr.update(), gr.update()
|
| 774 |
if not files:
|
| 775 |
+
return "β No files selected.", _samples_table(), gr.update(), gr.update()
|
| 776 |
count = 0
|
| 777 |
for f in files:
|
| 778 |
path = f if isinstance(f, str) else getattr(f, "name", None)
|
|
|
|
| 780 |
add_sample(language_id, path, model_name=model, is_reference=is_ref, transcript=transcript)
|
| 781 |
count += 1
|
| 782 |
except Exception as e: # noqa
|
| 783 |
+
ch = _sample_delete_choices()
|
| 784 |
return (f"β Error on a file: {e}", _samples_table(),
|
| 785 |
+
gr.update(choices=ch), gr.update(choices=ch))
|
| 786 |
+
ch = _sample_delete_choices()
|
| 787 |
return (f"β
Uploaded {count} sample(s).", _samples_table(),
|
| 788 |
+
gr.update(choices=ch, value=None), gr.update(choices=ch, value=None))
|
| 789 |
up_btn.click(admin_upload, [session, up_lang, up_files, up_model, up_isref, up_transcript],
|
| 790 |
+
[up_msg, samples_tbl, del_sample, tr_sample])
|
| 791 |
|
| 792 |
def admin_delete_sample(sess, sid):
|
| 793 |
if not sess or sess["role"] != "admin":
|
| 794 |
+
return "β Admin only.", _samples_table(), gr.update(), gr.update()
|
| 795 |
if not sid:
|
| 796 |
+
ch = _sample_delete_choices()
|
| 797 |
return ("β Select a sample to delete.", _samples_table(),
|
| 798 |
+
gr.update(choices=ch), gr.update(choices=ch))
|
| 799 |
delete_sample(int(sid))
|
| 800 |
+
ch = _sample_delete_choices()
|
| 801 |
return (f"β
Deleted sample #{int(sid)} (and any ratings it had).", _samples_table(),
|
| 802 |
+
gr.update(choices=ch, value=None), gr.update(choices=ch, value=None))
|
| 803 |
+
del_btn.click(admin_delete_sample, [session, del_sample],
|
| 804 |
+
[up_msg, samples_tbl, del_sample, tr_sample])
|
| 805 |
+
|
| 806 |
+
# ---- Admin: per-sample reference text ----
|
| 807 |
+
def load_transcript(sess, sid):
|
| 808 |
+
if not sess or sess["role"] != "admin" or not sid:
|
| 809 |
+
return ""
|
| 810 |
+
return get_sample_transcript(int(sid))
|
| 811 |
+
tr_sample.change(load_transcript, [session, tr_sample], [tr_text])
|
| 812 |
+
|
| 813 |
+
def save_transcript(sess, sid, text):
|
| 814 |
+
if not sess or sess["role"] != "admin":
|
| 815 |
+
return "β Admin only."
|
| 816 |
+
if not sid:
|
| 817 |
+
return "β Select a sample first."
|
| 818 |
+
set_sample_transcript(int(sid), text)
|
| 819 |
+
return f"β
Reference text saved for sample #{int(sid)}."
|
| 820 |
+
tr_btn.click(save_transcript, [session, tr_sample, tr_text], [tr_msg])
|
| 821 |
|
| 822 |
# ---- Admin: users ----
|
| 823 |
def _users_table():
|
|
|
|
| 863 |
return export_results(language_id)
|
| 864 |
export_btn.click(admin_export, [session, res_lang], [res_file])
|
| 865 |
|
| 866 |
+
# Populate admin tables + sample pickers right after an admin logs in.
|
| 867 |
li_btn.click(lambda s: (_languages_table(), _samples_table(), _users_table(),
|
| 868 |
+
gr.update(choices=_sample_delete_choices()),
|
| 869 |
gr.update(choices=_sample_delete_choices()))
|
| 870 |
+
if s and s["role"] == "admin" else ([], [], [], gr.update(choices=[]), gr.update(choices=[])),
|
| 871 |
+
[session], [langs_tbl, samples_tbl, users_tbl, del_sample, tr_sample])
|
| 872 |
|
| 873 |
# Refresh language-dependent choices on every page load, so newly added
|
| 874 |
# languages appear in the signup form (and admin dropdowns) without a restart.
|