arabic-doc-intelligence / core /extractor.py
Faraz618's picture
Update core/extractor.py
934cfad verified
Raw
History Blame Contribute Delete
3.31 kB
import io
import logging
from pathlib import Path
logger = logging.getLogger(__name__)
def extract_with_tesseract(file_bytes: bytes, file_extension: str) -> dict:
"""Extract text using Tesseract OCR — Arabic + English."""
try:
from PIL import Image
import pytesseract
extracted = {
"source": "tesseract",
"pages": [],
"full_text": "",
"tables": [],
"key_value_pairs": [],
"language": "ar",
"confidence": 0.0,
"word_count": 0
}
if file_extension.lower() == ".pdf":
try:
from pdf2image import convert_from_bytes
images = convert_from_bytes(file_bytes, dpi=150)
except Exception as e:
logger.warning(f"PDF conversion failed: {e}")
extracted["full_text"] = (
"[PDF extraction requires poppler. "
"Please upload a PNG or JPG image instead.]"
)
extracted["pages"].append({
"page_number": 1,
"lines": [],
"words": [],
})
return extracted
else:
image = Image.open(io.BytesIO(file_bytes))
# Convert to RGB if needed
if image.mode not in ("RGB", "L"):
image = image.convert("RGB")
images = [image]
full_text_parts = []
for page_idx, image in enumerate(images):
# Try Arabic+English, fall back to English only
try:
text = pytesseract.image_to_string(
image, lang="ara+eng", config="--psm 3"
)
except Exception:
try:
text = pytesseract.image_to_string(
image, lang="eng", config="--psm 3"
)
except Exception:
text = pytesseract.image_to_string(image, config="--psm 3")
lines = [ln.strip() for ln in text.splitlines() if ln.strip()]
full_text_parts.extend(lines)
page_data = {
"page_number": page_idx + 1,
"lines": [{"text": ln, "confidence": 0.75} for ln in lines],
"words": [
{"text": w, "confidence": 0.75}
for ln in lines
for w in ln.split()
],
}
extracted["pages"].append(page_data)
extracted["full_text"] = "\n".join(full_text_parts)
extracted["word_count"] = len(extracted["full_text"].split())
extracted["confidence"] = 0.75 if extracted["word_count"] > 0 else 0.0
return extracted
except Exception as e:
logger.error(f"Tesseract extraction failed: {e}")
raise
def extract_document(
file_bytes: bytes, file_extension: str, filename: str = ""
) -> dict:
"""Main extraction entry point — always uses Tesseract."""
logger.info(f"Extracting: {filename}")
result = extract_with_tesseract(file_bytes, file_extension)
result["filename"] = filename
result["file_size_bytes"] = len(file_bytes)
result["file_extension"] = file_extension
return result