
    JiM              
       B   d dl mZmZmZmZ d dlmZ d dlmZ d dl	m	Z	m
Z
 d dlmZmZmZ d dlmZ d dlmZ d dlZ e       Zej+                  d	       ed       ed       ee      fd
edee   dee   defd       Zej1                  d       ed       ed       ee      fd
edee   dee   defd       Zej+                  d       ed       ed       ee      fdee   dee   defd       ZdedefdZej+                  d       ee      fd
edefd       Zy)    )	APIRouterDependsHTTPExceptionQuery)Session)text)datetimetimezone)OptionalListDict)get_db)ActivityCategorizerNz'/api/activity-categories/{developer_id}developer_id
start_dateend_datedbc                 Z	  K   	 t               }|r&t        j                  |j                  dd            }n6t        j                  t
        j                        j                  dddd      }|r&t        j                  |j                  dd            }n#t        j                  t
        j                        }t        d      }|j                  || ||d      j                         }t        d|d    d|d	    d
|d    d|d    d|d    
       t        d      }	|j                  |	| ||d      j                         }
i i i i d}ddddddddddddd}d}|
D ]?  }|d   |d	   |d   xs d|d   xs d|d   xs d|d   r|d   j                         nd|d   |d   |d   |d   |d   d}|j                  |d   |d         }|d   j                         }|sd}|d   }||vrd }|||   vr2||d   dd|d!   |d!   ||d"   |d#   |d$   |d%   |d&   |d'   g d(||   |<   ||   |   }|d)xx   |d)   z  cc<   |d*xx   d	z  cc<   |d!   |d+<   |d,   j                  |d-   |d)   |d!   d.       ||   d/xx   d	z  cc<   ||   d)xx   |d)   z  cc<   ||d)   z  }B i }|j!                         D ]  \  }}g }|j!                         D ]  \  }}|d)   }|d0k\  rt#        |d0z  d      |d1<   |d1    d2|d3<   nS|d4k\  r*t#        |d4z  d	      }t#        |d0z  d      |d1<   | d5|d3<   n$t#        |d0z  d      |d1<   t#        |d	       d6|d3<   |j%                  d,d       |j                  |        |j'                  d7 d89       |||<    |D ]  }|dkD  r||   d)   |z  d:z  ||   d;<   nd||   d;<   ||   d)   }|d0z  }t#        |d      ||   d1<   |d0k\  rt#        |d	       d2||   d3<   _|d4k\  rt#        |d4z  d	       d5||   d3<   }t#        |d	       d6||   d3<    i }|j!                         D ]  \  }}|dd ||<    | |j                         |j                         d<|t#        |d0z  d      ||t)        |      d=S # t*        $ r}t-        d>d?t/        |       @      d}~ww xY ww)AzJGet activities categorized into Productive, Browser, and Server categoriesZ+00:00r   hourminutesecondmicroseconda  
            SELECT 
                COUNT(*) as total_records,
                SUM(duration) as total_duration,
                AVG(duration) as avg_duration,
                MIN(duration) as min_duration,
                MAX(duration) as max_duration
            FROM activity_records
            WHERE developer_id = :dev_id
            AND timestamp >= :start_date
            AND timestamp <= :end_date
        dev_idr   r   zDebug - Total records: z, Total duration:    z, Avg:    z, Min:    z, Max:    a  
            SELECT 
                id,
                developer_id,
                application_name,
                window_title,
                duration,
                timestamp,
                url,
                file_path,
                project_name,
                project_type,
                category
            FROM activity_records
            WHERE developer_id = :dev_id
            AND timestamp >= :start_date
            AND timestamp <= :end_date
            ORDER BY timestamp DESC
        )
productivebrowserservernon-work)countduration    N         	   
   )idr   application_namewindow_titler'   	timestampurl	file_pathproject_nameproject_typeexisting_categoryr1   r0   Untitledcategoryr#   r2   subcategory
confidencer3   r4   r5   r6   )r1   r0   r'   activity_countfirst_timestamplast_timestampr9   r:   r;   r3   r4   r5   r6   individual_activitiesr'   r<   r>   r?   r/   )r/   r'   r2   r&     duration_hourshduration_display<   msc                     | d   S )Nr'    )xs    AE:\timesheet\timesheet_new\backend\activity_categorization_api.py<lambda>z,get_categorized_activities.<locals>.<lambda>   s    q}    T)keyreversed   
percentagestartend)r   
date_range
statisticstotal_duration_hoursactivities_by_categorytop_activities_by_categoryproductivity_score  zError categorizing activities: status_codedetail)r   r	   fromisoformatreplacenowr
   utcr   executefetchoneprintfetchall	isoformatget_detailed_categorystripappenditemsroundpopsortcalculate_productivity_score	Exceptionr   str)r   r   r   r   categorizerrR   rS   debug_querydebug_resultqueryresultactivities_groupedcategory_statstotal_durationrowactivitycategory_infowindow_title_keyr9   grouped_activityrW   catgrouped_dictactivities_listr1   duration_secondsduration_minuteshoursrX   
activitieses                                  rJ   get_categorized_activitiesr      s    ^
)+ **:+=+=c8+LMELL.66AaPQ_`6aE(()9)9#x)HIC,,x||,C    zz+"0
  8:	 	 	'Q'88J<XY?J[ \"1o&gl1o->glSToEVX 	Y   ( E"$
  8:	 	 	
 %&15!"2 !q1"#3	
 C!f #A$'FLb #A"FKa36q6SV--/t1v V #A #A%(WH (==(+,M  (7==?##- $Z0H11$  '9('CC %5(01C(D !&''/'<&.{&; (#0#?"/"=#E?!)+!6$,^$<$,^$<-/B"8,-=>$  2(;<LMZ(HZ,@@(-.!3.19+1F-. 45<<tn$Z0%k2>  8$W-2-8$Z0HZ4HH0hz22NG L "$!3!9!9!;C O2>2D2D2F.. $4J#? #t+9>?ORV?VXY9Z$%56>NO_>`=aab;c$%78%+',-=-BA'F$9>?ORV?VXY9Z$%56>N=Oq;Q$%789>?ORV?VXY9Z$%56>CDTVW>X=YYZ;[$%78 $$%<dC&&'78! 3G&   %<d K*9"3'- "<2 'H!"8,Z8>ICO x(6 :;x(6  .h7
C$t+E9>uaN8$%56  4'BGq/ARRS?Tx();<!R'BGHX[]H]_`BaAbbc?dx();<BGHXZ[B\A]]^?_x();<) '. &("5;;=OC.8"o&s+  > )*}} )$).4*?$C&<*D">~"N
 	
  
4SVH=
 	

s)   R+Q<R  R+	R(
R##R((R+z./api/update-activity-categories/{developer_id}c           	      <  K   	 t               }|r&t        j                  |j                  dd            }n6t        j                  t
        j                        j                  dddd      }|r&t        j                  |j                  dd            }n#t        j                  t
        j                        }t        d      }|j                  || ||d      j                         }d}	|D ][  }
|
d   }|
d   xs d}|
d	   xs d}|j                  ||      }t        d
      }|j                  ||d   |d   |d   |d       |	dz  }	] |j                          d|	d|	 ddS # t        $ r.}|j                          t        ddt        |             d}~ww xY ww)z<Update the category field in the database for all activitiesr   r   r   r   z
            SELECT id, window_title, application_name
            FROM activity_records
            WHERE developer_id = :dev_id
            AND timestamp >= :start_date
            AND timestamp <= :end_date
        r   r   r(   r   a  
                UPDATE activity_records
                SET 
                    category = :category,
                    subcategory = :subcategory,
                    category_confidence = :confidence
                WHERE id = :activity_id
            r9   r:   r;   )r9   r:   r;   activity_idTzSuccessfully updated z activities)successupdated_countmessagerZ   zError updating categories: r[   N)r   r	   r^   r_   r`   r
   ra   r   rb   re   rg   commitro   rollbackr   rp   )r   r   r   r   rq   rR   rS   rt   ru   r   ry   r   r1   app_namer{   update_queryr   s                    rJ   update_activity_categoriesr      s    G
)+ **:+=+=c8+LMELL.66AaPQ_`6aE(()9)9#x)HIC,,x||,C    E"$
  8:	 	 Ca&Kq6<RL1v|H (==lHUM   ! L JJ|)*5,];+L9*	&  QM3 6 			 *.}o[I
 	
  

0Q9
 	

s)   FEE" !F"	F+)FFFz/api/category-summaryc                 f  K   	 | r&t        j                  | j                  dd            }n6t        j                  t        j
                        j                  dddd      }|r&t        j                  |j                  dd            }n#t        j                  t        j
                        }t        d      }|j                  |||d      j                         }g }d}|D ]G  }	|	d   |	d   |	d   xs dt        |	d   xs dd	z  d      |	d
   d}
|j                  |
       ||
d   z  }I |D ]%  }|dkD  rt        |d   |z  dz  d      |d<   !d|d<   ' |j                         |j                         d|t        |d	z  d      dS # t        $ r}t        ddt        |             d}~ww xY ww)z?Get summary of all activities by category across all developersr   r   r   r   a  
            SELECT 
                CASE 
                    WHEN category IN ('productive', 'browser', 'server', 'non-work') THEN category
                    ELSE 'browser'
                END as category,
                COUNT(*) as activity_count,
                SUM(duration) as total_duration,
                COUNT(DISTINCT developer_id) as developer_count
            FROM activity_records
            WHERE timestamp >= :start_date
            AND timestamp <= :end_date
            GROUP BY 
                CASE 
                    WHEN category IN ('productive', 'browser', 'server', 'non-work') THEN category
                    ELSE 'browser'
                END
            ORDER BY total_duration DESC
        )r   r   r   r   r@   r    )r9   r<   total_duration_secondsrV   developer_countr   rO   rP   rQ   )rT   summaryrV   rZ   z Error getting category summary: r[   N)r	   r^   r_   r`   r
   ra   r   rb   re   rk   ri   rf   ro   r   rp   )r   r   r   rR   rS   rt   ru   r   rx   ry   category_dataitemr   s                rJ   get_category_summaryr   F  s    J
**:+=+=c8+LMELL.66AaPQ_`6aE(()9)9#x)HIC,,x||,C   ( E$
  8: 	
 CF"%a&*-a&+A(-s1v{d.BA(F#&q6M NN=)m,DEEN  D!%*12^CcI1&\" &'\"  *}} $).4*?$C
 	
  
5c!fX>
 	

s)   F1FF F1	F.F))F..F1rw   returnc                    | j                  di       j                  dd      }| j                  di       j                  dd      }| j                  di       j                  dd      }| j                  di       j                  dd      }||z   }||dz  z  }||z   |z   |z   }||z
  }|dkD  r	||z  dz  }nd}t        t        |d      d	      S )
z;Calculate productivity score based on category distributionr"   r'   r   r$   r#   r%   g      ?rO   r   )getrk   min)	rw   productive_timeserver_timebrowser_timenon_work_timeproductive_total
total_time	work_timescores	            rJ   rn   rn     s    $((r:>>z1MO $$Xr266z1EK!%%i488QGL"&&z26:::qIM '4 s** !;.=MJ ]*I1}!I-4UC!$$rL   z#/api/debug-durations/{developer_id}c                   K   	 t        d      }|j                  |d| i      j                         }g }|D ]  }|d   xs d}|j                  |d   |d   t	        |d      |dk\  rt	        |dz  d       dnt	        |d       dt	        |d	   xs dd      |d
   r|d
   j                         nd|d   r|d   j                         ndd        t        d      }|j                  |d| i      j                         }|d   xs ddz  }	|d   |d   |d   xs dt	        |	d      t	        |d	   xs dd      |d
   |d   dd|ddS # t        $ r}
t        ddt        |
             d}
~
ww xY ww)z7Debug endpoint to check activity durations and groupinga  
            SELECT 
                window_title,
                COUNT(*) as count,
                SUM(duration) as total_duration,
                AVG(duration) as avg_duration,
                MIN(timestamp) as first_seen,
                MAX(timestamp) as last_seen
            FROM activity_records
            WHERE developer_id = :dev_id
            AND timestamp >= CURRENT_DATE
            GROUP BY window_title
            ORDER BY total_duration DESC
            LIMIT 20
        r   r   r   r   rD   rE   rF   r    r!   Nr)   )r1   r<   r   total_duration_displayavg_duration_seconds
first_seen	last_seena  
            SELECT 
                COUNT(*) as total_records,
                COUNT(DISTINCT window_title) as unique_windows,
                SUM(duration) as total_duration_seconds,
                AVG(duration) as avg_duration_seconds,
                MIN(duration) as min_duration_seconds,
                MAX(duration) as max_duration_seconds
            FROM activity_records
            WHERE developer_id = :dev_id
            AND timestamp >= CURRENT_DATE
        r@   z0ActivityWatch records activities every 6 seconds)total_recordsunique_windowsr   rV   avg_duration_per_record_secondsmin_duration_secondsmax_duration_secondsrecording_intervalz@Durations are in seconds. ActivityWatch polls every few seconds.)r   top_activities_groupednoterZ   zError debugging durations: r[   )
r   rb   re   ri   rk   rf   rc   ro   r   rp   )r   r   rt   ru   r   ry   total_secondsstats_querystatstotal_hoursr   s              rJ   debug_activity_durationsr     s    G
    EHl#;<EEG
CFKaM #A"%a&*/q*AN[_aNaU=3CQ-G,H*Jjop}  @A  kB  jC  CD  hE(-c!fk1(=47Fc!f..036q6SV--/t      

;<(@AJJLQx}1, "'q"'(*/(-a(-k1(=38qQ3J(-a(-a&X	 '1V
 	
  
0Q9
 	

s)   E1EE E1	E.E))E..E1)fastapir   r   r   r   sqlalchemy.ormr   
sqlalchemyr   r	   r
   typingr   r   r   databaser   activity_categorizerr   jsonrouterr   rp   r   postr   r   floatrn   r   rH   rL   rJ   <module>r      s   < < "  ' ' '  4 	56 !&d#Dk&/	e
e
e
 sme
 		e
 7e
N => !&d#Dk&/	N
N
N
 smN
 		N
 ?N
` #$ %d#Dk&/P
P
smP
 	P
 %P
d% %% %4 12 &/L
L
L
 3L
rL   