|
|
|
from flask import Blueprint, jsonify, request |
|
import io |
|
from app.utils import OCRModel |
|
import logging |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
main = Blueprint('main', __name__) |
|
ocr_model = OCRModel() |
|
|
|
|
|
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} |
|
|
|
|
|
KNOWN_ALLERGENS = { |
|
'gluten': ['wheat', 'barley', 'rye', 'oats', 'gluten', 'flour', 'bread', 'pasta'], |
|
'dairy': ['milk', 'yogurt', 'cheese', 'lactose', 'cream', 'butter', 'whey'], |
|
'nuts': ['nuts', 'peanuts', 'almonds', 'walnuts', 'cashews', 'pistachios'], |
|
'eggs': ['eggs', 'egg', 'albumin', 'mayonnaise'], |
|
'soy': ['soy', 'soybeans', 'tofu', 'edamame'], |
|
'fish': ['fish', 'salmon', 'tuna', 'cod', 'tilapia'], |
|
'shellfish': ['shellfish', 'shrimp', 'crab', 'lobster', 'oyster', 'mussels'], |
|
'sesame': ['sesame', 'tahini'], |
|
'mustard': ['mustard'], |
|
'celery': ['celery'], |
|
'lupin': ['lupin'], |
|
'sulfites': ['sulfites', 'sulphites'] |
|
} |
|
|
|
def allowed_file(filename): |
|
"""التحقق من صحة امتداد الملف""" |
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS |
|
|
|
def find_allergens(text, user_allergens): |
|
"""البحث عن الحساسيات في النص""" |
|
text = text.lower() |
|
found_allergens = set() |
|
allergen_details = {} |
|
allergen_locations = {} |
|
|
|
for allergen in user_allergens: |
|
allergen = allergen.strip().lower() |
|
if allergen in KNOWN_ALLERGENS: |
|
for variant in KNOWN_ALLERGENS[allergen]: |
|
if variant.lower() in text: |
|
found_allergens.add(allergen) |
|
allergen_details[allergen] = variant |
|
|
|
allergen_locations[allergen] = text.index(variant.lower()) |
|
elif allergen in text: |
|
found_allergens.add(allergen) |
|
allergen_details[allergen] = allergen |
|
allergen_locations[allergen] = text.index(allergen) |
|
|
|
return found_allergens, allergen_details, allergen_locations |
|
|
|
@main.route('/') |
|
def index(): |
|
return jsonify({ |
|
"message": "Welcome to the Text Recognition and Sensitivity Checking Service", |
|
"endpoints": { |
|
"/api/ocr": "POST - Image analysis and sensitivity testing", |
|
"/api/allergens": "GET - List of known allergens" |
|
}, |
|
"supported_formats": list(ALLOWED_EXTENSIONS), |
|
"known_allergens": list(KNOWN_ALLERGENS.keys()) |
|
}) |
|
|
|
@main.route('/api/ocr', methods=['POST']) |
|
def process_image(): |
|
try: |
|
|
|
if 'file' not in request.files: |
|
logger.warning("No file uploaded") |
|
return jsonify({"error": "No file uploaded"}), 400 |
|
|
|
|
|
if 'allergens' not in request.form: |
|
logger.warning("Allergens not specified") |
|
return jsonify({"error": "Allergens not specified"}), 400 |
|
|
|
file = request.files['file'] |
|
if file.filename == '': |
|
logger.warning("No file selected") |
|
return jsonify({"error": "No file selected"}), 400 |
|
|
|
|
|
if not allowed_file(file.filename): |
|
logger.warning(f"Invalid file type: {file.filename}") |
|
return jsonify({ |
|
"error": "File type not supported", |
|
"supported_formats": list(ALLOWED_EXTENSIONS) |
|
}), 400 |
|
|
|
|
|
user_allergens = request.form['allergens'].split(',') |
|
logger.info(f"Processing image for allergens: {user_allergens}") |
|
|
|
|
|
file_bytes = file.read() |
|
file_stream = io.BytesIO(file_bytes) |
|
|
|
|
|
extracted_text = ocr_model.process_image(file_stream) |
|
logger.info(f"Extracted text: {extracted_text}") |
|
|
|
|
|
found_allergens, allergen_details, allergen_locations = find_allergens(extracted_text, user_allergens) |
|
|
|
|
|
response = { |
|
"success": True, |
|
"extracted_text": extracted_text, |
|
"analysis": { |
|
"found_allergens": list(found_allergens), |
|
"allergen_details": allergen_details, |
|
"allergen_locations": allergen_locations, |
|
"has_allergens": len(found_allergens) > 0, |
|
"warning": "⚠️ Warning: Allergens found!" if found_allergens else "✅ No allergens found", |
|
"severity": "high" if len(found_allergens) > 0 else "none" |
|
} |
|
} |
|
|
|
logger.info(f"Analysis completed successfully: {found_allergens}") |
|
return jsonify(response) |
|
|
|
except Exception as e: |
|
logger.error(f"Error processing request: {str(e)}", exc_info=True) |
|
return jsonify({ |
|
"error": "An error occurred while processing the image.", |
|
"details": str(e) |
|
}), 500 |
|
|
|
@main.route('/api/allergens', methods=['GET']) |
|
def get_known_allergens(): |
|
return jsonify({ |
|
"allergens": KNOWN_ALLERGENS, |
|
"total_count": len(KNOWN_ALLERGENS), |
|
"last_updated": "2024-03-24" |
|
}) |