Spaces:
Sleeping
Sleeping
File size: 3,563 Bytes
ee9de9c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | from __future__ import annotations
from functools import lru_cache
from pathlib import Path
import re
from app.config import settings
@lru_cache(maxsize=1)
def get_ocr_reader():
try:
import easyocr
except ModuleNotFoundError as exc:
raise RuntimeError(
"OCR is enabled but EasyOCR is not installed. Install apps/api requirements again."
) from exc
return easyocr.Reader(["ar", "en"], gpu=False, verbose=False)
def ocr_cache_path(document_id: str, page_number: int) -> Path:
return settings.ocr_dir / f"{document_id}_p{page_number}.txt"
OCR_REPLACEMENTS = {
"تاربخ": "تاريخ",
"علان": "إعلان",
"اشع": "الشعب",
"عىبها": "عليها",
"يعما": "يعمل",
"بهده": "بهذه",
"الوثبقة": "الوثيقة",
"الدستوريه": "الدستورية",
"الاصوات": "الأصوات",
"لامشاركين": "للمشاركين",
"الشبوخ": "الشيوخ",
"الشيوح": "الشيوخ",
"الدبمقراطية": "الديمقراطية",
"الديمفراطية": "الديمقراطية",
"الديموفراطى": "الديمقراطى",
"الحربات": "الحريات",
"الحفو": "الحقوق",
"المفومات": "المقومات",
"الافتصادية": "الاقتصادية",
"الجمهوربة": "الجمهورية",
"رنبس": "رئيس",
"رئبس": "رئيس",
"المانون": "القانون",
"فانون": "قانون",
"قالون": "قانون",
"بحدده": "يحدده",
"النطام": "النظام",
"مبلادية": "ميلادية",
}
def clean_ocr_text(text: str) -> str:
cleaned_lines: list[str] = []
for line in text.splitlines():
stripped = line.strip()
if not stripped:
continue
if re.search(r"(?:node|روابط سريعة|روابط|فريق العمل|اتصل بنا)", stripped, re.IGNORECASE):
break
cleaned_lines.append(stripped)
cleaned = "\n".join(cleaned_lines)
for wrong, right in OCR_REPLACEMENTS.items():
cleaned = cleaned.replace(wrong, right)
cleaned = re.sub(r"[ \t]+", " ", cleaned)
return cleaned.strip()
def ocr_pdf_page(document_id: str, pdf_path: Path, page_number: int) -> str:
cache_path = ocr_cache_path(document_id, page_number)
if cache_path.exists():
return clean_ocr_text(cache_path.read_text(encoding="utf-8"))
try:
import fitz
except ModuleNotFoundError as exc:
raise RuntimeError("OCR requires PyMuPDF.") from exc
with fitz.open(pdf_path) as document:
if page_number < 1 or page_number > document.page_count:
return ""
page = document[page_number - 1]
pixmap = page.get_pixmap(
matrix=fitz.Matrix(settings.ocr_scale, settings.ocr_scale),
alpha=False,
)
image_path = settings.ocr_dir / f"{document_id}_p{page_number}.png"
pixmap.save(str(image_path))
reader = get_ocr_reader()
lines = reader.readtext(
str(image_path),
detail=0,
paragraph=True,
decoder="greedy",
batch_size=16,
canvas_size=settings.ocr_canvas_size,
mag_ratio=1.0,
)
text = clean_ocr_text("\n".join(str(line) for line in lines))
cache_path.write_text(text, encoding="utf-8")
return text
|