U
    hV                     @   sZ   d dl Z d dlmZ d dlmZmZmZ d dlZd dlmZm	Z	m
Z
mZ G dd dZdS )    N)RealDictCursor)datetimedate	timedelta)ListDictTupleOptionalc                   @   s   e Zd ZdZeeef dddZdd Zdee	e
 e	e
 eee ef dd	d
Zee eedddZdee	e
 edddZe
edddZee ee dddZee ee dddZdS )ActivityAnalyzerz+Analyze activity data for dashboard display	db_configc                 C   s
   || _ d S )Nr   )selfr    r   ./activity_analyzer_fixed.py__init__   s    zActivityAnalyzer.__init__c                 C   s2   t j| jd | jd | jd | jd | jd dS )zCreate a database connectionhostportdatabaseuserpassword)r   r   r   r   r   )psycopg2Zconnectr   )r   r   r   r   get_connection   s    zActivityAnalyzer.get_connectionN)developer_id
start_dateend_datereturnc           	      C   s   |st  }|st  }d}|  f}|jtdN}|||||f | }tdd |D }||fW  5 Q R  W  5 Q R  S Q R X W 5 Q R X dS )z9Get activities for a specific developer within date rangea  
            SELECT 
                application_name,
                window_title,
                category,
                duration,
                timestamp,
                project_name,
                url
            FROM activity_records
            WHERE CAST(developer_id AS VARCHAR) = %s
            AND DATE(timestamp) BETWEEN %s AND %s
            AND application_name IS NOT NULL
            ORDER BY timestamp DESC
        )Zcursor_factoryc                 s   s   | ]}|d  pdV  qdS )durationr   Nr   ).0Zactr   r   r   	<genexpr>7   s     z<ActivityAnalyzer.get_developer_activities.<locals>.<genexpr>N)r   todayr   cursorr   executeZfetchallsum)	r   r   r   r   queryconnr    
activitiestotal_durationr   r   r   get_developer_activities   s    
z)ActivityAnalyzer.get_developer_activities)r%   r&   r   c                 C   s   |r|dkrdS d}dddg}|D ]H}| d|krF|| dd7 }q"| dd d	kr"|| dd7 }q"t|| d
 }t|d
S )z0Calculate productivity score based on activitiesr   Zider   Zdocumentationcategoryr   application_name )codeZvscodeZsublimeZpycharmd   )getlowerintmin)r   r%   r&   Zproductive_timeZproductive_categoriesactivityZscorer   r   r   calculate_productivity_score;   s    
z-ActivityAnalyzer.calculate_productivity_score)r   target_dater   c           
      C   s   |st  }| |||\}}| ||}| |}|r@|d nd}| |}| |}	|| ||t|dt|d||	|t|d||dkrdnddid	S )z0Get comprehensive dashboard data for a developer  r      ZactiveZoffline)ZhoursZproductivitystatus)	r   r   Zactive_developersZteam_productivitytotal_hoursZavg_hours_per_devZapplication_breakdownZactivity_timelineZdeveloper_stats)	r   r   r'   r2   _get_active_developers_count_get_application_breakdown_get_activity_timelineZ	isoformatround)
r   r   r3   r%   r&   Zproductivity_scoreZactive_devsr7   Zapp_breakdowntimeliner   r   r   get_dashboard_dataN   s.    


z#ActivityAnalyzer.get_dashboard_data)r3   r   c                 C   sj   d}|   T}| @}|||f | }|r:|d ndW  5 Q R  W  5 Q R  S Q R X W 5 Q R X dS )z)Get count of active developers for a datez
            SELECT COUNT(DISTINCT developer_id) 
            FROM activity_records
            WHERE DATE(timestamp) = %s
            AND duration > 0
        r   N)r   r    r!   Zfetchone)r   r3   r#   r$   r    resultr   r   r   r8   w   s    

z-ActivityAnalyzer._get_active_developers_count)r%   r   c                    sx   i  |D ]>}| dd}| dd}| kr> |  |7  < q| |< q fdd  D }t|dd d	d
dd S )z+Get breakdown of time spent per applicationr)   ZUnknownr   r   c              	      sD   g | ]<\}}|t |d  d r8t |t   d dnddqS )r4      r,   r5   r   )namevalueZ
percentage)r;   r"   values)r   Zappr   Zapp_timer   r   
<listcomp>   s
    z?ActivityAnalyzer._get_application_breakdown.<locals>.<listcomp>c                 S   s   | d S )NrA   r   )xr   r   r   <lambda>       z=ActivityAnalyzer._get_application_breakdown.<locals>.<lambda>T)keyreverseN
   )r-   itemssorted)r   r%   r1   Zapp_namer   Z	breakdownr   rC   r   r9      s    

	z+ActivityAnalyzer._get_application_breakdownc              	   C   s   i }|D ]F}| d}|r|j}| dd}||krF||  |7  < q|||< qg }tdD ].}||ddt| |dd dd	 q\|S )
zGet hourly activity timeline	timestampr   r      Z02dz:00r4   r?   )hourrA   )r-   rO   rangeappendr;   )r   r%   Zhourly_datar1   rM   rO   r   r<   r   r   r   r:      s     



z'ActivityAnalyzer._get_activity_timeline)NN)N)__name__
__module____qualname____doc__r   stranyr   r   r	   r   r   r   floatr'   r/   r2   r=   r8   r9   r:   r   r   r   r   r
   
   s   
*!)r
   )r   Zpsycopg2.extrasr   r   r   r   Zjsontypingr   r   r   r	   r
   r   r   r   r   <module>   s
   