U
    h_                     @   s  d Z ddlZddlmZ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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mZmZ ddlm Z m!Z!m"Z"m#Z# ddl$m%Z% e Z&e'e(Z)e
dddd?ee* e+e+ee* ee* ee+ ee+ ee+ e,ee- ee+ eee+ef  e+dddZ.e
dddeee+ef  ee+ dddZ/e
dddd@e+ee* ee* e,dddZ0e
dddee1 e*dddZ2e
ddddAe*ee+ef d!d"d#Z3e
ddde+ee+ef d$d%d&Z4e
ddddBe*e*ee+ef d(d)d*Z5e
ddddCe*eee+ef  d,d-d.Z6e
dddeee+ef  e,d/d0d1Z7e
ddddDe*ee+ef e+ee+ef d3d4d5Z8e
ddde+ee+ef e,d6d7d8Z9e
d9d: Z:e
d;d< Z;e
d=d> Z<dS )Ea  
Adtlas Activities Celery Tasks

This module contains Celery tasks for the activities app,
providing asynchronous processing for activity logging,
data aggregation, cleanup, and analytics.

Features:
    - Asynchronous activity logging
    - Batch activity processing
    - Activity summary generation
    - Automated cleanup tasks
    - Analytics calculations
    - Report generation
    - Security monitoring

Author: Adtlas Development Team
Version: 1.0.0
Last Updated: 2025-01-27
    N)datetime	timedelta)ListDictAnyOptional)shared_taskgroupchord)settings)timezone)	send_mail)render_to_string)get_user_model)transaction)cache   )ActivityActivityCategoryActivitySummary)get_activity_statisticscleanup_old_activitiesget_security_alertsexport_activities_to_csv)activity_cleanup_completedT   )bindmax_retries)user_idactiondescriptioncategory_idcontent_type_id	object_id
ip_address
user_agentis_successfulduration_mserror_messagemetadatareturnc                 C   s   zFt jj|||||||||	|
||p$i d}td|j  t|jW S  tk
r } zBtdt|  | j	j
| jk r| jdd| j	j
  d|W 5 d}~X Y nX dS )a  
    Log an activity asynchronously.
    
    This task creates an activity record in the background,
    useful for high-traffic scenarios where synchronous logging
    might impact performance.
    
    Args:
        user_id: User ID (optional)
        action: Activity action
        description: Activity description
        category_id: Category ID (optional)
        content_type_id: Content type ID (optional)
        object_id: Object ID (optional)
        ip_address: IP address (optional)
        user_agent: User agent (optional)
        is_successful: Success status
        duration_ms: Duration in milliseconds (optional)
        error_message: Error message (optional)
        metadata: Additional metadata (optional)
    
    Returns:
        str: Activity ID
    r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   z Activity logged asynchronously: z'Failed to log activity asynchronously: <      	countdownN)r   objectscreateloggerinfoidstr	Exceptionerrorrequestretriesr   retry)selfr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   activityexc r>   0/var/www/html/Focus/src/apps/activities/tasks.pylog_activity_async2   s,    r@   )activities_datar*   c                 C   s   zg }|D ]v}t |d|d |d |d|d|d|d|d|d	d
|d|d|di d}|| q
t j|}dd |D }tdt| d |W S  tk
r } zDt	dt
|  | jj| jk r| jdd| jj  d|W 5 d}~X Y nX dS )a  
    Log multiple activities in bulk asynchronously.
    
    This task creates multiple activity records efficiently
    using bulk operations.
    
    Args:
        activities_data: List of activity data dictionaries
    
    Returns:
        list: List of activity IDs
    r   r   r    r!   r"   r#   r$   r%   r&   Tr'   r(   r)   r+   c                 S   s   g | ]}t |jqS r>   )r5   r4   ).0r<   r>   r>   r?   
<listcomp>   s     z'log_activities_bulk.<locals>.<listcomp>zBulk logged z activitieszFailed to bulk log activities: r,   r-   r.   N)r   getappendr0   bulk_creater2   r3   lenr6   r7   r5   r8   r9   r   r:   )r;   rA   
activitiesdatar<   Zcreated_activitiesZactivity_idsr=   r>   r>   r?   log_activities_bulko   s6    

rJ   )dater   r!   r*   c           
   
   C   s  z*t |d }t  tjj|||d\}}tjj	|d}|rT|j	|d}|rd|j	|d}|
 |_|j	dd
 |_|j	dd
 |_|j	dd	jd
dd}|rt|t| |_nd|_|d 
 |_t  dd|_|  td| d| d| d W 5 Q R  W dS Q R X W nf tk
r }	 zFtdt|	  | jj | j!k r|| j"dd| jj   dW Y dS d}	~	X Y nX dS )aV  
    Update activity summary for a specific date.
    
    This task calculates and updates activity statistics
    for a given date, user, and/or category.
    
    Args:
        date: Date string (YYYY-MM-DD)
        user_id: User ID (optional)
        category_id: Category ID (optional)
    
    Returns:
        bool: Success status
    %Y-%m-%d)rK   r   r!   created_at__dater   r!   Tr&   F)duration_ms__isnullr'   )flatr   r$   Zcelery_task)Zlast_updatedZcalculation_methodzActivity summary updated for z (user: z, category: )z#Failed to update activity summary: r,   r-   r.   N)#r   strptimerK   r   atomicr   r0   get_or_creater   filtercounttotal_activitiessuccessful_activitiesfailed_activitiesvalues_listsumrG   avg_duration_msvaluesdistinct
unique_ipsr   now	isoformatr)   saver2   r3   r6   r7   r5   r8   r9   r   r:   )
r;   rK   r   r!   Zsummary_datesummarycreatedrH   	durationsr=   r>   r>   r?   update_activity_summary   sN    

 
ri   )summary_keysr*   c              
   C   s   zNd}|D ],\}}}t j|||gd }|r
|d7 }q
td| d |W S  tk
r } zDtdt|  | jj	| j
k r| jdd| jj	  d	W Y dS d
}~X Y nX d
S )z
    Update multiple activity summaries in bulk.
    
    Args:
        summary_keys: List of tuples (date, user_id, category_id)
    
    Returns:
        int: Number of summaries updated
    r   )argsr   zBulk updated z activity summariesz*Failed to bulk update activity summaries: r,   r-   r.   N)ri   applyrD   r2   r3   r6   r7   r5   r8   r9   r   r:   )r;   rj   updated_countZdate_strr   r!   successr=   r>   r>   r?   update_activity_summaries_bulk   s    

ro   Z   )days_to_keepr*   c              
   C   s   z^t  }t|}t  }||  }tj| j|d |||| d}t	d| d |W S  t
k
r } zBtdt|  | jj| jk r| jdd| jj  d|W 5 d	}~X Y nX d	S )
a'  
    Clean up old activities based on retention policy.
    
    This task removes activities older than the specified
    number of days to maintain database performance.
    
    Args:
        days_to_keep: Number of days to keep activities
    
    Returns:
        dict: Cleanup results
    )senderdeleted_count)rs   rq   duration_secondsZcompleted_atzActivity cleanup completed: z activities deletedz"Failed to cleanup old activities: r,   r-   r.   N)r   rc   r   total_secondsr   send	__class__rd   r2   r3   r6   r7   r5   r8   r9   r   r:   )r;   rq   
start_timers   end_timedurationresultr=   r>   r>   r?   cleanup_old_activities_task  s*    r|   )rK   r*   c              
   C   s  z\t |d }tjj|d}ttt 	|t j
 tt 	|t j d}t|jdddddjtd	d
ddd }t|ddjtd	dd}t|jddiddjtd	dd}|jdd}| t|djtd	dddd d}	||||||	t  d}
d| }t||
d td|  |
W S  tk
r } zDtdt|  | jj| jk r| j dd| jj  d |W 5 d}~X Y nX dS )!z
    Generate daily activity report.
    
    This task creates a comprehensive report of activities
    for a specific date.
    
    Args:
        date: Date string (YYYY-MM-DD)
    
    Returns:
        dict: Activity report data
    rL   rM   )
start_dateend_dateF)user__isnulluser__emailuser__first_nameuser__last_namer4   )activity_countz-activity_countN
   category__namecategory__code)rY   z-counthourzEXTRACT(hour FROM created_at))selectrQ   r(      )Ztotal_errors
top_errors)rK   overall_stats	top_userscategory_breakdownhourly_distributionerror_summarygenerated_atZdaily_activity_report_iQ z$Daily activity report generated for z*Failed to generate daily activity report: r,   r-   r.   )!r   rU   rK   r   r0   rX   r   r   
make_awarecombinemintimemaxlistr`   annotateCountorder_byextrarY   rc   rd   r   setr2   r3   r6   r7   r5   r8   r9   r   r:   )r;   rK   report_daterH   r   r   r   r   Zerror_activitiesr   report	cache_keyr=   r>   r>   r?   generate_daily_activity_reportE  s      	 


r      )r   daysr*   c              
   C   s   zddl m} tjj|d}|||}|j|j| |j|j	
 d|d< t 
 |d< d| d| }t||d	 td
|  |W S  tjk
r   td| d i  Y S  tk
r } zDtdt|  | jj| jk r| jdd| jj  d|W 5 d}~X Y nX dS )a-  
    Generate user activity report.
    
    This task creates a comprehensive report of activities
    for a specific user over a given period.
    
    Args:
        user_id: User ID
        days: Number of days to include in the report
    
    Returns:
        dict: User activity report data
    r   )get_user_activity_summaryr4   )r4   email	full_name	is_activedate_joineduserr   Zuser_activity_report__  z(User activity report generated for user User z not found for activity reportz)Failed to generate user activity report: r,   r-   r.   N)utilsr   Userr0   rD   r4   r   get_full_namer   r   rd   r   rc   r   r   r2   r3   DoesNotExistr7   r6   r5   r8   r9   r   r:   )r;   r   r   r   r   rf   r   r=   r>   r>   r?   generate_user_activity_report  s.    

r      )hoursr*   c              
   C   s   zZt |}dd |D }|r&t| d| d}t||d tdt| d |W S  tk
r } zBt	dt
|  | jj| jk r| jd	d
| jj  d|W 5 d}~X Y nX dS )a  
    Monitor and process security alerts.
    
    This task checks for security-related activities
    and generates alerts for suspicious behavior.
    
    Args:
        hours: Number of hours to check for alerts
    
    Returns:
        list: List of security alerts
    c                 S   s   g | ]}|d  dkr|qS )severityhighr>   )rB   alertr>   r>   r?   rC     s      z+monitor_security_alerts.<locals>.<listcomp>Zsecurity_alerts_hr   zSecurity monitoring completed: z alerts foundz#Failed to monitor security alerts: r,   r-   r.   N)r   send_security_alert_emaildelayr   r   r2   r3   rG   r6   r7   r5   r8   r9   r   r:   )r;   r   alertsZhigh_severity_alertsr   r=   r>   r>   r?   monitor_security_alerts  s    
r   )r   r*   c              
   C   s   zt tdg }|s"td W dS dt| d}|t|t d}td|}td|}t|||tj	|dd	 t
d
t| d W dS  tk
r } zDtdt|  | jj| jk r| jdd| jj  dW Y dS d}~X Y nX dS )z
    Send security alert email notifications.
    
    Args:
        alerts: List of security alerts
    
    Returns:
        bool: Success status
    ZSECURITY_ALERT_EMAILSz.No admin emails configured for security alertsFzSecurity Alert: z suspicious activities detected)r   Zalert_count	timestampz%activities/emails/security_alert.htmlz$activities/emails/security_alert.txtsubjectmessagehtml_message
from_emailrecipient_listfail_silentlyzSecurity alert email sent to z recipientsTz%Failed to send security alert email: r,   r-   r.   N)getattrr   r2   warningrG   r   rc   r   r   DEFAULT_FROM_EMAILr3   r6   r7   r5   r8   r9   r   r:   )r;   r   Zadmin_emailsr   contextr   plain_messager=   r>   r>   r?   r     s6    


	r   csv)r   filtersformatr*   c              
   C   s  z~ddl m} ddlm} tjj|d}tj }|drN|j	|d d}|drh|j	|d d}|d	r|j	|d	 d
}|dr|j	|d d}|ddk	r|j	|d d}|dkrt
|}dt d d}	d}
n.ddlm} ||}dt d d}	d}
d|	 }||||d}|	|t|| ||t  d}t|j| td| d|	  |W S  tjk
r   td| d i  Y S  tk
r } zDtd t|  | jj| j k r| j!d!d"| jj  d#|W 5 d}~X Y nX dS )$ae  
    Export activities to file asynchronously.
    
    This task exports activities based on filters and
    sends the result to the requesting user.
    
    Args:
        user_id: User ID requesting the export
        filters: Activity filters
        format: Export format ('csv' or 'json')
    
    Returns:
        dict: Export result information
    r   )ContentFile)default_storager   r}   )created_at__gter~   )created_at__lter   rO   r!   rP   r&   NrQ   r   Zactivities_export_z%Y%m%d_%H%M%Sz.csvztext/csvr   )export_activities_to_jsonz.jsonzapplication/jsonzexports/activities/zutf-8)filename	file_path	file_sizeZrecord_countr   r   
created_atz#Activity export completed for user z: r   z not found for activity exportzFailed to export activities: r,   r-   r.   )"django.core.files.baser   django.core.files.storager   r   r0   rD   r   allrX   r   r   rc   strftimer   r   re   encoderG   rY   rd   send_export_notification_emailr   r   r2   r3   r   r7   r6   r5   r8   r9   r   r:   )r;   r   r   r   r   r   r   rH   contentr   content_typer   r   Z
saved_pathr{   r=   r>   r>   r?   export_activities_task8  sX    






r   )r   export_infor*   c              
   C   s   z`d}|t j d|d  d}td|}td|}t|||t j|gdd td	|  W d
S  tk
r } zDtdt	|  | j
j| jk r| jdd| j
j  dW Y dS d}~X Y nX dS )z
    Send export completion notification email.
    
    Args:
        email: User email address
        export_info: Export information
    
    Returns:
        bool: Success status
    zActivity Export Completedz/activities/exports/r   )r   Zdownload_urlz*activities/emails/export_notification.htmlz)activities/emails/export_notification.txtFr   z"Export notification email sent to Tz*Failed to send export notification email: r,   r-   r.   N)r   ZSITE_URLr   r   r   r2   r3   r6   r7   r5   r8   r9   r   r:   )r;   r   r   r   r   r   r   r=   r>   r>   r?   r     s,    

	r   c                  C   sx   t  tdd  } t| d tjj	dd}|D ]}tj| d|j
d q8t| d td|   dS )	z
    Daily task to update activity summaries.
    
    This task runs daily to update activity summaries
    for the previous day.
    r   )r   rL   T)r   rP   z*Daily activity summary task completed for N)r   rc   r   rK   ri   r   r   r   r0   rX   r4   r   r2   r3   )	yesterday
categoriescategoryr>   r>   r?   daily_activity_summary_task  s    r   c                  C   s$   t tdd} t|  td dS )z
    Weekly task to clean up old activities.
    
    This task runs weekly to remove old activities
    based on the retention policy.
    ZACTIVITIES_RETENTION_DAYSrp   zWeekly cleanup task initiatedN)r   r   r|   r   r2   r3   )retention_daysr>   r>   r?   weekly_cleanup_task  s    
r   c                   C   s   t jdd td dS )z
    Hourly task to monitor security alerts.
    
    This task runs hourly to check for security-related
    activities and generate alerts.
    r   )r   z)Hourly security monitoring task completedN)r   r   r2   r3   r>   r>   r>   r?   hourly_security_monitoring_task  s    r   )	NNNNNTNNN)NN)rp   )r   )r   )r   )=__doc__loggingr   r   typingr   r   r   r   celeryr   r	   r
   django.confr   django.utilsr   django.core.mailr   django.template.loaderr   django.contrib.authr   	django.dbr   django.core.cacher   modelsr   r   r   r   r   r   r   r   signalsr   r   	getLogger__name__r2   intr5   boolfloatr@   rJ   ri   tuplero   r|   r   r   r   r   r   r   r   r   r   r>   r>   r>   r?   <module>   s   

                  <
"2
  
 N
"
0
Y
7
 )
6
  
W
/

