U
    "h*                     @   s|   d dl Z d dlmZmZmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlZd dlZG dd dZdd	 Zed
krxe  dS )    N)datetimetimezone	timedelta)create_enginetext)DATABASE_URL)Configc                   @   sB   e Zd Zdd Zdd Zdd Zddd	ZdddZdddZd
S )ActivityWatchSyncc                 C   s   t j| _t j| _tt| _d S N)r   ACTIVITYWATCH_HOSTaw_hostLOCAL_DEVELOPER_NAMEdeveloper_namer   r   engine)self r   5/var/www/html/timesheet/backend/activitywatch_sync.py__init__   s    zActivityWatchSync.__init__c              
   C   s   zDt j| j ddd}|jdkr,| W S td|j  i W S W n8 tk
r| } ztd|  i  W Y S d}~X Y nX dS )z#Get available ActivityWatch bucketsz/api/0/buckets
   )timeout   zError getting buckets: z#Error connecting to ActivityWatch: N)requestsgetr   status_codejsonprint	Exception)r   responseer   r   r   get_activitywatch_buckets   s    


z+ActivityWatchSync.get_activitywatch_bucketsc              
   C   s   zbt j| j d| d| | dddd}|jdkrD| W S td| d	|j  g W S W n> tk
r } z td| d	|  g  W Y S d
}~X Y nX d
S )z$Get window events from ActivityWatchz/api/0/buckets/z/eventsi  )startendlimit   )paramsr   r   zError getting events from : N)r   r   r   	isoformatr   r   r   r   )r   bucket_name
start_timeend_timer   r   r   r   r   get_window_events   s     



z#ActivityWatchSync.get_window_events c                    s   |   |  t fdddD r*dS t fdddD rDdS t fddd	D r^d
S t fdddD rxdS t fdddD rdS t fdddD rdS t fdddD stfdddD rdS dS )z5Categorize application based on name and window titlec                 3   s   | ]}| kV  qd S r
   r   ).0Zdev_app	app_lowerr   r   	<genexpr>9   s     z;ActivityWatchSync.categorize_application.<locals>.<genexpr>)
vscodecodecursorpycharmintellijsublimeatomvimemacsz	notepad++ZIDEc                 3   s   | ]}| kV  qd S r
   r   )r,   browserr-   r   r   r/   @   s     )chromefirefoxsafariedgebraveoperaZBrowserc                 3   s   | ]}| kV  qd S r
   r   )r,   db_toolr-   r   r   r/   F   s     )datagrippgadminZ
phpmyadminmysql
postgresqlmongodbDatabasec                 3   s   | ]}| kV  qd S r
   r   )r,   Z	comm_toolr-   r   r   r/   L   s     )slackteamsdiscordtelegramwhatsappzoomskypeCommunicationc                 3   s   | ]}| kV  qd S r
   r   )r,   Z	prod_toolr-   r   r   r/   R   s     )
notionobsidiantrelloasanajira
confluenceexcelword
powerpointoutlookProductivityc                 3   s   | ]}| kV  qd S r
   r   )r,   Z	file_toolr-   r   r   r/   Y   s     )	filezillaZwinscpexplorerfinderterminalcmd
powershellSystemc                 3   s   | ]}| kV  qd S r
   r   )r,   Zent_appr-   r   r   r/   _   s     )spotifyyoutubenetflixtwitchZsteamrI   c                 3   s   | ]}| kV  qd S r
   r   )r,   Zent_word)title_lowerr   r   r/   a   s     )musicvideogameZEntertainmentOther)lowerany)r   app_namewindow_titler   )r.   re   r   categorize_application3   s&    z(ActivityWatchSync.categorize_applicationNc                 C   s.  t d| j d |s0ttjjddddd}|s@ttj}|  }|sXt d dS t dt| d d	}|	 D ]}d
|
 krx|} qqx|st d dS t d|  | |||}|st d dS t dt| d | j (}|td| j||d |  W 5 Q R X d}| j }|D ]}	z|	di }
|
dd}|
dd}|	dd}t|	d dd}|dk rW q.| ||}|td| j|||||d |d7 }W n< tk
r } zt d|  W Y q.W 5 d	}~X Y nX q.|  W 5 Q R X t d | d!| j  d"S )#z(Sync data from ActivityWatch to databaseu$   🔄 Syncing ActivityWatch data for z...r   hourminutesecondmicrosecondu#   ❌ No ActivityWatch buckets found!Fu   📊 Found z ActivityWatch bucketsNwindowu#   ❌ No window watcher bucket found!u   📋 Using bucket: u%   ❌ No events found in ActivityWatch!u   📥 Retrieved z events from ActivityWatchz
                DELETE FROM activity_records 
                WHERE developer_id = :dev_id 
                AND timestamp >= :start_date 
                AND timestamp <= :end_date
            dev_id
start_dateend_datedataappUnknowntitler+   duration	timestampZz+00:00r   a
  
                        INSERT INTO activity_records 
                        (developer_id, application_name, window_title, category, duration, timestamp)
                        VALUES (:dev_id, :app, :title, :category, :duration, :timestamp)
                    )rv   rz   r|   categoryr}   r~      zError processing event: u   ✅ Stored z activity records for T)r   r   r   nowr   utcreplacer   lenkeysrj   r*   r   connectexecuter   commitr   fromisoformatrn   r   )r   rw   rx   bucketsZwindow_bucketr'   eventsconnZstored_counteventry   rl   rm   r}   r~   r   r   r   r   r   sync_activitywatch_datag   sx    



 z)ActivityWatchSync.sync_activitywatch_datac                 C   s  |st tjjddddd}|s.t tj}| j }|td| j	||d
 }g }ddddd	d
g}t|D ]8\}}||d |d d |d ||t|  d qt|td| j	||d }	|	d pdd }
|	d pd}||
|| | ddW  5 Q R  S Q R X dS )z"Get activity summary from databaser   ro   a  
                SELECT 
                    category,
                    SUM(duration) as total_duration,
                    COUNT(*) as activity_count
                FROM activity_records 
                WHERE developer_id = :dev_id 
                AND timestamp >= :start_date 
                AND timestamp <= :end_date
                GROUP BY category
                ORDER BY total_duration DESC
            ru   z#8884d8z#82ca9dz#ffc658z#ff7300z#8dd1e1z#d084d0r   g      @   )r   r}   countcoloraN  
                SELECT 
                    SUM(duration) as total_duration,
                    COUNT(DISTINCT application_name) as project_count
                FROM activity_records 
                WHERE developer_id = :dev_id 
                AND timestamp >= :start_date 
                AND timestamp <= :end_date
            )r    r!   )ry   
total_timeactive_projects
date_rangeN)r   r   r   r   r   r   r   r   r   r   fetchall	enumerateappendr   fetchoner&   )r   rw   rx   r   result
activitiescolorsirowZtotal_resultr   Zproject_countr   r   r   get_summary   sF    



	zActivityWatchSync.get_summary)r+   )NN)NN)	__name__
__module____qualname__r   r   r*   rn   r   r   r   r   r   r   r	   
   s   
4
`r	   c                  C   s   t  } ttjjddddd}|tdd }| ||}|r| ||}t	d| j
 d t	d|d d	d
 t	d|d   t	dt|d   |d D ]$}t	d|d  d|d d	d qdS )z Manual sync function for testingr   ro   r   )daysu   
📊 Summary for :z   Total time: r   z.2fz hoursz   Active projects: r   z   Categories: ry   z   - r   r%   r}   hN)r	   r   r   r   r   r   r   r   r   r   r   r   )synctodayZtomorrowsuccesssummaryactivityr   r   r   manual_sync  s    r   __main__)r   r   r   r   
sqlalchemyr   r   databaser   configr   r   timer	   r   r   r   r   r   r   <module>   s      