Spaces:
Sleeping
Sleeping
Claude commited on
Commit ·
c3a052e
1
Parent(s): 20968a7
refactor: strip ingest to bare minimum — PDF + story pages + one button
Browse files- smoke_signal_tab.py +28 -38
smoke_signal_tab.py
CHANGED
|
@@ -2815,8 +2815,8 @@ def smoke_signal_tab():
|
|
| 2815 |
with gr.TabItem("① Ingest", id="ss-ingest") as ingest_tab:
|
| 2816 |
gr.HTML("""<div class="ss-panel-header" style="padding:20px 0 0 0">
|
| 2817 |
<div class="ss-panel-icon">📥</div>
|
| 2818 |
-
<div><p class="ss-panel-title">
|
| 2819 |
-
<p class="ss-panel-sub">Drop PDF ·
|
| 2820 |
</div>""")
|
| 2821 |
|
| 2822 |
ingest_status = gr.HTML(_ingest_status_html("idle"))
|
|
@@ -2830,42 +2830,26 @@ def smoke_signal_tab():
|
|
| 2830 |
type="filepath",
|
| 2831 |
)
|
| 2832 |
with gr.Column(scale=1):
|
| 2833 |
-
|
| 2834 |
-
label="②
|
| 2835 |
-
|
| 2836 |
-
value="unknown",
|
| 2837 |
-
)
|
| 2838 |
-
book_code_input = gr.Textbox(
|
| 2839 |
-
label="Book Code (3 letters)",
|
| 2840 |
-
placeholder="e.g. grf",
|
| 2841 |
lines=1,
|
| 2842 |
)
|
| 2843 |
-
|
| 2844 |
-
label="
|
| 2845 |
-
placeholder="e.g.
|
| 2846 |
lines=1,
|
| 2847 |
)
|
| 2848 |
-
ingest_notes = gr.Textbox(label="Notes", placeholder="Source, edition, etc.", lines=2)
|
| 2849 |
|
| 2850 |
-
|
| 2851 |
-
|
| 2852 |
-
|
| 2853 |
-
|
| 2854 |
-
|
| 2855 |
-
|
| 2856 |
-
scope_exclude = gr.Textbox(
|
| 2857 |
-
label="Story Pages Exclude",
|
| 2858 |
-
placeholder="e.g. 1,2,3,17,25",
|
| 2859 |
-
scale=2,
|
| 2860 |
-
)
|
| 2861 |
-
scope_title = gr.Textbox(
|
| 2862 |
-
label="Safe Book Title",
|
| 2863 |
-
placeholder="auto-filled from filename",
|
| 2864 |
-
scale=2,
|
| 2865 |
-
)
|
| 2866 |
|
| 2867 |
run_pipeline_btn = gr.Button(
|
| 2868 |
-
"
|
| 2869 |
elem_classes=["ss-btn-run"],
|
| 2870 |
)
|
| 2871 |
pipeline_done = gr.State(0)
|
|
@@ -2906,20 +2890,26 @@ def smoke_signal_tab():
|
|
| 2906 |
)
|
| 2907 |
|
| 2908 |
# ── Auto-populate: PDF filename → safe book title ─────────────
|
| 2909 |
-
def
|
|
|
|
|
|
|
| 2910 |
if not files:
|
| 2911 |
-
return ""
|
| 2912 |
first = files[0] if isinstance(files, list) else files
|
| 2913 |
name = Path(first).stem if isinstance(first, str) else ""
|
| 2914 |
-
# slugify: lowercase, replace spaces/underscores with hyphens, strip non-alphanum
|
| 2915 |
-
import re as _re
|
| 2916 |
slug = _re.sub(r"[^a-z0-9]+", "-", name.lower()).strip("-")
|
| 2917 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2918 |
|
| 2919 |
pdf_upload.change(
|
| 2920 |
-
|
| 2921 |
inputs=[pdf_upload],
|
| 2922 |
-
outputs=[scope_title],
|
| 2923 |
)
|
| 2924 |
|
| 2925 |
# Main pipeline button — does everything
|
|
|
|
| 2815 |
with gr.TabItem("① Ingest", id="ss-ingest") as ingest_tab:
|
| 2816 |
gr.HTML("""<div class="ss-panel-header" style="padding:20px 0 0 0">
|
| 2817 |
<div class="ss-panel-icon">📥</div>
|
| 2818 |
+
<div><p class="ss-panel-title">Text Extraction</p>
|
| 2819 |
+
<p class="ss-panel-sub">Drop PDF · Define story pages · Extract clean text for author fingerprinting</p></div>
|
| 2820 |
</div>""")
|
| 2821 |
|
| 2822 |
ingest_status = gr.HTML(_ingest_status_html("idle"))
|
|
|
|
| 2830 |
type="filepath",
|
| 2831 |
)
|
| 2832 |
with gr.Column(scale=1):
|
| 2833 |
+
scope_include = gr.Textbox(
|
| 2834 |
+
label="② Story Pages (include)",
|
| 2835 |
+
placeholder="e.g. 7-27 or 7,8,9,11-27 or all",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2836 |
lines=1,
|
| 2837 |
)
|
| 2838 |
+
scope_exclude = gr.Textbox(
|
| 2839 |
+
label="Story Pages (exclude)",
|
| 2840 |
+
placeholder="e.g. 1,2,3,17,25 — title/copyright pages",
|
| 2841 |
lines=1,
|
| 2842 |
)
|
|
|
|
| 2843 |
|
| 2844 |
+
# Hidden fields — auto-populated, not shown to user
|
| 2845 |
+
rights_dd = gr.Dropdown(choices=["licensed-owned"], value="licensed-owned", visible=False)
|
| 2846 |
+
book_code_input = gr.Textbox(visible=False, value="")
|
| 2847 |
+
pub_year_input = gr.Textbox(visible=False, value="")
|
| 2848 |
+
ingest_notes = gr.Textbox(visible=False, value="")
|
| 2849 |
+
scope_title = gr.Textbox(visible=False, value="")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2850 |
|
| 2851 |
run_pipeline_btn = gr.Button(
|
| 2852 |
+
"③ Extract Text →",
|
| 2853 |
elem_classes=["ss-btn-run"],
|
| 2854 |
)
|
| 2855 |
pipeline_done = gr.State(0)
|
|
|
|
| 2890 |
)
|
| 2891 |
|
| 2892 |
# ── Auto-populate: PDF filename → safe book title ─────────────
|
| 2893 |
+
def _auto_fill_from_upload(files):
|
| 2894 |
+
"""Auto-generate book code, year, and safe title from filename."""
|
| 2895 |
+
import re as _re
|
| 2896 |
if not files:
|
| 2897 |
+
return "", "", ""
|
| 2898 |
first = files[0] if isinstance(files, list) else files
|
| 2899 |
name = Path(first).stem if isinstance(first, str) else ""
|
|
|
|
|
|
|
| 2900 |
slug = _re.sub(r"[^a-z0-9]+", "-", name.lower()).strip("-")
|
| 2901 |
+
# Extract year if present in filename (e.g. "gruffalo-1999")
|
| 2902 |
+
year_match = _re.search(r"(19|20)\d{2}", name)
|
| 2903 |
+
year = year_match.group(0) if year_match else ""
|
| 2904 |
+
# Book code: first 3 alpha chars of filename
|
| 2905 |
+
alpha = _re.sub(r"[^a-z]", "", name.lower())
|
| 2906 |
+
code = alpha[:3] if len(alpha) >= 3 else alpha.ljust(3, "x")
|
| 2907 |
+
return code, year, slug
|
| 2908 |
|
| 2909 |
pdf_upload.change(
|
| 2910 |
+
_auto_fill_from_upload,
|
| 2911 |
inputs=[pdf_upload],
|
| 2912 |
+
outputs=[book_code_input, pub_year_input, scope_title],
|
| 2913 |
)
|
| 2914 |
|
| 2915 |
# Main pipeline button — does everything
|