
    1h                         S r SSKrSSKrSSKrSSKJrJr  SSK	r	SSK
r
SSKrSSKJrJr  SSKrSSKJrJr  SSKrSSKJr  SSKr\R,                  " S5         " S S	5      r\S
:X  a  \" 5       r\R5                  5         gg)z
Enhanced Standalone Face Recognition Application
Features: Real-time detection, recognition, history, statistics, settings, and attendance system
    N)ttk
messagebox)datetime	timedelta)ImageImageTk)Pathdarkc                       \ rS rSrS rS rS rS rS rS r	S r
S	 rS
 rS#S jrS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S  r!S! r"S"r#g)$FaceRecognitionApp   c                    [         R                  " 5       U l        U R                  R                  S5        U R                  R	                  S5        SU l        S U l        S U l        S U l        0 U l	        SU l
        SU l        SU l        SU l        SU l        / U l        0 U l        U R#                  5         U R%                  5         U R'                  5         U R)                  5         g )	N Enhanced Face Recognition System1400x900Fr   x   g?   )   r   )ctkCTkroottitlegeometry
is_runningcapface_cascade
recognizer	user_datacurrent_camera_indexconfidence_thresholddetection_sensitivitymin_neighborsmin_sizeattendance_logtoday_attendanceload_modelsload_attendance_data	create_uistart_cameraselfs    W/Users/scrubbed2358/Documents/attendance-logger/standalone_face_recognition_enhanced.py__init__FaceRecognitionApp.__init__   s    GGI			:;		:&   $%! %(!%("  ! " 	!!# 	 	    c                 D    Sn[         R                  R                  U5      (       d  [        R                  " SSU 35        g[
        R                  " U5      U l        Sn[         R                  R                  U5      (       d  [        R                  " SSU 35        g[
        R                  R                  5       U l
        U R                  R                  U5        [         R                  R                  S5      (       aS  [        SS5       n[        R                  " U5      U l        SSS5        [!        S	[#        U R                  5       S
35        g[!        S5        g! , (       d  f       N== f! [$         a$  n[        R                  " SSU 35         SnAgSnAff = f)z*Load face detection and recognition modelsz#haarcascade_frontalface_default.xmlErrorzFace cascade file not found: Nzface_recognizer.ymlz Face recognizer file not found: zuser_data.jsonr   ✅ Loaded z usersu   ⚠️ No user_data.json foundzFailed to load models: )ospathexistsr   	showerrorcv2CascadeClassifierr   faceLBPHFaceRecognizer_creater   readopenjsonloadr   printlen	Exception)r*   cascade_pathrecognizer_pathfes        r+   r%   FaceRecognitionApp.load_models:   s=   	I@L77>>,//$$W0Ml^.\] # 5 5l CD 4O77>>/22$$W0PQ`Pa.bc!hh@@BDOOO  1 ww~~.//*C0A%)YYq\DN 1C$7#8?@67	 10  	I  ,CA3*GHH	IsD   A E1 AE1 A.E1 E )*E1 E1  
E.*E1 1
F;FFc                     [         R                  R                  S5      (       a^  [        SS5       n[        R
                  " U5      n[        U5      U l        SSS5        [        S[        U R                  5       S35        g[        S5        g! , (       d  f       N== f! [         a  n[        SU 35         SnAgSnAff = f)z"Load attendance data from CSV fileattendance_log.csvr1   Nr2   z attendance recordsu"   ⚠️ No attendance_log.csv foundzError loading attendance data: )r3   r4   r5   r<   csv
DictReaderlistr#   r?   r@   rA   )r*   rD   readerrE   s       r+   r&   'FaceRecognitionApp.load_attendance_dataW   s    		9ww~~233.4 ^^A.F*.v,D' 5 C(;(;$<#==PQR:; 54  	93A3788	9s4   0B! 'B*B! B! 
BB! !
C+B>>Cc           	         [         R                  " U R                  5      nUR                  SSSSS9  [         R                  " US[         R
                  " SSS9S	9nUR                  S
S9  [         R                  " U5      U l        U R                  R                  SSS9  U R                  5         U R                  5         U R                  5         g)zCreate the user interfacebothT
   fillexpandpadxpadyr   r   boldsizeweighttextfontr      rU   rR   rS   N)r   CTkFramer   packCTkLabelCTkFont
CTkTabviewnotebookcreate_recognition_tabcreate_reports_tabcreate_settings_tab)r*   
main_frametitle_labels      r+   r'   FaceRecognitionApp.create_uid   s     \\$)),
VDrC ll:4V&)kkr&&IKg& z2t4 	##% 	! 	  "r.   c           	         U R                   R                  S5      n[        R                  " U5      nUR	                  SSSSS9  [        R                  " U5      nUR	                  SSSSS9  [        R                  " U5      nUR	                  S	S
9  [        R
                  " USSSS9U l        U R                  R	                  SSS9  [        R                  " U5      nUR	                  SS	S9  [        R                  " USU R                  S9U l	        U R                  R	                  SSSS9  [        R                  " USU R                  SS9U l        U R                  R	                  SSSS9  [        R
                  " US[        R                  " SS9S9U l        U R                  R	                  SS
9  [        R                  " U5      nUR	                  SSSS9  [        R
                  " US [        R                  " S!S"S#9S9nUR	                  SS
9  S$n[        R                  " XhS%S&S'9U l        U R                   R#                  S(S(S)9  U R                   R#                  S*S*S)9  U R                   R#                  S+S+S)9  U R                   R#                  S,S,S)9  U R                   R#                  S-S-S)9  U R                   R%                  S(S.S/9  U R                   R%                  S*S0S/9  U R                   R%                  S+S1S/9  U R                   R%                  S,S1S/9  U R                   R%                  S-S.S/9  [        R&                  " US2U R                   R(                  S39n	U R                   R+                  U	R,                  S49  U R                   R	                  SSSS5S9  U	R	                  SS6SS79  [        R                  " US8U R.                  S9n
U
R	                  SS
9  g9):zCreate the recognition tabRecognitionrO   TrP   rQ   leftr   rP   siderR   rS   rT   r]   r_   zCamera Loading...  ih  )r[   widthheight)rT   rU   xrR   rU   zStart Recognitionr[   commandrP      )rr   rT   rU   zStop Recognitiondisabled)r[   ry   stater{   zStatus: Ready   rX   rZ   right)rr   rR   rS   zRecognition History   rV   rW   )TimeUser
ConfidenceStatus
Attendanceheadings   columnsshowru   r   r[   r   r   r   r   d   rt   r   P   verticalorientry   yscrollcommandrP   r   yrr   rR   rT   zClear HistoryN)rf   addr   ra   rb   rc   camera_label	CTkButtonstart_recognitionstart_buttonstop_recognitionstop_buttonrd   status_labelr   Treeviewhistory_treeheadingcolumn	Scrollbaryview	configuresetclear_history)r*   recognition_tabcontent_frame
left_framecamera_framecontrols_frameright_framehistory_titler   history_scrollbarclear_buttons              r+   rg   )FaceRecognitionApp.create_recognition_tab|   s   --++M: _5t"2F \\-0
V&GL ||J/w'  LL<O-0>BR0 j173MM.?R040F0FHFrB==>P/3/D/DJX6;  LL/,/KKR,@BG, ll=1gF4@ [7L(+F(KM( ILLJ_ab 	!!&v!6!!&v!6!!,\!B!!(!:!!,\!B 	  s 3  s 3  R 8   4  S 9  MM+jRVRcRcRiRij##3D3H3H#IF7SG#GD }}[+/+=+=?r"r.   c           	      r   U R                   R                  S5      n[        R                  " U5      nUR	                  SSSSS9  [        R
                  " US[        R                  " SSS	9S
9nUR	                  SS9  [        R
                  " US[        R                  " SS9S
9nUR	                  SS9  [        R                  " U5      nUR	                  SSS9  [        R                  " U5      nUR	                  SSSS9  [        R
                  " US[        R                  " SSS	9S
9R	                  SSS9  [        R                  " U5      nUR	                  SS9  [        R
                  " USS9R	                  SSS9  [        R                  " U R                  5       S9U l	        [        R                  " XpR                  SS 9nUR	                  SS!S9  [        R
                  " US"S9R	                  SSS9  [        R                  " [        R                  " 5       R                  S#5      S9U l        [        R                  " XpR                  SS 9n	U	R	                  SS!S9  [        R                  " US$U R                   S%S&9n
U
R	                  SS'S9  [        R                  " U5      nUR	                  SSS!S9  [        R
                  " US(S9R	                  SSS9  [        R                  " 5       U l        [        R                  " XR"                  S)S 9nUR	                  SS!S9  UR%                  S*U R&                  5        [        R                  " U5      nUR	                  SSS9  [        R                  " U5      nUR	                  SSSS9  [        R                  " U5      nUR	                  SSSSS+9  [        R
                  " US,[        R                  " SSS	9S
9R	                  5         [        R
                  " US-[        R                  " SSS	9S
9U l        U R(                  R	                  5         [        R                  " U5      nUR	                  SSSS.S+9  [        R
                  " US/[        R                  " SSS	9S
9R	                  5         [        R
                  " US-[        R                  " SSS	9S
9U l        U R*                  R	                  5         [        R                  " U5      nUR	                  SSSS.S+9  [        R
                  " US0[        R                  " SSS	9S
9R	                  5         [        R
                  " US-[        R                  " SSS	9S
9U l        U R,                  R	                  5         [        R                  " U5      nUR	                  SSSS1S+9  [        R
                  " US2[        R                  " SSS	9S
9R	                  5         [        R
                  " US-[        R                  " SSS	9S
9U l        U R.                  R	                  5         [        R                  " U5      nUR	                  SSS39  [        R
                  " US4[        R                  " S5SS	9S
9nUR	                  SS9  [        R
                  " US6[        R                  " SS9S
9nUR	                  S!S9  S7n[0        R2                  " UUS8S9S:9U l        U R4                  R7                  S;S;S9  U R4                  R7                  S<S<S9  U R4                  R7                  S=S=S9  U R4                  R7                  S>S>S9  U R4                  R9                  S;S?S@9  U R4                  R9                  S<S%S@9  U R4                  R9                  S=S?S@9  U R4                  R9                  S>S%S@9  [0        R:                  " USAU R4                  R<                  SB9nU R4                  R?                  UR@                  SC9  U R4                  R	                  SSSS'S+9  UR	                  SDSES!SF9  U RC                  5         gG)Hz;Create the reports tab matching web version attendance logsReportsrO   TrP   rQ   zEnhanced Attendance Logr^   rV   rW   rZ   r   r{   r_   z:View and manage attendance records with advanced filtering   r   r]   rv   rw   rR   rT   rU   zDate Range Filter:r~   wanchorrU   )rR   zFrom:r   ro   rz   )rr   rT   valuer   )textvariablert   rp   zTo:%Y-%m-%dz
This Monthr   r[   ry   rt   r   zSearch by User ID or Name:   z<KeyRelease>rq   zTotal Records0r{   z	Check-insz
Check-outsr{   r   zActive Usersr`   zAttendance Records   z(Showing records from selected date range	TimestampUser ID	User Namer   r   r   r   r   r   r   r      r   r   r   r   r   r   r   N)"rf   r   r   ra   rb   rc   rd   	StringVarget_first_day_of_monthstart_date_varCTkEntryr   nowstrftimeend_date_varr   set_this_month_range
search_varbindfilter_attendance_datatotal_records_labelcheckin_count_labelcheckout_count_labelactive_users_labelr   r   attendance_treer   r   r   r   r   r   load_attendance_table)r*   reports_tabr   rk   
desc_labelfilters_frame
date_framedate_controls_framestart_date_entryend_date_entrythis_month_btnsearch_framesearch_entrystats_frame
stats_gridtotal_framecheckin_framecheckout_frameactive_frametable_frametable_title
table_descattendance_columnsattendance_scrollbars                           r+   rh   %FaceRecognitionApp.create_reports_tab   s
   mm''	2 [1t"2F ll=7P&)kkr&&IKf%\\-6r&)kkr&:<
W% ]3'2 \\-0
Sr3Z&:"V<	>>Bd#TZd>[!ll:6  c * 	(w7<<&w<W!mm$2M2M2OP<<(;J]J]ehi68 	(u5::W:UMM0G0G
0ST&9HYHYadeg6 ':.2.G.GsTg6 ||M2s':\(DEJJPV]dJe--/||LVYZvG4.$*E*EF ll=1c0 \\+.
Sr3 ll:.f3t&I[S[[bY_=`affh#&<<#CKK]_hnLo#p   %%' Z0SAF]3;;BW];^_ddf#&<<Cckk_ajpNq#r   %%' j1c$QG^,S[[bY_=`affh$'LLcPSP[P[aclrPs$t!!!&&( ||J/vC6J\S[[bY_=`affh"%,,|#CKK]_hnLo"p$$& ll=1fT2 ll;5I'*{{6'JLg& \\+4^&)kkr&:<
W% M"||KASZdmop 	$$[{$C$$YY$?$$[{$C$$XH$= 	##Ks#;##IS#9##Ks#;##HC#8  #}}[UYUiUiUoUop&&6J6N6N&O!!vF4g!V!!wSw!G 	""$r.   c           	      8   U R                   R                  S5      n[        R                  " U5      nUR	                  SSSSS9  [        R
                  " US[        R                  " SSS9S	9nUR	                  S
S9  [        R                  " U5      nUR	                  SSS9  [        R
                  " US[        R                  " SSS9S	9R	                  SS9  U R                  5       nU(       a  [        R                  " [        U R                  5      S9n[        R                  " UUUU R                  S9nUR	                  SS9  [        R
                  " USU R                  U R                  SS5       3[        R                  " SS9S	9nUR	                  SS9  [        R                  " USU R                  S9n	U	R	                  SS9  O5[        R
                  " US[        R                  " SS9S	9R	                  SS9  [        R                  " U5      n
U
R	                  SSS9  [        R
                  " U
S[        R                  " SSS9S	9R	                  SS9  [        R                  " U
5      nUR	                  SSSS9  [        R
                  " US [        R                  " S!SS9S	9R	                  S"S#S$9  [        R                   " US%S&S'U R"                  S(9U l        U R$                  R'                  U R(                  5        U R$                  R	                  SSSS9  [        R
                  " USU R(                   3S)9U l        U R*                  R	                  S*S9  [        R                  " U
5      nUR	                  SSSS9  [        R
                  " US+[        R                  " S!SS9S	9R	                  S"S#S$9  [        R                   " US,S-S.U R,                  S(9U l        U R.                  R'                  U R0                  5        U R.                  R	                  SSSS9  [        R
                  " USU R0                   3S)9U l        U R2                  R	                  S*S9  [        R                  " U
5      nUR	                  SSSS9  [        R
                  " US/[        R                  " S!SS9S	9R	                  S"S#S$9  [        R                   " US0SS1U R4                  S(9U l        U R6                  R'                  U R8                  5        U R6                  R	                  SSSS9  [        R
                  " USU R8                   3S)9U l        U R:                  R	                  S*S9  [        R                  " US2U R<                  S'S39nUR	                  SS9  g4)5z>Create the settings tab with threshold and sensitivity slidersSettingsrO   Tr^   rQ   zRecognition SettingsrV   rW   rZ   )r   r   r_   rv   r]   rw   zCamera Selection:r   rz   r   )valuesvariablery   r{   	Current: r   r   r   zRefresh Camerasrx   zNo cameras detectedzRecognition Settings:)rP   rP   rP   r   zConfidence Threshold:r~   r   r   r   2   r   r   )from_tonumber_of_stepsry   r   r   zDetection Sensitivity:g      ?g       @r   zMin Neighbors:   	   zSave Settingsr   N)rf   r   r   ra   rb   rc   rd   get_available_camerasr   strr   CTkOptionMenuon_camera_changeget_camera_display_namer   refresh_cameras	CTkSlideron_threshold_changethreshold_sliderr   r   threshold_labelon_sensitivity_changesensitivity_sliderr    sensitivity_labelon_neighbors_changeneighbors_sliderr!   neighbors_labelsave_settings)r*   settings_tabr   rk   r   available_cameras
camera_varcamera_dropdowncamera_inforefresh_buttonrecognition_framethreshold_framesensitivity_frameneighbors_framesave_buttons                  r+   ri   &FaceRecognitionApp.create_settings_tabO  s   }}((4 \2t"2F ll=7M&)kkr&&IKg& ||M2s1\(;"V<	>>Bdd>P !668S1J1J-KLJ!//5F7A6:6K6KMO   a ( ,,|,5d6R6RSWSlSlnoqr6s5t*u*-++2*>@K !$ !]]<>O040D0DFNQ'LL,A [[b13374Q4<  LL7Cg6&-D"V<	>>Bdd>Q ,,'89#BQ7_+B"V<	>>Bd#TZd>[ #oRC<?IaIa!c!!$";";<"""1"="||OIdNgNgMhBij!!v!.  LL):;Cbq9&-E"V<	>>Bd#TZd>["%--0AQT>A4KeKe#g##D$>$>?$$#BQ$?!$.?	RVRlRlQmFn!o###0 ,,'89#BQ7_+;"V<	>>Bd#TZd>[ #oQ2<=tG_G_!a!!$"4"45"""1"="||OIdN`N`MaBbc!!v!. mmM+/+=+=SJb!r.   c                 l    [         R                  " 5       nUR                  SS9nUR                  S5      $ )z&Get the first day of the current monthr   )dayr   )r   r   replacer   )r*   today	first_days      r+   r   )FaceRecognitionApp.get_first_day_of_month  s.    MMaM(	!!*--r.   c                     U R                   R                  U R                  5       5        U R                  R                  [        R
                  " 5       R                  S5      5        U R                  5         g)zSet date range to current monthr   N)r   r   r   r   r   r   r   r   r)   s    r+   r   'FaceRecognitionApp.set_this_month_range  sP     ; ; =>hlln55jAB""$r.   Nc                 $    U R                  5         g)z5Filter attendance data based on search and date rangeN)r   )r*   events     r+   r   )FaceRecognitionApp.filter_attendance_data  s    ""$r.   c                     U R                   R                  5        H  nU R                   R                  U5        M      U R                  R	                  5       nU R
                  R	                  5       nU R                  R	                  5       R                  5       n/ nU R                   H  nUR	                  SS5      R                  S5      S   nU(       a  U(       a  X's=::  a  U::  d  O  ME  U(       aL  UR	                  SS5      R                  5       nUR	                  SS5      R                  5       n	XH;  a  XI;  a  M  UR                  U5        M     U Hb  nU R                   R                  SSUR	                  SS5      UR	                  SS5      UR	                  SS5      UR	                  SS5      4S	9  Md     U R                  U5        g! [         a  n
[        S
U
 35         Sn
A
gSn
A
ff = f)z#Load attendance data into the tabler     r   r   r   endr   r   z Error loading attendance table: N)r   get_childrendeleter   getr   r   lowerr#   splitappendinsertupdate_statisticsrA   r?   )r*   item
start_dateend_datesearch_termfiltered_datarecordrecord_dateuser_id	user_namerE   s              r+   r   (FaceRecognitionApp.load_attendance_table  s   *	:,,99;$$++D1 < ,,002J((,,.H//--/557K M--$jjb9??DQG (&AA  $jjB7==?G &

; ; A A CI"1k6R $$V, .$ ($$++BJJ{B/JJy"-JJ{B/JJx,	?+  ( ""=1 	:4QC899	:s   GG 
G1G,,G1c                     [        U5      n[        U Vs/ s H  o3R                  S5      S:X  d  M  UPM     sn5      n[        U Vs/ s H  o3R                  S5      S:X  d  M  UPM     sn5      n[        5       nU H/  nUR                  SS5      nU(       d  M  UR                  U5        M1     [        U5      n	U R                  R                  [        U5      S9  U R                  R                  [        U5      S9  U R                  R                  [        U5      S9  U R                  R                  [        U	5      S9  gs  snf s  snf ! [         a  n
[        SU
 35         Sn
A
gSn
A
ff = f)	zUpdate statistics labelsr   Check-in	Check-outr   r$  r   zError updating statistics: N)r@   r*  r   r   r   r   r   r   r   r   rA   r?   )r*   datatotal_recordsr1   checkins	checkoutsunique_usersr5  r7  active_usersrE   s              r+   r/  $FaceRecognitionApp.update_statistics  s<   	5IMtMt!uuX*/LAtMNHO1h;0NQOPI 5L **Y37 $$W-  |,L $$..C4F.G$$..CM.B%%//S^/D##--3|3D-E NO   	5/s344	5sE   E EEE E	$E	*-E B(E 
E 
E0E++E0c                 p    [        U5      U l        U R                  R                  SU R                   3S9  g)zHandle threshold slider changer   r   N)intr   r  r   r*   r   s     r+   r  &FaceRecognitionApp.on_threshold_change  s3    $'J!&&i8Q8Q7R,S&Tr.   c                 r    [        US5      U l        U R                  R                  SU R                   3S9  g)z Handle sensitivity slider change   r   r   N)roundr    r  r   rF  s     r+   r  (FaceRecognitionApp.on_sensitivity_change  s5    %*5!_"((	$:T:T9U.V(Wr.   c                 p    [        U5      U l        U R                  R                  SU R                   3S9  g)zHandle neighbors slider changer   r   N)rE  r!   r
  r   rF  s     r+   r  &FaceRecognitionApp.on_neighbors_change  s3     Z&&i8J8J7K,L&Mr.   c                 j   U R                   U R                  U R                  U R                  S.n [	        SS5       n[
        R                  " XSS9  SSS5        [        R                  " SS5        g! , (       d  f       N&= f! [         a$  n[        R                  " S	S
U 35         SnAgSnAff = f)zSave current settings)r   r    r!   r   zapp_settings.jsonr   rI  )indentNSuccesszSettings saved successfully!r0   zFailed to save settings: )r   r    r!   r   r<   r=   dumpr   showinforA   r6   )r*   settingsrD   rE   s       r+   r   FaceRecognitionApp.save_settings  s     %)$=$=%)%?%?!//$($=$=	
	K)3/1		(a0 0	+IJ 0/  	K  ,EaS*IJJ	Ks.   B A3B 3
B=B 
B2B--B2c                 .    [         R                  " U R                  5      U l        U R                  R	                  5       (       d%  [
        R                  " SSU R                   35        gU R                  R                  [         R                  S5        U R                  R                  [         R                  S5        [        SU R                   S35        g! [         a1  n[
        R                  " SSU R                   S	U 35         SnAgSnAff = f)
zInitialize and start the camerar0   zCould not open camera Ni  rs   u   ✅ Camera z started successfullyzFailed to start camera z: )r7   VideoCapturer   r   isOpenedr   r6   r   CAP_PROP_FRAME_WIDTHCAP_PROP_FRAME_HEIGHTr?   rA   )r*   rE   s     r+   r(   FaceRecognitionApp.start_camera+  s    	f''(A(ABDH88$$&&$$W0FtG`G`Fa.bc HHLL1137HHLL22C8K 9 9::OPQ 	f  ,CDD]D]C^^`ab`c*dee	fs   A(C +A-C 
D#'DDc                 H   U R                   (       d  SU l         U R                  R                  SS9  U R                  R                  SS9  U R                  R                  SS9  [
        R                  " U R                  SS9U l        U R                  R                  5         gg)	zStart face recognition loopTr|   r}   normalzStatus: Recognition Activer   )targetdaemonN)
r   r   r   r   r   	threadingThreadrecognition_looprecognition_threadstartr)   s    r+   r   $FaceRecognitionApp.start_recognition<  s    "DO''j'9&&X&6''-I'J '0&6&6d>S>S\`&aD###))+ r.   c                     SU l         U R                  R                  SS9  U R                  R                  SS9  U R                  R                  SS9  g)zStop face recognition loopFr]  r\  r|   zStatus: Stoppedr   N)r   r   r   r   r   r)   s    r+   r   #FaceRecognitionApp.stop_recognitionH  sO    ##(#3"""4##):#;r.   c           
         U R                   (       Ga   U R                  R                  5       u  pU(       d  M8  [        R                  " U[        R
                  5      n[        R                  " U[        R                  5      nU R                  R                  UU R                  U R                  U R                  S9nU GHn  u  pgp[        R                  " X6U4Xh-   Xy-   4SS5        Sn
[        R                  " X6U4Xj-   U4SS5        [        R                  " X6U4XgU
-   4SS5        [        R                  " X6U-   U
-
  U4Xh-   U4SS5        [        R                  " X6U-   U4Xh-   Xz-   4SS5        [        R                  " X6Xy-   U
-
  4XgU	-   4SS5        [        R                  " X6Xy-   4Xj-   Xy-   4SS5        [        R                  " X6U-   U
-
  Xy-   4Xh-   Xy-   4SS5        [        R                  " X6U-   Xy-   U
-
  4Xh-   Xy-   4SS5        U R                  (       d  GM^  [        U5      S:  d  GMp  XGXy-   2XfU-   24   n[        R                   " US5      n[        R"                  " U5      n U R                  R%                  U5      u  pU R&                  R)                  [+        U5      0 5      R)                  SS	U 35      nU S
US S3n[        R,                  " X?XgS-
  4[        R.                  SSS5        XR0                  :  a(  U R3                  XU5      nU R5                  XSU5        GMn  GMq     [:        R<                  " U5      n[>        R@                  " U5      nU RB                  RE                  USS9  UU RB                  l#        [        RH                  " S5        U R                   (       a  GM  gg! [6         a  n[9        SU 35         SnAGM  SnAff = f! [6         a  n[9        SU 35         SnAGM  SnAff = f)z+Main recognition loop with attendance logic)scaleFactorminNeighborsminSize)r      r   rI  r^      r   )r   r   namezUser  (.1f)rP   gffffff?
RecognizedzRecognition error: Nr$  )imager[   r   zError in recognition loop: )%r   r   r;   r7   cvtColorCOLOR_BGR2RGBCOLOR_BGR2GRAYr   detectMultiScaler    r!   r"   	rectangleliner   r@   resizeequalizeHistpredictr   r*  r   putTextFONT_HERSHEY_SIMPLEXr   handle_attendanceadd_to_historyrA   r?   r   	fromarrayr   
PhotoImager   r   rs  waitKey)r*   retframe	frame_rgbgrayfacesrv   r   r   hcorner_sizeface_roir7  
confidencer8  r[   attendance_statusrE   	frame_pilframe_tks                       r+   rb  #FaceRecognitionApp.recognition_loopO  s   oooK!XX]]_
  LL0A0AB	 ||E3+=+=>)):: $ : :!%!3!3 MM	 ;  %*LQ1MM)Vac13ZaP #%KHHYA!0DkSTUHHYAO0DkSTUHHYQ)<a(@15!*k[\]HHYQ
QUAO4Lk[\]HHYAEK,?(@1!e*k[\]HHYAE
Q_ae4Lk[\]HHYQ)<ae(DquaenVacdeHHYQ0C(DquaenVacde 3u:>#'!#q1u#5#&::h
#C#&#3#3H#==26//2I2I(2S/G )-(:(:3w<(L(P(PQW[`ah`iYj(kI '0[:c2B!#DDKK	!rT&)&>&>[RSU  *,E,EE484J4J7_i4j 1 $ 3 3I<Yj k  FK %*Z "OOI6	"--i8 !!++(+D*2!!' BQ ooox  ) =!$7s";<<=  3A378sU   #O GO O /;O +B?N5*A5O 5
O?OO OO 
P &O;;P c                 `    [         R                  " 5       nUR                  S5      nUR                  S5      nX`R                  ;  a  0 U R                  U'   U R                  U   R	                  [        U5      0 5      nSU;  a!  SnUSS.U R                  U   [        U5      '   OQUR	                  S5      c   SnXPR                  U   [        U5         S'   OSnXPR                  U   [        U5         S'   U R                  XQX(5        U$ ! [         a  n	[        S	U	 35         Sn	A	g
Sn	A	ff = f)zOHandle attendance logic: first recognition is check-in, subsequent is check-outz%Y-%m-%d %H:%M:%Sr   check_inr;  N)r  	check_outr  r<  zError handling attendance: r0   )	r   r   r   r$   r*  r   save_attendance_recordrA   r?   )
r*   r7  r8  r  r   	timestampr  user_attendancer  rE   s
             r+   r  $FaceRecognitionApp.handle_attendance  s3   #	,,.C%89ILL,E 111/1%%e,"33E:>>s7|RPO 0$.! )!%>%%e,S\: !$$[19$/!JS%%e,S\:;G %0!JS%%e,S\:;G ''	IY$$ 	/s34	s   DD 
D-D((D-c                     Sn[         R                  R                  U5      =(       a"    [         R                  R                  U5      S:  n[	        USSS9 n[
        R                  " U5      nU(       d  UR                  / SQ5        UR                  XX4/5        SSS5        U R                  5         g! , (       d  f       N= f! [         a  n	[        SU	 35         Sn	A	gSn	A	ff = f)	z"Save attendance record to CSV filerH   r   ar$  )newliner   Nz Error saving attendance record: )r3   r4   r5   getsizer<   rI   writerwriterowr&   rA   r?   )
r*   r  r7  r8  statuscsv_filefile_existsfiler  rE   s
             r+   r  )FaceRecognitionApp.save_attendance_record  s    	:+H''..2Trwwx7PST7TKhR0DD)"OO$STY GH	 1 %%' 10  	:4QC899	:s1   AC AB4C 4
C>C 
C'C""C'c           	          [         R                  " 5       R                  S5      nU R                  R	                  SSXQUS X44S9  [        U R                  R                  5       5      S:  a7  U R                  R                  U R                  R                  5       S   5        g	g	! [         a  n[        SU 35         S	nAg	S	nAff = f)
z!Add recognition result to historyz%H:%M:%Sr$  r   rp  r'  r   zError adding to history: N)
r   r   r   r   r.  r@   r(  r)  rA   r?   )r*   r8  r  r  r  r  rE   s          r+   r  !FaceRecognitionApp.add_to_history  s    	3 //
;I $$RIZX[L\_e3y$z 4$$1134s:!!(():):)G)G)I")MN ;  	3-aS122	3s   B!B% %
C/CCc                 |    U R                   R                  5        H  nU R                   R                  U5        M      g)zClear recognition historyN)r   r(  r)  )r*   r0  s     r+   r    FaceRecognitionApp.clear_history  s/    %%224D$$T* 5r.   c                    / n[        S5       H  n[        R                  " U5      nUR                  5       (       d  M0  [	        UR                  [        R                  5      5      n[	        UR                  [        R                  5      5      nU R                  X$U5      nUR                  U5        UR                  5         M     U$ )z3Get list of available cameras with meaningful namesrP   )ranger7   rV  rW  rE  r*  rX  rY  r   r-  release)r*   r  ir   rt   ru   camera_names          r+   r   (FaceRecognitionApp.get_available_cameras  s     rA""1%C||~~CGGC$<$<=>SWWS%>%>?@ #::1VL!((5  ! r.   c                     [         R                  " 5       nUS:X  a  US:  d  US:  a	  SU SU S3$ SU SU S3$ US:X  a  S	U;   d  S
U;   a	  SU SU S3$ SU SU S3$ SU SU SU S3$ ! [         a  nSU SU SU S3s SnA$ SnAff = f)z,Get a meaningful display name for the camerar   i  i8  zMacBook Built-in Camera (rv   rq  zBuilt-in Camera (r   AVFoundationDarwinziPhone/External Camera (zExternal Camera (zCamera ro  N)r7   getBackendNamerA   )r*   indexrt   ru   backendrE   s         r+   r   *FaceRecognitionApp.get_camera_display_name  s    	8((*G zD=FdN6ugQvhaHH.ugQvha@@!!W,G0C5eWAfXQGG.ugQvha@@ !r%&;; 	8UG2eWAfXQ77	8s3   /A+ A+ A+ A+ A+ +
B5B BBc                     U R                  U5      nUb  X R                  :w  a  U R                  (       a9  U R                  R                  5       (       a  U R                  R	                  5         X l        U R                  5         U R                  USS5      nU R                  R                  SU 3S9  ggg! [         a  n[        SU 35         SnAgSnAff = f)zHandle camera selection changeNr   zStatus: Switched to r   zError changing camera: )extract_camera_indexr   r   rW  r  r(   r   r   r   rA   r?   )r*   camera_selectioncamera_indexr  rE   s        r+   r   #FaceRecognitionApp.on_camera_change  s    	1445EFL'L<U<U,U88 1 1 3 3HH$$& -9) !!# #::<AN!!++3G}1U+V -V'  	1+A3/00	1s   B2B7 7
CCCc                 ~    SU;   aQ  UR                  5       n[        U5       H1  u  p4US:X  d  M  US-   [        U5      :  d  M!  [        X#S-      5      s  $    OSU;   a  gSU;   d  SU;   a  gSSKnUR                  SU5      nU(       a  [        US   5      $  g! [         a  n[        S	U 35         SnAgSnAff = f)
z1Extract camera index from camera selection stringCamerar   zBuilt-inr   iPhoneExternalNz\d+zError extracting camera index: )r,  	enumerater@   rE  refindallrA   r?   )r*   r  partsr  partr  numbersrE   s           r+   r  'FaceRecognitionApp.extract_camera_index4  s    	9++(..0(/GAx'AECJ,>"5Q<00  0 //--?O1O jj)9:G71:&    	93A3788	9s4   *B B B 	B  B -*B 
B<$B77B<c                 2    [         R                  " SS5        g)zRefresh available cameras listRefreshz@Camera list refreshed. Close and reopen settings to see changes.N)r   rR  r)   s    r+   r   "FaceRecognitionApp.refresh_camerasN  s     	I'ijr.   c                     SU l         U R                  (       a  U R                  R                  5         U R                  R	                  5         g)zHandle application closingFN)r   r   r  r   destroyr)   s    r+   
on_closingFaceRecognitionApp.on_closingT  s0    88HH		r.   c                     U R                   R                  SU R                  5        U R                   R                  5         g)zRun the applicationWM_DELETE_WINDOWN)r   protocolr  mainloopr)   s    r+   runFaceRecognitionApp.run[  s+    		-t?		r.   )"r   r#   r   r   r   r   r   r   r   r    r   r   r   r   r!   r"   r
  r	  rf   rc  r   r   r   r  r  r   r   r   r   r  r  r$   r   r   )N)$__name__
__module____qualname____firstlineno__r,   r%   r&   r'   rg   rh   ri   r   r   r   r   r/  r  r  r  r  r(   r   r   rb  r  r  r  r   r   r   r   r  r   r  r  __static_attributes__ r.   r+   r   r      s    BI:9#0K#ZD%Le"N.%%,:\50U
X
N
K f"
,<N`%N:&3+
!(86104kr.   r   __main__)__doc__r7   numpynpcustomtkinterr   tkinterr   r   r3   r=   rI   r   r   r`  PILr   r   calendarpathlibr	   timeset_appearance_moder   r  appr  r  r.   r+   <module>r     sp   
    # 	  
 (         F FP z

CGGI r.   