
    JiG              
          d dl mZmZmZ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mZm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 e       Z ej4                  e      Z G d d	e      Zd
ededefdZ d(dededefdZ!d)dededede"fdZ#ejI                  d       edd       ed       ee      fded
ededefd       Z%ejM                  d      d
edefd       Z'ejM                  d      dd ee      fd
edee   d ee   defd!       Z(ejM                  d"      dd ee      fdee   d ee   defd#       Z)ejM                  d$      d%        Z*d&e
defd'Z+y)*    )	APIRouterDependsHTTPExceptionstatusHeaderRequest)Session)ListDictOptionalAny)datetimetimezone	timedeltaN)	BaseModel)get_dbc                   6    e Zd ZU eed<   eed<   eeef   ed<   y)ActivityWatchEvent	timestampdurationdataN)__name__
__module____qualname__str__annotations__floatr   r        7E:\timesheet\timesheet_new\backend\stateless_webhook.pyr   r      s    NO
sCx.r   r   developer_idprovided_tokenreturnc                 z   t        j                  dd      }|  d| dt        j                         j                   }t        j                  |j                               j                         }ddl	}t        j                  |dd       }|j                  |      j                         j                  d      }||k(  S )z;Validate token without database lookup - uses master secretMASTER_SECRETz'your-master-secret-for-token-generation:r   N0   =)osgetenvr   nowyearhashlibsha256encode	hexdigestbase64bytesfromhexurlsafe_b64encodedecoderstrip)r!   r"   master_secrettoken_input
token_hashr1   token_bytesexpected_tokens           r    validate_stateless_tokenr<      s    IIo/XYM "N!M?!HLLN4G4G3HIK 2 2 45??AJ --
3B0K--k:AACJJ3ON^++r   app_namewindow_titlec                 P   | sy| j                         |r|j                         nd}t        fddD              ryt        fddD              ryt        fd	d
D              ryt        fddD              ryt        fddD              ryt        fddD              ryy)z5Categorize application based on name and window titleother c              3   &   K   | ]  }|v  
 y wNr   .0browserapp_name_lowers     r    	<genexpr>z)categorize_application.<locals>.<genexpr>,   s     
n4m7n$4m   )chromefirefoxsafariedgeoperabraverF   c              3   &   K   | ]  }|v  
 y wrC   r   rE   iderG   s     r    rH   z)categorize_application.<locals>.<genexpr>0   s"       b  -aS3.   -arI   )vscodezvisual studiopycharmintellijsublimeatomvimemacsz	notepad++cursorcodedevelopmentc              3   &   K   | ]  }|v  
 y wrC   r   )rE   dbrG   s     r    rH   z)categorize_application.<locals>.<genexpr>4   s     
x*wB2*wrI   )datagrippgadminmysqldbeavernavicat	sqlserveroracledatabasec              3   &   K   | ]  }|v  
 y wrC   r   )rE   prodrG   s     r    rH   z)categorize_application.<locals>.<genexpr>8   s"       `  /_d4>!  /_rI   )wordexcel
powerpointoutlookteamsslackdiscordzoomnotionobsidianpostmanproductivityc              3   &   K   | ]  }|v  
 y wrC   r   )rE   mediarG   s     r    rH   z)categorize_application.<locals>.<genexpr><   s     
s0ru5N"0rrI   )spotifyyoutubevlczmedia playernetflixtwitchentertainmentc              3   &   K   | ]  }|v  
 y wrC   r   )rE   systemrG   s     r    rH   z)categorize_application.<locals>.<genexpr>@   s"       V  3U6^#  3UrI   )	explorerfinderterminalcmd
powershellztask managerlockdwmwinlogonr~   )lowerany)r=   r>   window_title_lowerrG   s      @r    categorize_applicationr   #   s    ^^%N1=++-2 
n4m
nn   b  -a  b  b 
x*w
xx   `  /_  `  ` 
s0r
ss   V  3U  V  Vr   urlc           	         ddd|dd}| s|s|S |r|j                         nd| r| j                         nd}t        fddD              rtd| v rV| j                  d      }t        |      dk\  r6|d	   j	                         }|d
   j	                         }|j                  |dd|v r| d| n|d| d| d       |S t        fddD              r|r	 d	dlm}  ||      }	|	j                  j                  dd      dv sdv r+|j                  d|	j                  xs d dd|  d       |S g d}
t        fd|
D              r|j                  dd|  d       |S 	 d| v r<| j                  d      d	   j	                         }|j                  |d d!| d       |S |r|j                  d"d      nd#}|j                  |d| r| d$|  n|d       |S # t        $ r Y w xY w)%z@Extract project information from window title, app name, and URLNWork)project_nameproject_type	file_pathr   detailed_activityrA   c              3   &   K   | ]  }|v  
 y wrC   r   rQ   s     r    rH   z'extract_project_info.<locals>.<genexpr>V   s     
`,_S3. ,_rI   )rZ   rS   r[   rT   rU   z -    r      Development./zCoding: z in )r   r   r   r   c              3   &   K   | ]  }|v  
 y wrC   r   rD   s     r    rH   z'extract_project_info.<locals>.<genexpr>f   s     ^6]7W&6]rI   )rJ   rK   rM   rL   )urlparsezwww.	localhostz	127.0.0.1z
localhost:3000zWeb DevelopmentzLocal Development: )r   r   r   )z
github.comzstackoverflow.comzdocs.zapi.z
developer.zconsole.c              3   &   K   | ]  }|v  
 y wrC   r   )rE   work_domaindomains     r    rH   z'extract_project_info.<locals>.<genexpr>x   s     M{f,rI   zWeb Researchz
Research: zWeb Browsingz
Browsing: z.exeUnknownz: )r   r   splitlenstripupdateurllib.parser   netlocreplaceport	Exception)r>   r=   r   project_infor   partsfilenameprojectr   parsedwork_domains
page_titleclean_app_namerG   r   s                @@r    extract_project_infor   E   sj    !L )1X^^%rN1=++-2 
`,_
``L  &&u-E5zQ 8>>+(..*##$+$1<?8OG9AhZ!8QX+3H:T')K	%  $# 
^6]^	^1!#..vr: &(K6,A ''*4V[[5JF4K(L(9/B<.-Q) 
 ('  nMMM ''(.(6/9,-H) 
 (' N L %++E215;;=J * .'1*%>! 
   6>X%%fb19N&DP/r,@Vd  +  s   AG 51G 	G*)G*z/activitywatch/webhook.zDeveloper-ID)aliasrequestauthorizationr^   c                   K   |j                  d      st        dd      |j                  d      d   }t        ||      s%t        j                  d|        t        dd      t        j                  d	|        	 | j                          d
{   }d}|j                         D ]  \  }}t        |t              s|D ]  }	t        |	t              s|	j                  d      }
|	j                  dd      }|	j                  di       }|
r|dk  rR	 t        j                  |
j                  dd            }|j                  d      xs |j                  dd      }|j                  dd      }|j                  dd
      }|r|dk(  rt!        ||      }t#        |||      }ddlm} |j)                  |      j+                  |j,                  |k(  |j.                  |k(  |j0                  |k(  |j2                  |k(        j5                         }|rQ ||||||d   ||||d   |d   |d         }|j7                  |       |dz  }  |j=                          t        j                  d| d |        d!d"| d#|t        j>                  t@        jB                        jE                         d$S 7 "# t8        $ r#}t        j;                  d|        Y d
}~d
}~ww xY w# t        jF                  $ r t        d%d&      t8        $ rF}|jI                          t        j;                  d'|        t        d(d)tK        |             d
}~ww xY ww)*zCReceive ActivityWatch data via webhook - stateless token validationzBearer i  zInvalid authorization header)status_codedetail r   zInvalid token for developer zInvalid developer or tokenz$Received ActivityWatch webhook from Nr   r   r   r      Z+00:00appapplicationr   titlerA   r   ActivityRecordr   r   r   r   )r!   application_namer>   r   r   categoryr   r   r   r   r   zError processing event: zSuccessfully processed z activities from successz
Processed z activities)r   messager!   r   i  zInvalid JSON dataz(Error processing ActivityWatch webhook: i  zProcessing error: )&
startswithr   r   r<   loggerwarninginfojsonitems
isinstancelistdictgetr   fromisoformatr   r   r   modelsr   queryfilterr!   r   r   r   firstaddr   errorcommitr+   r   utc	isoformatJSONDecodeErrorrollbackr   )r   r!   r   r^   tokenwebhook_dataprocessed_activitiesbucket_namebucket_dataeventtimestamp_strr   r   r   r=   r>   r   r   r   r   existingactivity_recordes                          r    'receive_activitywatch_webhook_statelessr      s[     ##I.4RSS$Q'E $L%85l^DE4PQQ
KK6|nEFZS$\\^+  )5(:(:(<$K+t,(E%eT2  %*IIk$:M$yyQ7H 99VR0D(HqL 1!$,$:$:=;P;PQTV^;_$`	 $(88E?#Xdhh}i6X'+xx'<"hhud3  (8y+@$ $:(L#Q';L(TW'X :#%88N#;#B#B*77<G*44	A*;;xG*33x?	$
  %' ! $$ +9)5-5)5 #&2;&?%-%-&/)5n)E)5n)E.:;N.O+ /,1,s ) )=F 			-.B-CCTUaTbcd  #$8#9E(!hll3==?	
 	
Y ,F % !'?s%CD !   I4GHH S
?sCD6HQ4QRRSs   A<M?K& J4-K& AK& A5J7K& BJ7K& 5J7	A*K& 3M4K& 7	K# KK& K##K& &(MAMMMz/activitywatch/validate-tokenr   c                    K   t        | |      }| |t        j                  t        j                        j                         dS w)z1Test endpoint to validate a token (for debugging))r!   token_validr   )r<   r   r+   r   r   r   )r!   r   is_valids      r    validate_token_endpointr   	  s?      (e<H %\\(,,/99; s   AAz//activitywatch/developer-summary/{developer_id}
start_dateend_datec                   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
                        }ddlm} |j                  |      j                  |j                  | k(  |j                  |k\  |j                  |k        j                         }|s*| |j                         |j                         dddi i ddS t        |      }| |j                         |j                         d|dS w)	zFGet activity summary for a developer (no user authentication required)r   r   r   hourminutesecondmicrosecondr   startend)total_activities
total_time
categoriesprojects)r!   
date_rangesummary)r   r   r   r+   r   r   r   r   r   r   r!   r   allr   process_developer_activities)	r!   r   r   r^   r   r   r   
activitiesr   s	            r    get_developer_summary_statelessr     s<     &&z'9'9#x'HIX\\*22!A[\2]$$X%5%5c8%DEll8<<( &.)00##|3  E)  C' 
ce	  ($)OO$5cmmoN,-Qb^`a
 	
 +:6G % % 1#--/J s   E#E%z/activitywatch/team-summaryc                   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
                        }ddlm} ddlm	} |j                   ||j                              j                  |j                  j                  d      |j                  |k\  |j                  |k        j                         }g }d}	d}
|D ]  \  }|s|j                  |      j                  |j                  |k(  |j                  |k\  |j                  |k        j                         }t!        |      }|	|d   z  }	|
|d	   z  }
|j                  d
d      j#                         }d
|v r3|j%                  d
      dd }dj'                  |      j#                         }|j)                  |||d        |j+                         |j+                         d|t-        |      |	|	dz  dd|
ddS w)z;Get team-wide summary without requiring user authenticationr   r   r   r   )distinctr   Nr   r   _r   )r!   namer   r     .2fh)r   total_time_formattedr   )r   	team_datatotal_developersteam_totals)r   r   r   r+   r   r   
sqlalchemyr   r   r   r   r!   r   isnotr   r   r   r   r   joinappendr   r   )r   r   r^   r   r   r   r   developer_idsr  total_team_timetotal_team_activitiesdev_idr   r   developer_name
name_partss                   r    get_team_summary_statelessr  C  s<     &&z'9'9#x'HIX\\*22!A[\2]$$X%5%5c8%DEll8<<( $%HHXn&A&ABCJJ##))$/  E)  C' 
ce	  IO"	 XXn-44''61$$-$$+
 #%	 	 /z:7<00);!<<  S1779&=c*3B/J XXj1779N""
 	- #: !& 1#--/J	N)'6'=c&B!$D 5
		 	s   IIz/healthc                  v   K   ddt        j                  t        j                        j	                         ddS w)zHealth check endpointhealthy	statelessz:ActivityWatch webhook endpoint is running (stateless mode))r   moder   r   )r   r+   r   r   r   r   r   r    health_checkr    s4      \\(,,/99;O	 s   79r   c           	         | s	ddi i dddS t        d | D              }i }i }d}| D ]  }|j                  xs d}|j                  xs d}|j                  }||vrddd||<   ||   dxx   dz  cc<   ||   d	xx   |z  cc<   ||vrdd|j                  xs d
d||<   ||   dxx   dz  cc<   ||   d	xx   |z  cc<   dddddddd}	|	j                  |d      }
|||
z  z  } |dkD  r||z  dz  nd}|j                         D ]  }|d	   dz  dd|d<    |j                         D ]  }|d	   dz  dd|d<    t        |       ||dz  dd||dz  ddt        |d      ||dS )z*Process activities into summary statisticsr   )r   r   r   r   working_hoursproductivity_percentagec              3   4   K   | ]  }|j                     y wrC   )r   )rE   activitys     r    rH   z/process_developer_activities.<locals>.<genexpr>  s     Bz8X&&zs   r@   r   )countr   r   r   r   r   )r   r   typeg      ?g333333?g      ?g?g        )r\   rf   rt   rF   r@   r~   r|   d   r  r  r  duration_formatted)r   r   r  r  working_hours_formattedr  r   r   )	sumr   r   r   r   r   valuesr   round)r   r   r   r   r  r  r   r   r   category_weightsweightr  category_dataproject_datas                 r    r   r     s#    !'(
 	
 BzBBJJHM$$/''49$$ :%-.A#>Jx 8W%*%8Z(H4( ("*+HDYDYDc]c dHW'"a'"*%1%  
 "%%h4F**; > EOQRN}z9C?XY $**,1>z1JT1QRU0VVW.X*+ - !)0<Z0H40OPS/TTU-V)* *  
O #-#4S"9 ;&&3d&:3%?q#A#()@!#D 	 	r   )rA   rC   ),fastapir   r   r   r   r   r   sqlalchemy.ormr	   typingr
   r   r   r   r   r   r   r   r-   r)   pydanticr   rf   r   loggingrouter	getLoggerr   r   r   r   boolr<   r   r   r   postr   r   r   r   r  r  r   r   r   r    <module>r5     s$   N N " , , 2 2   	   				8	$ 
,3 , , , S    S  DPs Pc P Pt Pd %& s.9&/	oSoSoS oS 		oS 'oSb +, - => !%"&/	))) sm) 		) ?)V )* $"&/DDsmD 	D +DL I BT Bd Br   