o
    $cwh;j                     @   sh  d dl mZmZmZ d dlmZ ddlmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlZd dlZd dlZd dlZejd zejd  W n	 eyO   Y nw d d	lmZ d dlZd d
lmZmZ d dlZd dl Z d dl!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-Z-d dl.m/Z/ d dl0m1Z1 ddlm2Z2 d dl3m4Z4 d dl5Z5d dl6Z6zd dl7Z7dZ8W n e9y   dZ8Y nw e$ddgdZ:e:j;d dd ej<dddZ=dd Z>d d! Z?dZ@d aAe5B ZCd"d# ZDG d$d% d%ejEZFd@d&d'ZGd(d) ZHd*d+ ZIe(d@d,d-ZJd.d/ ZKd0d1 ZLd2d3 ZMd4d5 ZNd6d7 ZOd8d9 ZPe(d:d; ZQd<d= ZRd>d? ZSdS )A    )renderredirectget_object_or_404)messages   )User	UserImage
AttendanceEvent)forms)settingsNF)timezone)HttpResponseJsonResponse)ContentFile)FaceAnalysis)cosine_similarity)csrf_exempt)logout)IntegrityError)cache)cache_event_embeddings)	EventForm)ValidationErrorT	buffalo_sCPUExecutionProvider)name	providers)  r   )ctx_iddet_sizeg       @)   r!   )	clipLimittileGridSizec                 C   sF   t | t j}t |\}}}t|}t |||f}t |t jS N)cv2cvtColorCOLOR_BGR2LABsplitclaheapplymergeCOLOR_LAB2BGR)imglablabcllimg r4   D/var/www/html/yash/facial_attendance_system-main/attendance/views.pyapply_clahe-   s
   
r6   c                 C   s   t | } t| dS )N)p   r7   )r6   r%   resize)r-   r4   r4   r5   preprocess_image4   s   r9   c              	   C   s   g }| t| d | jd d \}}|d |d f}dD ]}t||d}| tj| |||ftjd q| tj| ddd | tj| d	d
d | t| dd |S )Nr      )i
   g      ?)
borderModeg?   )alphabetag?i)   r@   r   )	appendr%   flipshapegetRotationMatrix2D
warpAffineBORDER_REFLECTconvertScaleAbsGaussianBlur)r-   	augmentedhwcenterangleMr4   r4   r5   augment_image?   s    rO   c                       s*   e Zd ZG dd dZ fddZ  ZS )UserRegistrationFormc                   @   s   e Zd ZeZg dZdS )zUserRegistrationForm.Meta)
first_name	last_namemobile_numbercompanyemailN)__name__
__module____qualname__r   modelfieldsr4   r4   r4   r5   MetaQ   s    r[   c                    s:   t  j|i | | jD ]}| j| jjddi qd S )Nclasszform-control)super__init__rZ   widgetattrsupdate)selfargskwargsfield	__class__r4   r5   r^   U   s   
zUserRegistrationForm.__init__)rV   rW   rX   r[   r^   __classcell__r4   r4   rf   r5   rP   P   s    rP   c           &      C   s  t t}| jdd }d|v rd}nd|v s!d|v s!d|v r$d}nd}d }|d ur2tt|d}td	| d
| d|  |d urH|| j	d< |d ur^|
 s^t| d t| dd|iS | jdkr4t| j| j}| jd}t| jdd}d }	|jdd r|jdd r|jdd r|jdd sd}	n|jdd rt|jdddksd}	nt|dkrd}	|	rtd|	  t| d|||	dS | r-|d  }
|
d!\}}|d"d# }|jd  d$|jd  d%| }tjtj |}t!|d&}|"t#$| W d    n	1 sw   Y  t%&|}t'' }t(t)|}t'' }td'|r@t|nd  d(|| d)d* d }|r|d  j*+d+d#}t,j-.d,/ D ]Y}|ru|j0j1j2|j3d4 suqbt'' }t56t|j7+d+d#}t8||d  d  }t'' }td-|| d)d. |d/kr|j0}|}td0|j9 d1|j: d2| d3  nqbt;| |rt| d|||t<t=|dd4tj>d5S |d urt?j-j2|jd |d6@ }|rt| d7 t| d||d8S |A }|j1B| n|A }d }tC|D ]\} }
|
d!\}}|d"d# }|j9 d$|j: d$|j3 d9| d+  d:| 	}tjtj |}!t!|!d&}|"t#$| W d    n	1 sXw   Y  t%&|!}|gtD| }"tC|"D ]\}#}$t'' }t(t)|$}t'' }td;|  d<|# d=|rt|nd  d>|| d)d*	 |r|d  j*}%|#d krt,j-jE||tF|%G |d? td@| dAttF|%G   n!t,j-jE|d tF|%G |d? tdB|j3 dAttF|%G   |d+7 }qmq|rtH| dC|j9 d1|j: dD| dE |r|j3| j	d< t| dt |d4dFS tIdGS |J  t| d||dHdS t| dI nt }t| d||d8S )JNHTTP_USER_AGENT androidiphoneipadipoddesktopidz[register_user] event_id: 	, event: , device_type: last_event_idz&Registration for this event is closed.attendance/event_closed.htmleventPOSTimagescaptured_imagesz[]rQ   rR   rS   rU   zFAll fields (First Name, Last Name, Mobile Number, Email) are required.r;   z0Mobile Number must be exactly a 10-digit number.r@   z.Please capture exactly 3 photos as instructed.z[DEBUG] Registration error: zattendance/register.html)formrv   registration_errorr   ;base64,/_z_temp_check.zwb+z+[DEBUG] Registration: face_app.get() found z faces in temp image. Took .3fs.r   userz?[PROFILE] Registration duplicate check: cosine_similarity took 	 seconds.皙?zDUPLICATE DETECTED:  z (sim=)T)rv   duplicate_userduplicate_imageduplicate_similarityshow_duplicate	MEDIA_URL)rU   eventsz<A user with this email is already registered for this event.)rz   rv   _webcam_.z1[DEBUG] Registration: face_app.get() for aug_img -z found z faces. Took )r   
image_pathencodingrv   z[DEBUG] Saved UserImage: z, encoding length: z.[DEBUG] Saved augmentation embedding for user zUser 'z' registered with z* valid photo(s) (including augmentations).)rz   rv   show_mark_attendanceregister_userz$Face not detected. Please try again.z-Please capture exactly 1 photo as instructed.)Klogging	getLoggerrV   METAgetlowerr   r
   printsessionis_upcomingr   errorr   methodrP   rw   FILESgetlistjsonloadsdatastripisdigitlenis_validr(   cleaned_dataospathjoinr   
MEDIA_ROOTopenwritebase64	b64decoder%   imreadtimeface_appr9   	embeddingreshaper   objectsselect_relatedallr   r   filterrq   existsnparrayr   r   rQ   rR   removeroundfloatr   r   firstsaveadd	enumeraterO   createdumpstolistsuccessr   delete)&requestevent_idlogger
user_agentreg_device_typerv   rz   filesry   r{   data_urlformatimgstrextfilenametemp_img_pathdestinationr-   t0facest1r   new_embedding
user_imaget2existing_embeddingsimt3r   existing_userr   savediimg_pathall_imgsidxaug_imgr   r4   r4   r5   r   [   s   

H(
 
*
 

	*
6

$$$r   c                 C   *   t jddd d }t| dd|iS )Nr   
-timestamp   attendance/mark_attendance.htmllogsr	   r   r   order_byr   r   r   r4   r4   r5   mark_attendance      r   c                 C   sd   || j d< tt|d}| st| dd|iS tjj|dd	dd d }t| d	|||d
S )Nrt   rp   ru   rv   )rv   r   r   r   r   )r   rv   r   )
r   r   r
   r   r   r	   r   r   r   r   )r   r   rv   r   r4   r4   r5   mark_attendance_for_event   s   
"r   c           0      C   s  | j dkrCzt! td7 att dkr$tdddW  d    W S W d    n1 s.w   Y  t| j}|d}|dd	}d }d }|d ur\t	j
j|d
 }|rZ|jnd }td| d| d|  |sstdddW S t| d|   }d| }t|rtdddW S t|dd |d\}	}
|	dd }t|
}t|tj}t }t|tj}t }td|| dd t|d}t |}t }t!t"|}t }td|| dd |stdddW S dd |D }|r2td|j# dd g f\}}|d u s|s1t$|j# td|j# dd g f\}}nXt%j
& }g }g }|D ]3}t }t't|j()dd}t }td |j*j# d!|| dd" |+| |+|j* q=td#t,| d$t,| d% |rt-|nd }|d u s|std& tdd'dW S |d(krd)}n
|d*krd+}nd,}|D ]d}t.r|j/d dkr|0d-}|tj1j2|ddd. }|0d-} | tj1j2| ddd. } t34|j/d }!|!5| |!6| d\}"}#t7|#d d }$t8|"d d }%td/|%d td0|%  |%|kr||$ }&t9:t9; }'|'< }(t=j
j|&d1|d2>d3 })|)r?t9:|)j?nd }*|*rH|*< nd }+d},|*rW|+|(krWd},nt=j
j|&|(d1|d4@ },|,rtd|&jAd5 |&jB d|rv|j#nd ||&jA d5|&jB d6d7  W S z3t=|&d1|'|d8}-|-C  |-D  td|&jAd5 |&jB d|r|j#nd ||&jA d5|&jB d9d7W   W S  tEy }. z"td|&jAd5 |&jB d|r|j#nd |tF|.d7W  Y d }.~.  W S d }.~.w tGy   td|&jAd5 |&jB d|r|j#nd ||&jA d5|&jB d6d7 Y   W S w qtd: tdd'dW S  tHyB }/ ztdd;tF|/ dW  Y d }/~/S d }/~/ww tdd<dS )=Nrw   r   r   FzFrame skipped for performance.r   message
image_datadevice_typero   rp   z![ajax_mark_attendance] event_id: rr   rs   No image data received.r   attendance_request_z1Duplicate request detected. Please wait a moment.Tr|   r}   r~   z-[PROFILE] AJAX attendance: cv2.imdecode took r   r      r   z/[PROFILE] AJAX attendance: face_app.get() took rj   c                 S   s   g | ]	}|j d dqS )r   r~   )r   r   ).0facer4   r4   r5   
<listcomp>   s    z(ajax_mark_attendance.<locals>.<listcomp>event__embeddingsz9[DEBUG] AJAX attendance: loading user embedding for user z took r   z [DEBUG] AJAX attendance: loaded z users and z embeddings.zZ[DEBUG] AJAX attendance: No embeddings or users found. Returning 'No known face detected.'No known face detected.rk   gp=
ף?rl   r   g333333?float32)axiskeepdimsz[FAISS] Best similarity: z-[PROFILE] AJAX attendance: best similarity = login)r   
event_typerv   r   )r   timestamp__dater  rv   r   z& (Attendance already marked for today))r   r   already_markedr   
event_namer   )r   r  	timestamprv   z - Attendance marked!z3[ALERT] No known face detected in multi-face frame!Error: Invalid request method.)Ir   attendance_lockattendance_frame_counter
FRAME_SKIPr   r   r   bodyr   r
   r   r   r   r   r   hashlibmd5encode	hexdigestr   setr(   r   r   r   
frombufferuint8r   r%   imdecodeIMREAD_COLORr8   r6   r   r9   rq   r   r   r   r   r   r   r   rA   r   vstackfaiss_availablerC   astypelinalgnormfaissIndexFlatIPr   searchintr   r   	localtimenowdater	   r   r  r   rQ   rR   
full_cleanr   r   strr   	Exception)0r   r   r   r   r   rv   r  request_hash	cache_keyr   r   r   	img_bytesnparrr   r-   r   r   r   r   new_embeddingsembeddings_npusersuser_images
embeddingsuit4embt5	thresholdr   xbxqindexDIbest_idxbest_simr   r   todaylast_attendancelast_attendance_locallast_attendance_dater  
attendanceveer4   r4   r5   ajax_mark_attendance   s   





 







DFDH$rA  c                 C   s   t jdd}| jdd }| jdd }| jdd }|r,|j|d}|r4|j|d}|rQztj	
|d	 }|j|d
}W n	 tyP   Y nw t| d||||dS )Nr   r   r   rj   employee_coder!  user__name__icontainsuser__employee_code__icontains%Y-%m-%dr  zattendance/view_logs.html)r   name_filtercode_filterdate_filter)r	   r   r   r   GETr   r   r   r   datetimestrptimer!  
ValueErrorr   )r   r   rI  rJ  rK  date_objr4   r4   r5   view_attendance_logsj  s*   rQ  c                 C   s   ddl m} |j }| jd}tj d}d }|r9z|jj|d}|j|d}W n |j	y8   d }Y nw t
| d|tj||rIt|d	S dd	S )
Nr   )r
   rv   rx   rp   )r   z attendance/registered_users.htmlrj   )r+  r   r   selected_event_id)modelsr
   r   r   rL  r   r   prefetch_relatedr   DoesNotExistr   r   r   r  )r   r
   r   rR  r+  selected_eventr4   r4   r5   list_registered_users  s(   

rW  c           	      C   s   t jdd}| jdd }| jdd }| jdd }|r,|j|d}|r4|j|d}|rQztj	
|d	 }|j|d
}W n	 tyP   Y nw tdd}d|d< t|}|g d |D ]}||jj|jj|jg qh|S )Nr   r   r   rj   rB  r!  rC  rE  rG  rH  ztext/csv)content_typez*attachment; filename="attendance_logs.csv"zContent-Disposition)NamezEmployee Code	Timestamp)r	   r   r   r   rL  r   r   r   r   rM  rN  r!  rO  r   csvwriterwriterowr   r   rB  r  )	r   r   rI  rJ  rK  rP  responser\  logr4   r4   r5   export_attendance_csv  s,   

r`  c                 C   sV   t t|d}| jdkr'|j D ]}|jr"tj|jr"t	|j q|
  tdS )Nrp   rw   registered_users)r   r   r   rx   r   r   r   r   r   r   r   r   )r   user_idr   r-   r4   r4   r5   delete_user  s   
rc  c                 C   s.   | j }|jrtjj|dd t|  t| dS )Nr   )r   r  zattendance/logout.html)r   is_authenticatedr	   r   r   r   r   )r   r   r4   r4   r5   logout_view  s
   
re  c                 C   r   )Nr   r   r;   zattendance/mark_logout.htmlr   r   r   r4   r4   r5   mark_logout  r   rf  c              
   C   s  | j dkrSz%t| j}|d}|stdddW S |d\}}|dd }t|}t	
|t	j}t|tj}t|d	}tt|}	|	sUtdd
dW S |	d jdd}
tdd g f\}}|d u sn|stj }g }g }|D ]}t	t|jdd}|| ||j qy|rt	|}nd }tjd||fd d |d u s|stdddW S t|
|d }d}t	|}|| }||kr%|| }t !t " }|# }t$jj%||dd& }|stdddW S t$jj%||dd& }|st$jj'|d|d td|j(d |j) dW S td|j(d |j) ddW S tdddW S  t*yR } zt+d|  tddt,| dW  Y d }~S d }~ww tdddS )Nrw   r   Fr   r   r|   r}   r~   r   zNo face detected.r   r   all_user_embeddings)timeoutr   g?r  )r   r  r  z)You must log in today before logging out.r   )r   r  r  Tr   )r   r   )r   r   r  zLogout error: r  r  )-r   r   r   r  r   r   r(   r   r   r   r  r  r%   r  r  r8   r   r9   r   r   r   r   r   r   r   r   rA   r   r  r  r   argmaxr   r  r   r!  r	   r   r   r   rQ   rR   r$  r   r#  )r   r   r   r   r   r   r'  r(  r-   r   r   r*  r+  r,  r-  r.  r0  simsr2  r8  r9  r   r   r:  has_logged_inalready_logged_outr@  r4   r4   r5   ajax_mark_logout  sl   





$rm  c                 C   s(   | j dkrd| jv r| jd= tdS d S )Nrw   rt   r   )r   r   r   )r   r4   r4   r5   clear_event  s
   

rn  c                 C   s   | j dkrd| jv rtjj| jd d  tdS | j dkr6d| jvr6t| j}| r5|	  tdS nt }tj
 d}t| d||dS )Nrw   delete_event_idrp   	add_eventz-event_datezattendance/add_event.html)rz   r   )r   rw   r
   r   r   r   r   r   r   r   r   r   r   )r   rz   r   r4   r4   r5   rp    s   
rp  r$   )Tdjango.shortcutsr   r   r   django.contribr   rS  r   r   r	   r
   djangor   django.confr   r   r   numpyr   r%   oclsetUseOpenCLcuda	setDevicer$  django.utilsr   r[  django.httpr   r   r   r   django.core.files.baser   insightface.appr   sklearn.metrics.pairwiser   django.views.decorators.csrfr   django.contrib.authr   	django.dbr   r  django.core.cacher   attendance.utilsr   r   django.core.exceptionsr   	threadingr   r  r  ImportErrorr   preparecreateCLAHEr)   r6   r9   r  r
  Lockr	  rO   	ModelFormrP   r   r   r   rA  rQ  rW  r`  rc  re  rf  rm  rn  rp  r4   r4   r4   r5   <module>   s    
 v

9