
    JiI                        d dl mZmZmZ d dlmZ d dlmZmZm	Z	 d dl
m
Z
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mZ d dlmZ d dlZ ej@                  e!      Z" e       Z# G d d      Z$e#jK                  d      dddd ee      fde&de&de&de&def
d       Z'e#jK                  d      dd ee      fde(de	e(   de	e(   defd       Z)y)    )	APIRouterDependsHTTPException)Session)ListDictOptional)datetime	timedeltatimezoneN)get_db)ActivityRecord)Config)DeveloperDiscovery)FixedDeveloperDiscovery)DynamicActivityWatchClient)ActivityCategorizer)extract_project_infoc                       e Zd ZdZdefdZ	 	 	 	 ddededededef
d	Zdefd
Z	dededededef
dZ
dedefdZdedee   fdZy) EnvironmentBasedDeveloperServicezMService to handle developer list based on environment - Fixed for existing DBdbc                 2    || _         t        |      | _        y )N)r   r   	discovery)selfr   s     AE:\timesheet\timesheet_new\backend\fixed_dynamic_developer_api.py__init__z)EnvironmentBasedDeveloperService.__init__   s    04    scan_network
scan_localscan_databaseforce_refreshreturnc                 r    t        j                         r| j                         S | j                  ||||      S )z>Get developers list based on environment (local vs production))r   is_local_get_local_developer_only_get_all_developers)r   r   r   r    r!   s        r   get_developers_listz4EnvironmentBasedDeveloperService.get_developers_list   s5     ??1133++L*mUbccr   c                    	 t        j                         }t        j                  xs |}ddlm} | j                  j                   |d      d|i      j                         }|r|d   }|d   }n|}t        j                  d| d       | j                  j                         }g }|r|D ]  }|j                  d|d	    |||d
   |d	   ddd|j                  d| d|d	          || j                  |      t!        j"                  t$        j&                        j)                         |j                  dd      |j                  dd      d        nc| j                  |      }	|j                  d| ||dd|	dkD  rdnd|	dkD  rdnd|	dkD  rd|	 dnd|||	| j+                  |      |	dkD  rdnddd       |dt-        |      t!        j"                  t$        j&                        j)                         |dt/               v r|dS |dS # t0        $ r}
t        j3                  d|
        d t        j                  t        j                         ddddd!t        j                         t        j                  dd"dddgddt!        j"                  t$        j&                        j)                         t        j                  t5        |
      d#cY d"}
~
S d"}
~
ww xY w)$z'Return only the current local developerr   textz
                SELECT developer_id, name 
                FROM developers 
                WHERE name = :dev_name OR developer_id = :dev_name
                LIMIT 1
            dev_name   zLocal developer 'z' not found in developers tablelocal_porthostonlinelocalzLocal ActivityWatch instance	device_id_versionunknownbucket_count)idnamehostnamer/   r.   statussourcedescriptionr2   developer_idactivity_count	last_seenr4   r6   	local_db_	localhosti  database_onlyofflinedatabasezLocal developer (z activities in database)zLocal developer (no data yet)local_developer_id)
developersenvironmenttotal_countdiscovered_atlocal_developerrE   zError getting local developer: local_fallbackz Local developer (database error)N)rF   rG   rH   rI   rJ   error)socketgethostnamer   LOCAL_DEVELOPER_NAME
sqlalchemyr*   r   executefetchoneloggerwarningr   discover_local_instancesappendget_get_activity_count_safer
   nowr   utc	isoformat_get_last_activity_time_safelenlocals	ExceptionrL   str)r   local_hostnamelocal_developer_namer*   
dev_resultrE   local_instancesrF   instancedb_activity_countes              r   r%   z:EnvironmentBasedDeveloperService._get_local_developer_only'   s   g	#//1N#)#>#>#P.  ( / * 0 xz  %/]"'1!}$%9"!23G2HHghi #nnEEGOJ /H%% &x'7&89 4$2 ( 0 ( 0"*"))E%-\\+.AQQRS[\bScRd?e%f(:*.*G*GHZ*[%-\\(,,%?%I%I%K#+<<	9#E(0^Q(G'  !0& %)$A$ABT$U!!!%n%560 .' 1BQ1FoI,=,Ajwfwz{f{%67H6IIa#b  Da!/$6&7!%!B!BCU!V->-Bz	$%# $ )&":!)hll!;!E!E!G#7<PTZT\<\&8  cw   	LL:1#>? +"77 & 2 2 4' '%#E!'!3!3!5$*$?$?&'!%($%     ' !)hll!;!E!E!G#)#>#>Q+ 	s%   G?H H 	KB6KKKc                    	 t         j                  d       | j                  j                  |||      }|D ]  }|j	                  d      xs |j	                  d      }| j                  |      |d<   |j	                  d      rM| j                  |      |d<   |d   sgt        |d   t              r|d   j                         n|d   |d<    |dt        |      t        j                  t        j                        j                         dd	S # t        $ r6}t         j                  d
|        t!        ddt#        |             d}~ww xY w)z5Get all developers from all sources (production mode)z&Performing full developer discovery...)r   r   r    r=   r7   r>   r?   
productionF)rF   rG   rH   rI   
from_cachez"Error discovering all developers:   zError discovering developers: status_codedetailN)rS   infor   discover_all_developersrW   rX   r\   
isinstancer
   r[   r]   rY   r   rZ   r_   rL   r   r`   )	r   r   r   r    r!   discovered_developersdevdev_idrg   s	            r   r&   z4EnvironmentBasedDeveloperService._get_all_developers   sU   	cKK@A$(NN$J$J)%+ %K %! -0ACGGDM(,(E(Ef(M$%ww{+'+'H'H'PC$;'KUVYZeVfhpKq3{+;+E+E+Gwz  |G  xHK( - 4+"#89!)hll!;!E!E!G#   	cLL=aSABC:XY\]^Y_X`8abb	cs%   BD D A/D 	E1EEdeveloper_id_or_namec                    	 ddl m}m} | j                  j	                   |d      ||d      j                         }|r?|d   }| j                  j	                   |d      d|i      }|j                         }|xs dS y# t        $ r}t        j                  d| d|        	 | j                  j	                   d	            }|j                         }	t        j                  d
|	        |	xs dcY d}~S #  Y Y d}~yxY wd}~ww xY w)z)Safely get activity count for a developerr   )funcr*   
                SELECT developer_id 
                FROM developers 
                WHERE developer_id = :dev_id OR name = :dev_name
                LIMIT 1
            rt   r+   z
                    SELECT COUNT(*) 
                    FROM activity_records 
                    WHERE developer_id = :dev_id
                rt   z!Error getting activity count for : z%SELECT COUNT(*) FROM activity_recordsz Returning total activity count: N)rP   rw   r*   r   rQ   rR   scalarr_   rS   rT   ro   )
r   ru   rw   r*   rc   r=   resultcountrg   totals
             r   rX   z9EnvironmentBasedDeveloperService._get_activity_count_safe   s   '	-  / * /0 xz  )!} / *
 l	 z! 		NN>?S>TTVWXVYZ[.U)VW>ugFGz!		s7   A;A? ?	DD$AC82D8D :D DDc                 x   	 ddl m} | j                  j                   |d      ||d      j	                         }|rM|d   }| j                  j                   |d      d|i      }|j                         }|r|j                         S dS y# t        $ r%}t        j                  d| d	|        Y d}~yd}~ww xY w)
z-Safely get last activity time for a developerr   r)   rx   ry   z
                    SELECT MAX(timestamp)
                    FROM activity_records 
                    WHERE developer_id = :dev_id
                rt   Nz%Error getting last activity time for rz   )
rP   r*   r   rQ   rR   r{   r[   r_   rS   rT   )r   ru   r*   rc   r=   r|   	last_timerg   s           r   r\   z=EnvironmentBasedDeveloperService._get_last_activity_time_safe   s     	'  / * /0 xz  )!} / *
 l	 #MMO	09y**,CtC 	NNBCWBXXZ[\Z]^_	s   BB B 	B9B44B9N)FTTF)__name__
__module____qualname____doc__r   r   boolr   r'   r%   r&   r`   intrX   r	   r\    r   r   r   r      s    W57 5 8=.21516	d 	d'+	d*.	d +/	d <@	di4 iV c  c$  c*. c?C cHL cD)S )S )V" "RU "r   r   z/developersFTr   r   r    r!   r   c                 H   K   t        |      }|j                  | |||      S w)z(Get developers list based on environment)r   r'   )r   r   r    r!   r   services         r   r'   r'     s*      /r2G&&|ZP]^^s    "z/activity-data/{developer_id}r=   
start_dateend_datec                 	   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        |      }|j                         }t         fd|d   D        d      }	|	st        dd	
      g }
d}|	d   dk(  rX	 t        |	      }|j                         r<|j                  ||      }
d}t        j                  d|	d    dt!        |
       d       |
sQ	 ddlm} |j+                   |d      |	j-                  d      xs |	d   ||d      j/                         }|D cg c]  }|j0                  |j2                  xs |	d   |j4                  |j6                  |j8                  xs d|j:                  r|j:                  j=                         nd|j>                  xs d|j@                  xs |j6                  |jB                  xs d|jD                  xs d|jF                  |jH                  |jJ                  d }
}d}t        j                  d|	d    dt!        |
       d       |
D ]  }|j-                  d      sStO        |      }|j-                  d      xs d|d<   |j-                  d      xs d |d<   |j-                  d!      xs d"|d!<   |jQ                  |j-                  d#d      |j-                  d$d            }|d%   |d%<   |d&   |d&<   |d'   |d(<    ddd)ddd)ddd)ddd)ddd)d*}|
D ]I  }|j-                  d%d+      }||v s||   d,xx   d-z  cc<   ||   d.xx   |j-                  d.d      z  cc<   K tS        d/ |
D              }|D ].  }|dkD  rtU        ||   d.   |z  d0z  d-      ||   d1<   'd||   d1<   0 |
|	|||j=                         |j=                         d2t!        |
      |d3S # t"        $ r)}t        j%                  d|	d    d|        Y d}~d}~ww xY wc c}w # t"        $ r%}t        jM                  d|        g }
Y d}~d}~ww xY w# t"        $ r9}t        jM                  d4  d|        t        d5d6tW        |       
      d}~ww xY ww)7z*Get activity data for a specific developerZz+00:00r   )hourminutesecondmicrosecondc              3   4   K   | ]  }|d    k(  s|  yw)r7   Nr   ).0dr=   s     r   	<genexpr>z.get_developer_activity_data.<locals>.<genexpr>+  s      `%D$S_H_!%Ds   rF   Ni  zDeveloper not foundrl   rD   r:   r0   activitywatchzRetrieved live data for r8   rz   z activitieszFailed to get live data for r)   a  
                    SELECT 
                        ar.application_name,
                        ar.window_title,
                        ar.duration,
                        ar.timestamp,
                        ar.category,
                        ar.detailed_activity,
                        ar.url,
                        ar.file_path,
                        ar.developer_id,
                        ar.project_name,
                        ar.project_type,
                        ar.project_file,
                        d.name as developer_name
                    FROM activity_records ar
                    LEFT JOIN developers d ON ar.developer_id = d.developer_id
                    WHERE ar.developer_id = :dev_id
                    AND ar.timestamp >= :start_date
                    AND ar.timestamp <= :end_date
                    ORDER BY ar.duration DESC
                    LIMIT 1000
                r=   )rt   r   r   Other )r=   developer_nameapplication_namewindow_titleduration	timestampcategorydetailed_activityurl	file_pathproject_nameproject_typeproject_filezRetrieved database data for z Error getting database records: r   
Unassignedr   Generalr   Activityr   r   r   subcategory
confidencecategory_confidence)r}   r   )
productivebrowserserverznon-workuncategorizedr   r}   r,   r   c              3   &   K   | ]	  }|d      yw)r   Nr   )r   items     r   r   z.get_developer_activity_data.<locals>.<genexpr>  s     H-$T*--s   d   
percentage)startend)data	developerdata_source
total_time
date_ranger>   category_summaryz Error getting activity data for rk   zError getting activity data: ),r   r
   fromisoformatreplacerY   r   rZ   r   r'   nextr   r   test_connectionget_activity_datarS   ro   r]   r_   rT   rP   r*   rQ   rW   fetchallr=   r   r   r   r   r   r[   r   r   r   r   r   r   r   rL   r   get_detailed_categorysumroundr`   )r=   r   r   r   categorizerr   r   r   developers_resultr   activity_datar   clientrg   r*   
db_recordsrecordactivityproject_infocategory_infor   cattotal_durations   `                      r   get_developer_activity_datar     s[    W^)+ **:+=+=c8+LMELL.66AaPQ_`6aE(()9)9#x)HIC,,x||,C 326#779`%6|%D`bfg	C8MNN  X(*X3I>))+$*$<$<UC$HM"1KKK":9V;L:MRPSTaPbOccn op 5#+  ZZ . ). (mmN;Py?P"' #-4 8:5 T !+!, !+f %+$7$7&,&;&;&Py?P(.(?(?$*$7$7 & 41AGAQAQ!1!1!;!;!=W[ & :7)/)A)A)XVEXEX!::+!'!1!1!7R$*$7$7$*$7$7$*$7$7" !+  !,  ):9V;L:MRPSTaPbOccnop &H<</3H=+7+;+;N+K+[|(+7+;+;N+K+Xy(+7+;+;N+K+Yz( (==^R0/4M $1#<HZ &3M&BH]#.;L.IH*+# &* %&15!"2 !q1"#3'(a8
 &H,,z?;C&& %g.!3. %j1X\\*a5PP1	 & H-HH $C!6;=Mc=RS]=^ao=osv<vxy6z %l367 %l3	 $ ""&($)OO$5cmmoN!-0 0
 	
Q  X!=i>O=PPRSTRUVWWXJ!,&  #?sCD "#t  ^7~RsKL6STWXYTZS[4\]]^s   S3DR. AQ R. "A
Q= ,CQ8,Q= 2C'R. B(R. S3	Q5Q0*R. 0Q55R. 8Q= =	R+R& R. &R++R. .	S074S++S00S3)*fastapir   r   r   sqlalchemy.ormr   typingr   r   r	   r
   r   r   osloggingrD   r   modelsr   configr   developer_discoveryr   fixed_developer_discoveryr   dynamic_activitywatch_clientr   activity_categorizerr   improved_project_extractorr   rM   	getLoggerr   rS   routerr   rW   r   r'   r`   r   r   r   r   <module>r      s+   5 5 " ' ' 2 2 	   !  2 = C 4 ; 			8	$	l l^ M&/	_	_	_ 	_ 		_
 		_ 	_ +, !%"&/	^^^^^^ sm^^ 		^^ -^^r   