U
    duF                     @   s   d 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mZ ddl	m
Z
 ddlmZ ddlmZmZ dd	lmZ dd
lmZmZ dZdZdZdZdZdZdZdZdZG dd dZG dd dejZdd Z dddZ!e"dkre!  dS )z0Graphical monitor of Celery events using curses.    N)datetime)count)ceil)wrap)time)VERSION_BANNERstates)app_or_default)abbrabbrtask)CursesMonitorevtop      $            zGevents: {s.event_count} tasks:{s.task_count} workers:{w_alive}/{w_all}
c                   @   sf  e Zd ZdZi ZdZdZdZdZdZ	e
jZe
jZdZdZdZd	e Zd
ZdGddZdd Zedd Zedd Zedd Zedd Zedd Zdd Zdd Zdd ZdHd d!Z e
j!d"e
j"d#e
j#d$iZ$d%d& Z%dId'd(Z&d)d* Z'd+d, Z(d-d. Z)d/d0 Z*d1d2 Z+d3d4 Z,d5d6 Z-d7d8 Z.d9d: Z/d;d< Z0d=d> Z1d?d@ Z2dAdB Z3edCdD Z4edEdF Z5dS )Jr   z#A curses based Celery task monitor.N
   r   z
Selected: zWorkers online: zKeys: z9j:down k:up i:info t:traceback r:result c:revoke ^c: quitzcelery events zInfo: c                 C   sX   || _ |p| j| _|| _| j| j| j| j| j| j| j	d}t
|f| j| _t | _d S )N)JKCTRIL)appkeymapstatemove_selection_downmove_selection_uprevoke_selectionselection_tracebackselection_resultselection_infoselection_rate_limitdict	threadingRLocklock)selfr   r   r   Zdefault_keymap r+   ;/tmp/pip-unpacked-wheel-9cz4377o/celery/events/cursesmon.py__init__3   s    	zCursesMonitor.__init__c              
   C   s   | j }|d t d t }|d t d t }|tk r<|}	nt}	||	 d }tt|d }
||
 d }t||		|	}t||	|}t
||
	|
}t|t	t}|	t}| d| d| d| d| d
}| jd krt|d | | _|d | S )N   g       @ )display_widthSTATE_WIDTHTIMESTAMP_WIDTHMIN_TASK_WIDTHMIN_WORKER_WIDTH
UUID_WIDTHintr   r
   ljustr   screen_widthlen)r*   uuidtaskworker	timestampr   mxZdetail_widthZ
uuid_spaceZ
uuid_widthZ
task_widthZworker_widthrowr+   r+   r,   
format_rowC   s$    
"
zCursesMonitor.format_rowc                 C   s   | j  \}}|S Nwingetmaxyxr*   _r>   r+   r+   r,   r8   ^   s    zCursesMonitor.screen_widthc                 C   s   | j  \}}|S rA   rB   r*   myrF   r+   r+   r,   screen_heightc   s    zCursesMonitor.screen_heightc                 C   s   | j  \}}|t S rA   )rC   rD   BORDER_SPACINGrE   r+   r+   r,   r0   h   s    zCursesMonitor.display_widthc                 C   s   | j  \}}|d S )Nr   rB   rG   r+   r+   r,   display_heightm   s    zCursesMonitor.display_heightc                 C   s   | j S rA   )rK   r*   r+   r+   r,   limitr   s    zCursesMonitor.limitc                 C   s8   | j s
dS t| j D ]\}}| j|d kr|  S qdS Nr   )tasks	enumerateselected_task)r*   ier+   r+   r,   find_positionv   s    
zCursesMonitor.find_positionc                 C   s   |  d d S )Nmove_selectionrL   r+   r+   r,   r    ~   s    zCursesMonitor.move_selection_upc                 C   s   |  d d S )Nr.   rV   rL   r+   r+   r,   r      s    z!CursesMonitor.move_selection_downr.   c                 C   sT   | j s
d S |  }z| j ||  d | _W n$ tk
rN   | j d d | _Y nX d S rN   )rO   rT   rQ   
IndexError)r*   	directionposr+   r+   r,   rW      s    zCursesMonitor.move_selectionr   r   r   c                 C   sX   z| j   }W n tk
r(   Y d S X | j|p8|}| j|}|d k	rT|  d S rA   )rC   getkeyupper	Exceptionkeyaliasgetr   )r*   keyhandlerr+   r+   r,   handle_keypress   s    zCursesMonitor.handle_keypressc                 C   s   | j   | j  \}}td }}|rN| j t|d|tjtjB  t| |||t| | j |d ddtj | j 	  z| j 
  W S  tk
r   Y qX qd S )N   r   r.   r   zPress any key to continue...)rC   eraserD   r   addstrnextcursesA_BOLDA_UNDERLINErefreshr[   r\   r]   )r*   callbacktitlerH   r>   y
blank_liner+   r+   r,   alert   s"    


zCursesMonitor.alertc                 C   s   | j st S | jj| j  }|js*t S | j \}}d}| j|d d|tj	tj
B  | j|d t|d d|t|   | |d dt| }|r| jjj|j| dd}| | d S )NzNew rate limit: rc   r   r/   Treply)rQ   rg   beepr   rO   namerC   rD   re   rh   ri   r9   readliner   controlZ
rate_limitstripalert_remote_control_reply)r*   r;   rH   r>   rZrlimitrq   r+   r+   r,   r%      s     ( z"CursesMonitor.selection_rate_limitc                    s    fdd} |dS )Nc           
   	      s   t |} s2jt|ddtjtd  d S  D ]}t|}t| \}}| d}j|d|tj tj}d}	d|kr|d }	|tdO }nd|kr|d }	|tdO }j|dt	| |	| q6d S )Nr   z#No replies received in 1s deadline.rc   :  errorok)
r   rC   re   rf   rg   rh   
color_pairitemsA_NORMALr9   )
rH   r>   xsrm   Zsubreplycurlinehostresponseattrtextrq   r*   r+   r,   rk      s.      
z:CursesMonitor.alert_remote_control_reply.<locals>.callbackzRemote Control Command Replies)ro   )r*   rq   rk   r+   r   r,   rw      s    z(CursesMonitor.alert_remote_control_replyc                 C   sr   d}t   zVd}| j||| }|dkr|dt jfkr<q`|dkrJd}q`|t|7 }|d7 }qW 5 t   X |S )Nrz   r   rU   r   )   r.   )rg   echoZnoechorC   Zgetch	KEY_ENTERchr)r*   xrm   bufferrR   chr+   r+   r,   rt      s    
zCursesMonitor.readlinec                 C   s0   | j st S | jjj| j dd}| | d S )NTrp   )rQ   rg   rr   r   ru   Zrevokerw   )r*   rq   r+   r+   r,   r!      s    zCursesMonitor.revoke_selectionc                    s*    j s
d S  fdd} |d j  S )Nc              
      sJ   j  \}} t|} jj j }|jdgd}d|dd fd|dd fgt|	  }|D ]\}}|d krtqbt
|}t|}	|d }
 j |	d|
tj t|| d }t|dkr j |	t|
d t|d	  jt|
d   qb|D ]R}t|}||d krd
}n||kr qb j |dtd|  jd tj qqbd S )Nr   )extraargskwargsry   r   rc   r.   r   z	    [...]z    r   )rC   rD   r   r   rO   rQ   infopoplistr~   strrf   re   rg   rh   r   r9   r
   r8   r   )r>   rH   r   rm   r;   r   Z	infoitemsr`   valuer   keyswrappedZsublineZnextyrL   r+   r,   alert_callback   sJ    
 

 z4CursesMonitor.selection_info.<locals>.alert_callbackzTask details for rQ   ro   r*   r   r+   rL   r,   r$      s    # 
zCursesMonitor.selection_infoc                    sR    j st S  jj j  jtjkr0t S  fdd} |d j  S )Nc                    s2   t |}jdD ]} jt|d| qd S )N
r   )r   	tracebacksplitrC   re   rf   )rH   r>   r   rm   liner*   r;   r+   r,   r   '  s    z9CursesMonitor.selection_traceback.<locals>.alert_callbackzTask Exception Traceback for )rQ   rg   rr   r   rO   r   EXCEPTION_STATESro   r   r+   r   r,   r"      s    
z!CursesMonitor.selection_tracebackc                    s*    j s
d S  fdd} |d j  S )Nc                    s^   t |} jj j }t|dd p,t|dd }t|p6d|d D ]} jt|d| q@d S )Nresult	exceptionrz   rc   r   )	r   r   rO   rQ   getattrr   rC   re   rf   )rH   r>   r   rm   r;   r   r   rL   r+   r,   r   5  s    
z6CursesMonitor.selection_result.<locals>.alert_callbackzTask Result for r   r   r+   rL   r,   r#   1  s    
zCursesMonitor.selection_resultc           	      C   s   | j |j}tj}|j| jkr&tj}t	|j
p4t }|d}|jrP|jjnd}| |j|j|||j}| j|t|| |r| j|t|t t d |j||B  d S )Nz%H:%M:%Sz*NONE*r.   )state_colorsr_   r   rg   r   r:   rQ   Z
A_STANDOUTr   utcfromtimestampr=   r   strftimer<   hostnamer@   rs   rC   re   LEFT_BORDER_OFFSETr9   r1   rJ   )	r*   linenor;   Zstate_colorr   r=   Ztimefr   r   r+   r+   r,   display_task_rowB  s*    

  zCursesMonitor.display_task_rowc                 C   sb  | j P | j}|   t}td }}| \}}|  |dt	d |
  |d|| jtjt	dB  t| |t||| ddddd	tjtjB  | j}|rt|D ]4\}\}}	|| jkr q|	jrt|}
| |
|	 qt| ||d
 |tj| jd  | jr8||d || jtj d}d}z| jj| j }W n tk
rb   Y n^X | }d|krd|d |d< d|krt |d d|d< d!dd |" D }d}t || jt#| j d |}||d |t#| j | ||krNt#|t#| }||d |t#| j | |tj n||d |dtj$ | j%r||d || j&tj ||d |t#| j& d!t'| j%tj$ n||d |d ||d || j(tj ||d |t#| j( t)j| jt#dd | jj%* D t#| jj%dtj | +|d || j,tj | +|d |t#| j, | j-tj |.  W 5 Q R X d S )Nrc   r/   r.      UUIDZTASKZWORKERZTIMEZSTATE   r   zMissing extended inforz   Zruntimez{:.2f}r   r   c                 s   s    | ]\}}| d | V  qdS )=Nr+   ).0r`   r   r+   r+   r,   	<genexpr>  s   z%CursesMonitor.draw.<locals>.<genexpr>z... -> key izNo task selectedz, zNo workers discovered.r   c                 S   s   g | ]}|j r|qS r+   alive)r   wr+   r+   r,   
<listcomp>  s    z&CursesMonitor.draw.<locals>.<listcomp>)sZw_aliveZw_all)/r)   rC   rb   r   r   rD   rd   Zbkgdrg   r}   Zborderre   greetZA_DIMrf   r@   rh   ri   rO   rP   rK   r:   r   ZhlineZ	ACS_HLINEr8   rQ   selected_strr   KeyErrorr   formatr
   joinr~   r9   r   workers
online_strsortedinfo_strSTATUS_SCREENvaluessafe_add_str
help_titlehelprj   )r*   rC   r   rm   rn   rH   rF   rO   r?   r;   r   r   ZdetailZ	selectionZinfowinZ	detailposr+   r+   r,   drawV  s    
  





   
zCursesMonitor.drawc                 O   s@   |t | | jkr$|d | j|  }| jj|||f|| d S rA   )r9   r8   rC   re   )r*   rm   r   stringr   r   r+   r+   r,   r     s    zCursesMonitor.safe_add_strc              	   C   s   | j  t | _| jd | jd t  td| j| j	 tdtj
| j	 tdtj| j	 tdtj| j	 tdtj| j	 tdtj| j tjtdtjtdtjtdi| _tjD ]}td| j|< qt  W 5 Q R X d S )NTr.   rc   r   r   r   r   )r)   rg   ZinitscrrC   ZnodelaykeypadZstart_colorZ	init_pair
foreground
backgroundZ	COLOR_REDZCOLOR_GREENZCOLOR_MAGENTAZ
COLOR_BLUEZCOLOR_YELLOWr   SUCCESSr}   ZREVOKEDZSTARTEDr   r   Zcbreak)r*   r   r+   r+   r,   init_screen  s(    
  
zCursesMonitor.init_screenc              	   C   s:   | j * t  | jd t  t  W 5 Q R X d S NF)r)   rg   ZnocbreakrC   r   r   ZendwinrL   r+   r+   r,   resetscreen  s
    zCursesMonitor.resetscreenc                 C   s   t | j d S rA   )rg   Znapmsscreen_delayrL   r+   r+   r,   nap  s    zCursesMonitor.napc                 C   s   t | jj| jdS )N)rM   )r   r   Ztasks_by_timerM   rL   r+   r+   r,   rO     s    zCursesMonitor.tasksc                 C   s   dd | j j D S )Nc                 S   s   g | ]\}}|j r|qS r+   r   )r   r   r   r+   r+   r,   r     s    z)CursesMonitor.workers.<locals>.<listcomp>)r   r   r~   rL   r+   r+   r,   r     s    zCursesMonitor.workers)N)r.   )N)6__name__
__module____qualname____doc__r   rC   r   rQ   Zselected_positionr   rg   ZCOLOR_BLACKr   ZCOLOR_WHITEr   r   r   r   r   r   r   r-   r@   propertyr8   rI   r0   rK   rM   rT   r    r   rW   ZKEY_DOWNZKEY_UPr   r^   rb   ro   r%   rw   rt   r!   r$   r"   r#   r   r   r   r   r   r   rO   r   r+   r+   r+   r,   r   "   sn   







	  

+X
r   c                       s$   e Zd Z fddZdd Z  ZS )DisplayThreadc                    s   || _ d| _t   d S r   )displayshutdownsuperr-   )r*   r   	__class__r+   r,   r-     s    zDisplayThread.__init__c                 C   s    | j s| j  | j  q d S rA   )r   r   r   r   rL   r+   r+   r,   run  s    
zDisplayThread.run)r   r   r   r-   r   __classcell__r+   r+   r   r,   r     s   r   c                 C   s   dd }t dtjd |  }zB||| jj | jj|d|j	id}|
  |  |  W n> |j|j k
r } zt d|tjd W 5 d }~X Y nX W 5 Q R X qd S )Nc                 S   s   t d| |tjd d S )Nz&Connection Error: {!r}.  Retry in {}s.file)printr   sysstderr)excintervalr+   r+   r,   on_connection_error  s     z+capture_events.<locals>.on_connection_errorz-> evtop: starting capture...r   *)handlerszConnection lost: )r   r   r   Zconnection_for_readZensure_connectionconfZbroker_connection_max_retrieseventsZReceivereventr   r   captureZconnection_errorsZchannel_errors)r   r   r   r   connrecvr   r+   r+   r,   capture_events  s    
r   c              	   C   s   t | } | j }t|| }|  t|}|  zt| || W nX tk
rp   d|_	|
  |   Y n. ttfk
r   d|_	|
  |  Y nX dS )zStart curses monitor.TN)r	   r   Stater   r   r   startr   r]   r   r   r   KeyboardInterrupt
SystemExit)r   r   r   Z	refresherr+   r+   r,   r     s"    

r   __main__)N)#r   rg   r   r'   r   	itertoolsr   mathr   textwrapr   r   Zceleryr   r   Z
celery.appr	   Zcelery.utils.textr
   r   __all__rJ   r   r5   r1   r2   r4   r3   r   r   Threadr   r   r   r   r+   r+   r+   r,   <module>   s:      B
