Spaces:
Sleeping
Sleeping
Pointf5ive commited on
Commit ·
74365bc
1
Parent(s): d149161
fix: support DOCX manuscript uploads in dashboard and codex extractor
Browse files- app.py +5 -5
- src/codex_extractor.py +24 -4
app.py
CHANGED
|
@@ -2597,7 +2597,7 @@ def run_codex_extraction(
|
|
| 2597 |
"""
|
| 2598 |
if file_obj is None:
|
| 2599 |
return (
|
| 2600 |
-
"No file uploaded. Please upload a .txt or .pdf file.",
|
| 2601 |
"",
|
| 2602 |
"ERROR: No file uploaded.",
|
| 2603 |
)
|
|
@@ -2814,7 +2814,7 @@ def analyze_manuscript_for_dashboard(file_obj, active_path: str):
|
|
| 2814 |
"""
|
| 2815 |
file_path = _extract_uploaded_path(file_obj)
|
| 2816 |
if not file_path:
|
| 2817 |
-
raise gr.Error("Upload a manuscript (.txt or .pdf) first.")
|
| 2818 |
|
| 2819 |
stem = Path(file_path).stem.strip() or "Unknown Author"
|
| 2820 |
author_name = stem.replace("_", " ")[:120]
|
|
@@ -2922,8 +2922,8 @@ with gr.Blocks(title="TOTEM Studio") as demo:
|
|
| 2922 |
"Upload manuscript here to run extraction and refresh workbook scoring context."
|
| 2923 |
)
|
| 2924 |
dashboard_manuscript_file = gr.File(
|
| 2925 |
-
label="Manuscript (.txt or .pdf)",
|
| 2926 |
-
file_types=[".txt", ".pdf"],
|
| 2927 |
type="filepath",
|
| 2928 |
)
|
| 2929 |
dashboard_manuscript_analyze = gr.Button(
|
|
@@ -3015,7 +3015,7 @@ with gr.Blocks(title="TOTEM Studio") as demo:
|
|
| 3015 |
)
|
| 3016 |
codex_file = gr.File(
|
| 3017 |
label="Upload Text or PDF",
|
| 3018 |
-
file_types=[".txt", ".pdf"],
|
| 3019 |
type="filepath",
|
| 3020 |
)
|
| 3021 |
with gr.Row():
|
|
|
|
| 2597 |
"""
|
| 2598 |
if file_obj is None:
|
| 2599 |
return (
|
| 2600 |
+
"No file uploaded. Please upload a .txt, .docx, or .pdf file.",
|
| 2601 |
"",
|
| 2602 |
"ERROR: No file uploaded.",
|
| 2603 |
)
|
|
|
|
| 2814 |
"""
|
| 2815 |
file_path = _extract_uploaded_path(file_obj)
|
| 2816 |
if not file_path:
|
| 2817 |
+
raise gr.Error("Upload a manuscript (.txt, .docx, or .pdf) first.")
|
| 2818 |
|
| 2819 |
stem = Path(file_path).stem.strip() or "Unknown Author"
|
| 2820 |
author_name = stem.replace("_", " ")[:120]
|
|
|
|
| 2922 |
"Upload manuscript here to run extraction and refresh workbook scoring context."
|
| 2923 |
)
|
| 2924 |
dashboard_manuscript_file = gr.File(
|
| 2925 |
+
label="Manuscript (.txt, .docx, or .pdf)",
|
| 2926 |
+
file_types=[".txt", ".docx", ".pdf"],
|
| 2927 |
type="filepath",
|
| 2928 |
)
|
| 2929 |
dashboard_manuscript_analyze = gr.Button(
|
|
|
|
| 3015 |
)
|
| 3016 |
codex_file = gr.File(
|
| 3017 |
label="Upload Text or PDF",
|
| 3018 |
+
file_types=[".txt", ".docx", ".pdf"],
|
| 3019 |
type="filepath",
|
| 3020 |
)
|
| 3021 |
with gr.Row():
|
src/codex_extractor.py
CHANGED
|
@@ -87,6 +87,7 @@ import math
|
|
| 87 |
import os
|
| 88 |
import re
|
| 89 |
import string
|
|
|
|
| 90 |
from collections import Counter
|
| 91 |
from pathlib import Path
|
| 92 |
from shutil import which
|
|
@@ -473,14 +474,33 @@ def extract_text_from_file(
|
|
| 473 |
end_page: int | None = None,
|
| 474 |
) -> tuple[str, str, list[dict]]:
|
| 475 |
"""
|
| 476 |
-
Extract text from PDF or plain text file.
|
| 477 |
|
| 478 |
Returns (story_text, raw_text, page_trace).
|
| 479 |
For plain text files page_trace contains a single synthetic entry.
|
| 480 |
"""
|
| 481 |
path = Path(file_path)
|
| 482 |
-
|
|
|
|
| 483 |
return extract_text_from_pdf(path, start_page=start_page, end_page=end_page)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
else:
|
| 485 |
content = path.read_text(encoding="utf-8", errors="replace")
|
| 486 |
wc = _word_count(content)
|
|
@@ -1805,7 +1825,7 @@ def process_upload(
|
|
| 1805 |
Entry point for Gradio interface.
|
| 1806 |
|
| 1807 |
Args:
|
| 1808 |
-
file_path: Path to uploaded PDF or text file.
|
| 1809 |
author_name: Author's full name.
|
| 1810 |
author_id: Codex author ID.
|
| 1811 |
works_sampled: Title of the uploaded work (user-supplied only;
|
|
@@ -1913,4 +1933,4 @@ if __name__ == "__main__":
|
|
| 1913 |
debug_output_dir="/tmp/codex_debug",
|
| 1914 |
)
|
| 1915 |
print(format_fingerprint_report(fp))
|
| 1916 |
-
print("\nDebug artefacts written to:", fp.get("Debug_Artefacts", {}))
|
|
|
|
| 87 |
import os
|
| 88 |
import re
|
| 89 |
import string
|
| 90 |
+
import zipfile
|
| 91 |
from collections import Counter
|
| 92 |
from pathlib import Path
|
| 93 |
from shutil import which
|
|
|
|
| 474 |
end_page: int | None = None,
|
| 475 |
) -> tuple[str, str, list[dict]]:
|
| 476 |
"""
|
| 477 |
+
Extract text from PDF, DOCX, or plain text file.
|
| 478 |
|
| 479 |
Returns (story_text, raw_text, page_trace).
|
| 480 |
For plain text files page_trace contains a single synthetic entry.
|
| 481 |
"""
|
| 482 |
path = Path(file_path)
|
| 483 |
+
suffix = path.suffix.lower()
|
| 484 |
+
if suffix == ".pdf":
|
| 485 |
return extract_text_from_pdf(path, start_page=start_page, end_page=end_page)
|
| 486 |
+
if suffix == ".docx":
|
| 487 |
+
with zipfile.ZipFile(path) as zf:
|
| 488 |
+
xml = zf.read("word/document.xml").decode("utf-8", errors="replace")
|
| 489 |
+
xml = re.sub(r"<w:tab\\s*/>", "\t", xml)
|
| 490 |
+
xml = re.sub(r"</w:p>", "\n", xml)
|
| 491 |
+
content = re.sub(r"<[^>]+>", "", xml)
|
| 492 |
+
content = content.replace("&", "&").replace("<", "<").replace(">", ">")
|
| 493 |
+
content = re.sub(r"\n{3,}", "\n\n", content).strip()
|
| 494 |
+
wc = _word_count(content)
|
| 495 |
+
page_trace = [{
|
| 496 |
+
"page_number": 1,
|
| 497 |
+
"raw_word_count": wc,
|
| 498 |
+
"cleaned_word_count": wc,
|
| 499 |
+
"classification": "story",
|
| 500 |
+
"included": True,
|
| 501 |
+
"skip_reason": "",
|
| 502 |
+
}]
|
| 503 |
+
return content, content, page_trace
|
| 504 |
else:
|
| 505 |
content = path.read_text(encoding="utf-8", errors="replace")
|
| 506 |
wc = _word_count(content)
|
|
|
|
| 1825 |
Entry point for Gradio interface.
|
| 1826 |
|
| 1827 |
Args:
|
| 1828 |
+
file_path: Path to uploaded PDF, DOCX, or text file.
|
| 1829 |
author_name: Author's full name.
|
| 1830 |
author_id: Codex author ID.
|
| 1831 |
works_sampled: Title of the uploaded work (user-supplied only;
|
|
|
|
| 1933 |
debug_output_dir="/tmp/codex_debug",
|
| 1934 |
)
|
| 1935 |
print(format_fingerprint_report(fp))
|
| 1936 |
+
print("\nDebug artefacts written to:", fp.get("Debug_Artefacts", {}))
|