U
    µh¢h
  ã                
   @   s¼   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlZzeje j d¡d W n6 ek
r– Z zede› ƒ eƒ  W 5 dZ[X Y nX dd„ Zdd	„ Zd
d„ Zdd„ ZdS )é    N)ÚImageZ'AIzaSyCJimpvYx_rUZo043u3iFwtKig9uqsbEHY)Zapi_keyzBError: GOOGLE_API_KEY not found. Please set it in your .env file. c              
   C   s”   zXt  | ¡ d¡}t  |¡ d¡}t ¡ › d}tj ||¡}|j|d|gd ||fW S  t	k
rŽ } zt
d|› ƒ W Y ¢dS d}~X Y nX dS )z&Combines two images into a single PDF.ZRGBz.pdfT)Úsave_allZappend_imageszError combining images to PDF: )NNN)r   ÚopenÚconvertÚuuidÚuuid4ÚosÚpathÚjoinÚsaveÚ	ExceptionÚprint)Zimage1_pathZimage2_pathÚoutput_folderZimg1Zimg2Úpdf_filenameÚpdf_pathÚe© r   ú,/var/www/html/id_scanner_app_1-main/utils.pyÚcombine_images_to_pdf   s    
r   c              
   C   s¦   zjt  | ¡}|jdkr$| ¡  W dS | d¡}| ¡ }dt ¡ › d}tj	 
||¡}| |¡ | ¡  |W S  tk
r  } ztd|› ƒ W Y ¢dS d}~X Y nX dS )zEConverts the first page of a PDF to a JPG image and returns the path.r   NZ	pdf_page_ú.jpgzError converting PDF to image: )Úfitzr   Z
page_countÚcloseZ	load_pageZ
get_pixmapr   r   r   r	   r
   r   r   r   )r   r   ÚdocÚpageZpixZimage_filenameZimage_filepathr   r   r   r   Úconvert_pdf_first_page_to_image!   s    

 

r   c              
   C   sò  z²d}d}t j ||¡}t  | ¡}|dkr@td| › ƒ W dS |jdd… \}}t j t  |d¡ddd¡}| |¡ | 	¡ }	t
 |	d	d	dd…df ¡}
|	d	d	|
df }|d
krštd|d›ƒ |	d	d	|
dd…f t
 ||||g¡ }| d¡\}}}}d}td	|| ƒ}td	|| ƒ}t||| ƒ}t||| ƒ}|||…||…f }|jd	kr\W dS dt ¡ › d}tj ||¡}t  ||¡ td|› ƒ |W S td|d›dƒ W dS W n8 tk
rì } ztd|› ƒ W Y ¢dS d}~X Y nX dS )z/Detects a face using a stable OpenCV DNN model.zdeploy.prototxtz(res10_300x300_ssd_iter_140000.caffemodelNz7!!! FACE DETECTION ERROR: Could not read image file at é   )é,  r   g      ð?)g      Z@g      f@g     À^@r   g333333Ó?z2>>> FACE DETECTION: Found a face with confidence: z.2fé   é   Úinté   Zface_r   z.>>> FACE DETECTION SUCCESS: Face extracted to zO>>> FACE DETECTION: No faces found with sufficient confidence (Max Confidence: z).z:!!! FACE DETECTION CRITICAL ERROR: An exception occurred: )Úcv2ZdnnZreadNetFromCaffeZimreadr   ÚshapeZblobFromImageZresizeZsetInputÚforwardÚnpZargmaxÚarrayZastypeÚmaxÚminÚsizer   r   r   r	   r
   Zimwriter   )Z
image_pathr   Zprototxt_pathZ
model_pathÚnetZimgÚhÚwZblobZ
detectionsZbest_detection_indexZ
confidenceZboxZstartXZstartYZendXZendYÚpaddingZface_croppedZface_filenameZface_filepathr   r   r   r   Údetect_and_extract_face3   sN    
 ÿ

&   
r-   c              
   C   sJ  zÀt  d¡}t j| d}d}|j||gdddddœd}td|j› dƒ |j ¡ s|td	ƒ |jrrtd
|j› ƒ ddiW S |j ¡ }| d¡rœ|dd… }| 	d¡r²|dd… }t
 |¡}|W S  t
jk
r } z"td|› ƒ d|jdœ W Y ¢S d}~X Y nB tk
rD } z"td|› ƒ dt|ƒi W Y ¢S d}~X Y nX dS )z2Performs OCR on an image or PDF file using Gemini.zgemini-1.5-flash)r	   a©  
        Analyze the document. Extract all textual information into a structured JSON object.

        **CRITICAL INSTRUCTIONS:**
        1.  **JSON ONLY:** The entire output must be a single, valid JSON object.
        2.  **NO MARKDOWN:** Do not wrap the JSON in ```json ... ``` or any other markdown formatting.
        3.  **NO EXPLANATIONS:** Do not include any introductory text, summary, or any other explanatory sentences before or after the JSON object. Your entire response must start with `{` and end with `}`.
        4.  Use descriptive keys like "fullName", "dateOfBirth", "idNumber", "address".
        5.  If a field is not present, the value must be null.
        Z
BLOCK_NONE)ZHARM_CATEGORY_HARASSMENTZHARM_CATEGORY_HATE_SPEECHZHARM_CATEGORY_SEXUALLY_EXPLICITZHARM_CATEGORY_DANGEROUS_CONTENT)Zsafety_settingsz--- RAW GEMINI RESPONSE ---
z
-------------------------zK!!! GEMINI ERROR: Received an empty response. Likely due to safety filters.zPrompt Feedback from API: ÚerrorzAAPI returned an empty response, likely blocked by safety filters.z```jsonr   Nz```éýÿÿÿzG!!! JSON DECODE ERROR: Failed to parse Gemini response as JSON. Error: z+Failed to parse non-JSON response from API.)r.   Zraw_responsez5!!! An unexpected error occurred calling Gemini API: )ÚgenaiZGenerativeModelZupload_fileZgenerate_contentr   ÚtextÚstripZprompt_feedbackÚ
startswithÚendswithÚjsonÚloadsÚJSONDecodeErrorr   Ústr)Z	file_pathÚmodelZuploaded_fileÚpromptÚresponseZcleaned_textÚdatar   r   r   r   Úcall_gemini_ocrd   s>    
ýþ





 r=   )r   r   r5   r!   Znumpyr$   Zgoogle.generativeaiZgenerativeair0   ZPILr   r   Ú	configureÚenvironÚgetÚAttributeErrorr   r   Úexitr   r   r-   r=   r   r   r   r   Ú<module>   s    1