Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files
backend/media_analysis/public_routes.py
CHANGED
|
@@ -10,6 +10,8 @@ import time
|
|
| 10 |
from collections import defaultdict, deque
|
| 11 |
from threading import Lock, BoundedSemaphore
|
| 12 |
from flask import Blueprint, jsonify, request
|
|
|
|
|
|
|
| 13 |
from .figure_analysis import analyze_media_question, MediaSelectionError
|
| 14 |
from .vision_client import VisionConfigurationError
|
| 15 |
|
|
@@ -118,12 +120,30 @@ def media_analyze_public():
|
|
| 118 |
sources = result.get("sources") or result.get("source_identifiers") or []
|
| 119 |
if len(sources) != 1:
|
| 120 |
return jsonify({"error": "Media source mismatch: expected exactly one source"}), 502
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
if
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
# Do not send large duplicate tabular records: CSV already carries the data.
|
| 128 |
result.pop("structured_data", None)
|
| 129 |
if "answer" in result:
|
|
|
|
| 10 |
from collections import defaultdict, deque
|
| 11 |
from threading import Lock, BoundedSemaphore
|
| 12 |
from flask import Blueprint, jsonify, request
|
| 13 |
+
from pathlib import PurePosixPath
|
| 14 |
+
from urllib.parse import unquote
|
| 15 |
from .figure_analysis import analyze_media_question, MediaSelectionError
|
| 16 |
from .vision_client import VisionConfigurationError
|
| 17 |
|
|
|
|
| 120 |
sources = result.get("sources") or result.get("source_identifiers") or []
|
| 121 |
if len(sources) != 1:
|
| 122 |
return jsonify({"error": "Media source mismatch: expected exactly one source"}), 502
|
| 123 |
+
# Gallery selections are authorized by a precise image filename which
|
| 124 |
+
# prepare_media_evidence already resolved against this paper's manifest.
|
| 125 |
+
# Preserve its original label even if it differs from the gallery's
|
| 126 |
+
# display number. This is especially important when source PDFs have
|
| 127 |
+
# duplicated printed table numbers or inconsistent extraction labels.
|
| 128 |
+
source = sources[0]
|
| 129 |
+
if media_image:
|
| 130 |
+
source_url = str(source.get("image_url") or "")
|
| 131 |
+
image_returned = PurePosixPath(unquote(source_url).split("?", 1)[0]).name
|
| 132 |
+
if image_returned != media_image:
|
| 133 |
+
return jsonify({"error": "Media source mismatch: selected image differs from the returned image"}), 502
|
| 134 |
+
else:
|
| 135 |
+
# Typed requests have no unique image: require the returned
|
| 136 |
+
# manifest label to match the explicitly requested number.
|
| 137 |
+
src_label = str(source.get("label") or "")
|
| 138 |
+
src_match = re.search(r"\b(fig(?:ure)?|table)[\s_.-]*0*(\d+)\b", src_label, re.I)
|
| 139 |
+
if (not src_match or
|
| 140 |
+
("table" if src_match.group(1).lower() == "table" else "figure") != requested_kind or
|
| 141 |
+
int(src_match.group(2)) != requested_number):
|
| 142 |
+
return jsonify({"error": "Media source mismatch: requested and returned labels differ"}), 502
|
| 143 |
+
# Tell the frontend which image was validated. It should not re-apply
|
| 144 |
+
# a display-label check for exact gallery selections.
|
| 145 |
+
if media_image:
|
| 146 |
+
result["selected_media_image"] = media_image
|
| 147 |
# Do not send large duplicate tabular records: CSV already carries the data.
|
| 148 |
result.pop("structured_data", None)
|
| 149 |
if "answer" in result:
|