
    )h5                        d dl m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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  ej8                  e      Z G d d      Z e       Z d Z!d Z"d Z#dde$de%fdZ&y)    )Session)funcand_)datetimedate	timedeltatimezone)DictAnyListOptionalN)BackgroundScheduler)CronTrigger)PersonaGenerationService)Persona)ConnectedAccount)get_db_sessionc            	           e Zd ZdZd Zd Zd Zd Zdede	e
   fdZded	e
deeef   fd
Zded	e
de	e   fdZd Zdd	e
dedeeef   fdZdeeef   fdZy)PersonaScheduledServicezXScheduled service for automatically refreshing personas based on social media analytics.c                 >    t               | _        d | _        d| _        y )NF)r   	schedulerservice
is_runningselfs    K/var/www/html/hubwallet-dev/src/marketing/apps/persona/scheduled_service.py__init__z PersonaScheduledService.__init__   s    ,.    c                    	 | j                   s| j                  j                  | j                  ddddd       | j                  j	                          d| _         t
        j                  d       t
        j                  d       | j                          yt
        j                  d	       y# t        $ r'}t
        j                  d
t        |               d}~ww xY w)z$Start the persona refresh scheduler.interval   persona_refresh_jobz.Refresh all personas every 5 minutes (testing)T)r   triggerminutesidnamereplace_existingz.Persona scheduled service started successfullyz)Personas will be refreshed every 2-3 daysz,Persona scheduled service is already runningz*Error starting persona scheduled service: N)r   r   add_jobrefresh_all_personas_jobstartloggerinforun_initial_refresh	Exceptionerrorstrr   es     r   start_schedulerz'PersonaScheduledService.start_scheduler   s    $	??&&66&,I%) ' & $$&"&LMGH ((* JK 	LLEc!fXNO	s   BB+ B+ +	C4"CCc                    	 | j                   r7| j                  j                          d| _         t        j	                  d       yt        j	                  d       y# t
        $ r'}t        j                  dt        |               d}~ww xY w)z#Stop the persona refresh scheduler.Fz!Persona scheduled service stoppedz(Persona scheduled service is not runningz*Error stopping persona scheduled service: N)r   r   shutdownr+   r,   r.   r/   r0   r1   s     r   stop_schedulerz&PersonaScheduledService.stop_schedulerB   sj    
	'')"'?@FG 	LLEc!fXNO	s   AA A 	B$"BBc           
         t         j                  d       t        j                         }	 t               }t	        |      | _        | j                  |      }|s4t         j                  d       	 dt               v r|j                          yyt         j                  dt        |       d       t        |      dddg d}|D ]b  }	 | j                  ||      }|d	   j                  |       |d
   dk(  r|dxx   dz  cc<   n#|d
   dk(  r|dxx   dz  cc<   n|dxx   dz  cc<   d t        j                         |z
  }t         j                  d|dd       t         j                  d|d    d|d    d|d    d       |d	   D ]  }	|	d
   dk(  r"t         j                  d|	d    d|	d           -|	d
   dk(  r"t         j                  d|	d    d|	d           W|	d
   dk(  s`t         j                  d|	d    d|	d            	 dt               v rj                          yy# t        $ r]}t         j                  d| dt        |              |dxx   dz  cc<   |d	   j                  |dt        |      d       Y d}~d}~ww xY w# t        $ r+}t         j                  dt        |              Y d}~d}~ww xY w# dt               v rj                          w w xY w)z*Main job function to refresh all personas.z&Starting scheduled persona refresh jobz)No stores with personas found for refreshdbNzFound z  stores with personas to refreshr   )total_stores
successfulfailedskippeddetailsr=   statussuccessr:      r;   r<   zError processing store : r/   store_idr>   messagez!Persona refresh job completed in z.2fz secondsz	Results: z successful, z	 failed, z skippedzStore rC   rD   zError in persona refresh job: )r+   r,   timer   r   r   _get_stores_with_personaslocalscloselen_refresh_store_personasappendr.   r/   r0   warning)
r   
start_timer8   stores_with_personasresultsrC   store_resultr2   execution_timedetails
             r   r)   z0PersonaScheduledService.refresh_all_personas_jobP   s   <=YY[
@	!B 4B7DL $(#A#A"#E 'GHf vx
  c KK&%9!: ;;[\] !$$8 9G 1 #'#?#?H#MLI&--l;#H-:-2-%h/8;)Q.)	*a/*, "YY[:5NKK;N3;OxXYKK)GL$9#:-PXHYGZZcdkludvcww  A  B "), T(#y0KK&
);(<Bvi?P>Q RSH%1NNVF:,>+?r&BSAT#UVH%2KK&
);(<Bvi?P>Q RST vx
  5 ! LL#:8*Bs1vh!OPH%*%I&--$,")#&q6/  .  	DLL9#a&BCC	D vx
  si   AJ 8J AH&$B?J $#J K &	J/AJJ JJ 	K!J>9K >KK K%r8   returnc                    	 |j                  t        j                        j                         j	                         }|D cg c]  }|d   	 c}S c c}w # t
        $ r-}t        j                  dt        |              g cY d}~S d}~ww xY w)z%Get all store IDs that have personas.r   z$Error getting stores with personas: N)	queryr   rC   distinctallr.   r+   r/   r0   )r   r8   	store_idsrC   r2   s        r   rF   z1PersonaScheduledService._get_stores_with_personas   sr    	!1!12;;=AACI09:HHQK::: 	LL?AxHII	s/   ?A AA A 	B"B BBrC   c                    	 t         j                  d|        | j                  ||      }|s|dddS |j                  t              j                  t        j                  |k(        j                         }|s|dddS g }|D ]  }|j                  }|j                   |j                  t        j                        }t        j                  t        j                        |z
  j                  }|dk\  sq|j!                  |        |s|dd	dS d
}	d
}
|D ]  }	 | j"                  j%                  |j                  |j&                  dd      }|j(                  r+|	dz  }	t         j                  d|j*                   d|        n7|
dz  }
t         j-                  d|j*                   d| d|j.                           |
d
k(  r	d}d|	 d}n|	d
kD  rd}d|	 d|
 d}nd}d|
 d}||||	|
t7        |      dS # t0        $ rA}|
dz  }
t         j3                  d|j*                   d| dt5        |              Y d}~%d}~ww xY w# t0        $ r@}t         j3                  d| dt5        |              |dd t5        |       dcY d}~S d}~ww xY w)!z*Refresh all personas for a specific store.zRefreshing personas for store r<   z%No active social media accounts foundrB   zNo personas found for storeN)tzinfo   z.All personas are recent (less than 2 days old)r      T)days_to_analyzeforce_refreshr@   zSuccessfully refreshed persona z for store zFailed to refresh persona rA   zError refreshing persona r?   z
Refreshed z personas successfullypartialz personas, z failedr;   z Failed to refresh any personas (z failed))rC   r>   rD   refreshed_countfailed_counttotal_personasz$Error refreshing personas for store r/   zError: )r+   r,   _get_active_social_accountsrU   r   filterrC   rW   
updated_atrZ   replacer	   utcr   nowdaysrK   r   generate_persona_for_store	branch_idr?   r%   rL   rD   r.   r/   r0   rI   )r   r8   rC   active_accountsstore_personaspersonas_to_refreshpersonare   days_since_updater`   ra   resultr2   r>   rD   s                  r   rJ   z/PersonaScheduledService._refresh_store_personas   s   [	KK8
CD #>>r8LO" ('F   XXg.55g6F6F(6RSWWYN! ('<  #%) 8$//
$$,!+!3!38<<!3!HJ%-\\(,,%?*%L$R$R!$)'..w78 ' ('O   OL. jj!\\DD(())(*&*	 E F ~~'1,&Egjj\Q\]e\f$gh$))CGJJ<{[cZddfgmgugufv'wxj* q "&&77MN 1$"&&7{<.PWX!<\N(S % "#2 ,"%n"5  ! j A%LLL#<WZZLT\S]]_`cde`f_g!hiij0  	LL?zCPQF8TU$!$SVH- 	sa   1I A
I ?A4I 4I 	I B!G5::I 5	H?>6H:4I :H??I 	J5J JJc           	      B   	 |j                  t              j                  t        j                  |k(  t        j                  j                  d            j                         }|S # t        $ r0}t        j                  d| dt        |              g cY d}~S d}~ww xY w)z-Get active social media accounts for a store.Fz/Error getting active social accounts for store rA   N)rU   r   rd   rC   
is_deletedis_rW   r.   r+   r/   r0   )r   r8   rC   accountsr2   s        r   rc   z3PersonaScheduledService._get_active_social_accounts   s    
	xx 0188 ))X5 ++//6 ce 
 O 	LLJ8*TVWZ[\W]V^_`I	s   A"A% %	B.%BBBc                 N    t         j                  d       | j                          y)zARun initial refresh for all stores (useful for first-time setup).z.Running initial persona refresh for all storesN)r+   r,   r)   r   s    r   r-   z+PersonaScheduledService.run_initial_refresh  s    DE%%'r   r^   c           	         t         j                  d|        	 t               }t        |      | _        | j                  ||      }d||ddt               v r|j                          S S # t        $ rZ}t         j                  d| dt        |              d|t        |      dcY d	}~dt               v rj                          S S d	}~ww xY w# dt               v rj                          w w xY w)
z/Manually refresh personas for a specific store.z#Manual refresh requested for store T)r?   rC   rq   r8   z"Error in manual refresh for store rA   F)r?   rC   r/   N)r+   r,   r   r   r   rJ   rG   rH   r.   r/   r0   )r   rC   r^   r8   rq   r2   s         r   manual_refresh_storez,PersonaScheduledService.manual_refresh_store  s    9(DE	!B3B7DL11"h?F  $  vx
    	LL=hZr#a&RS $Q  vx
  	 vx
  s/   1A) )	C22C$C%C CC C.c           	         	 g }| j                   j                         D ]e  }|j                  |j                  |j                  |j
                  r|j
                  j                         ndt        |j                        d       g | j                  | j                   j                  t        |      |dS # t        $ r9}t        j                  dt        |              dt        |      dcY d}~S d}~ww xY w)z-Get current scheduler status and information.N)r%   r&   next_run_timer#   )r   scheduler_stateactive_jobsjobsz Error getting scheduler status: F)r   r/   )r   get_jobsrK   r%   r&   rz   	isoformatr0   r#   r   staterI   r.   r+   r/   )r   r}   jobr2   s       r   get_scheduler_statusz,PersonaScheduledService.get_scheduler_status-  s    	D~~..0 &&HHFIFWFWS%6%6%@%@%B]a"3;;/	  #oo#'>>#7#7"4y	   	LL;CF8DE#Q 	s   B1B4 4	C6=.C1+C61C6NF)__name__
__module____qualname____doc__r   r3   r6   r)   r   r   intrF   r
   r0   r   rJ   r   rc   r-   boolrx   r    r   r   r   r      s    b 
&PENG S	 ]' ]S ]T#s(^ ]~g  N^I_ (
S  RVWZ\_W_R` 6d38n r   r   c                  ,    t         j                          y)z$Start the persona scheduler service.N)persona_schedulerr3   r   r   r   start_persona_schedulerr   J  s    %%'r   c                  ,    t         j                          y)z#Stop the persona scheduler service.N)r   r6   r   r   r   stop_persona_schedulerr   N  s    $$&r   c                  *    t         j                         S )z0Get the current status of the persona scheduler.)r   r   r   r   r   get_persona_scheduler_statusr   R  s    1133r   rC   r^   c                 .    t         j                  | |      S )z6Manually trigger persona refresh for a specific store.)r   rx   )rC   r^   s     r   manual_refresh_store_personasr   V  s    11(MJJr   r   )'sqlalchemy.ormr   
sqlalchemyr   r   r   r   r   r	   typingr
   r   r   r   loggingrE   !apscheduler.schedulers.backgroundr   apscheduler.triggers.cronr   "src.marketing.apps.persona.servicer    src.marketing.apps.persona.modelr    src.marketing.apps.Account.modelr   src.utils.dbr   	getLoggerr   r+   r   r   r   r   r   r   r   r   r   r   r   <module>r      s~    " ! 8 8 , ,   A 1 G 4 = '			8	$s sl	 ,- ('4KC K Kr   