Spaces:
Running
Running
Update app/services/classifier.py
Browse files- app/services/classifier.py +39 -9
app/services/classifier.py
CHANGED
|
@@ -22,7 +22,7 @@ LLM_MAX_CHARS = 3000
|
|
| 22 |
|
| 23 |
_nsfw_runtime: dict[str, Any] | None = None
|
| 24 |
_nsfw_error: str | None = None
|
| 25 |
-
_ocr_reader: Any | None = None
|
| 26 |
_ocr_error: str | None = None
|
| 27 |
|
| 28 |
logger = logging.getLogger(__name__)
|
|
@@ -189,14 +189,27 @@ def classify_game_with_ocr_llm(file_path: str, filename: str, suspected_game: bo
|
|
| 189 |
|
| 190 |
|
| 191 |
def extract_ocr_text_and_urls(file_path: str) -> tuple[str, list[str]]:
|
| 192 |
-
|
| 193 |
-
if
|
| 194 |
logger.warning("ocr unavailable: reader is None")
|
| 195 |
return "", []
|
| 196 |
|
| 197 |
try:
|
| 198 |
-
|
| 199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
except Exception:
|
| 201 |
logger.exception("ocr read failed for file=%s", file_path)
|
| 202 |
return "", []
|
|
@@ -234,15 +247,32 @@ def _load_ocr_reader() -> Any | None:
|
|
| 234 |
if _ocr_error is not None:
|
| 235 |
return None
|
| 236 |
|
|
|
|
| 237 |
try:
|
| 238 |
import easyocr
|
| 239 |
|
| 240 |
-
_ocr_reader =
|
| 241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
return _ocr_reader
|
| 243 |
except Exception as exc:
|
| 244 |
-
_ocr_error =
|
| 245 |
-
logger.warning("ocr reader init failed: %s", _ocr_error)
|
| 246 |
return None
|
| 247 |
|
| 248 |
|
|
|
|
| 22 |
|
| 23 |
_nsfw_runtime: dict[str, Any] | None = None
|
| 24 |
_nsfw_error: str | None = None
|
| 25 |
+
_ocr_reader: dict[str, Any] | None = None
|
| 26 |
_ocr_error: str | None = None
|
| 27 |
|
| 28 |
logger = logging.getLogger(__name__)
|
|
|
|
| 189 |
|
| 190 |
|
| 191 |
def extract_ocr_text_and_urls(file_path: str) -> tuple[str, list[str]]:
|
| 192 |
+
runtime = _load_ocr_reader()
|
| 193 |
+
if runtime is None:
|
| 194 |
logger.warning("ocr unavailable: reader is None")
|
| 195 |
return "", []
|
| 196 |
|
| 197 |
try:
|
| 198 |
+
backend = runtime["backend"]
|
| 199 |
+
reader = runtime["reader"]
|
| 200 |
+
if backend == "easyocr":
|
| 201 |
+
results = reader.readtext(file_path, detail=0, paragraph=True)
|
| 202 |
+
ocr_text = "\n".join(str(x) for x in results).strip()
|
| 203 |
+
elif backend == "rapidocr":
|
| 204 |
+
results, _elapsed = reader(file_path)
|
| 205 |
+
if not results:
|
| 206 |
+
ocr_text = ""
|
| 207 |
+
else:
|
| 208 |
+
# RapidOCR result item: [box, text, score]
|
| 209 |
+
ocr_text = "\n".join(str(item[1]) for item in results if len(item) > 1).strip()
|
| 210 |
+
else:
|
| 211 |
+
logger.warning("ocr unknown backend=%s", backend)
|
| 212 |
+
return "", []
|
| 213 |
except Exception:
|
| 214 |
logger.exception("ocr read failed for file=%s", file_path)
|
| 215 |
return "", []
|
|
|
|
| 247 |
if _ocr_error is not None:
|
| 248 |
return None
|
| 249 |
|
| 250 |
+
easyocr_error: str | None = None
|
| 251 |
try:
|
| 252 |
import easyocr
|
| 253 |
|
| 254 |
+
_ocr_reader = {
|
| 255 |
+
"backend": "easyocr",
|
| 256 |
+
"reader": easyocr.Reader(["en"], gpu=False),
|
| 257 |
+
}
|
| 258 |
+
logger.info("ocr reader initialized backend=easyocr")
|
| 259 |
+
return _ocr_reader
|
| 260 |
+
except Exception as exc:
|
| 261 |
+
easyocr_error = str(exc)
|
| 262 |
+
logger.warning("ocr easyocr init failed: %s", easyocr_error)
|
| 263 |
+
|
| 264 |
+
try:
|
| 265 |
+
from rapidocr_onnxruntime import RapidOCR
|
| 266 |
+
|
| 267 |
+
_ocr_reader = {
|
| 268 |
+
"backend": "rapidocr",
|
| 269 |
+
"reader": RapidOCR(),
|
| 270 |
+
}
|
| 271 |
+
logger.info("ocr reader initialized backend=rapidocr")
|
| 272 |
return _ocr_reader
|
| 273 |
except Exception as exc:
|
| 274 |
+
_ocr_error = f"easyocr={easyocr_error}; rapidocr={exc}"
|
| 275 |
+
logger.warning("ocr reader init failed all backends: %s", _ocr_error)
|
| 276 |
return None
|
| 277 |
|
| 278 |
|