ó
P'—^c           @@ s†  d  Z  d d l m Z m 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 d d
 l m Z d d l m Z d d l m Z m Z d d l m Z m Z d d g Z d Z d Z d Z d Z d Z d Z  d Z! d Z" d e# f d „  ƒ  YZ$ d e j% f d „  ƒ  YZ& d „  Z' e( d „ Z) e* d k r‚e) ƒ  n  d S(   sp   
    celery.events.cursesmon
    ~~~~~~~~~~~~~~~~~~~~~~~

    Graphical monitor of Celery events using curses.

i    (   t   absolute_importt   print_functionN(   t   datetime(   t   count(   t   wrap(   t   time(   t   ceil(   t   VERSION_BANNER(   t   states(   t   app_or_default(   t   itemst   values(   t   abbrt   abbrtaskt   CursesMonitort   evtopi   i   i$   i   i   i   sG   events: {s.event_count} tasks:{s.task_count} workers:{w_alive}/{w_all}
c           B@ s¾  e  Z i  Z d( Z d( Z d  Z d( Z d Z d Z	 e
 j Z e
 j Z d Z d Z d Z d j e ƒ Z d Z d( d „ Z d	 „  Z e d
 „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z d d „ Z  i d e
 j! 6d e
 j" 6d e
 j# 6Z$ d „  Z% d( d „ Z& d „  Z' d „  Z( d „  Z) d „  Z* d „  Z+ d „  Z, d „  Z- d  „  Z. d! „  Z/ d" „  Z0 d# „  Z1 d$ „  Z2 d% „  Z3 e d& „  ƒ Z4 e d' „  ƒ Z5 RS()   i
   i    s
   Selected: s   Workers online: s   Keys: s9   j:down k:up i:info t:traceback r:result c:revoke ^c: quits   celery events {0}s   Info: c         C@ s˜   | |  _  | p |  j |  _ | |  _ i |  j d 6|  j d 6|  j d 6|  j d 6|  j d 6|  j d 6|  j	 d 6} t
 | |  j  |  _ t j ƒ  |  _ d  S(   Nt   Jt   Kt   Ct   Tt   Rt   It   L(   t   appt   keymapt   statet   move_selection_downt   move_selection_upt   revoke_selectiont   selection_tracebackt   selection_resultt   selection_infot   selection_rate_limitt   dictt	   threadingt   RLockt   lock(   t   selfR   R   R   t   default_keymap(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   __init__=   s    		




c         C@ s9  |  j  } | d t d t } | d t d t } | t k  rJ | }	 n t }	 | |	 d } t t | d ƒ ƒ }
 | |
 d } t | |	 ƒ j	 |	 ƒ } t | | ƒ j	 | ƒ } t
 | |
 ƒ j	 |
 ƒ } t | t ƒ j	 t ƒ } | j	 t ƒ } d j | | | | | ƒ } |  j d  k r1t | |  ƒ |  _ n  | |  S(   Ni   g       @s   {0} {1} {2} {3} {4} (   t   display_widtht   STATE_WIDTHt   TIMESTAMP_WIDTHt   MIN_TASK_WIDTHt   MIN_WORKER_WIDTHt
   UUID_WIDTHt   intR   R   t   ljustR   t   formatt   screen_widtht   Nonet   len(   R%   t   uuidt   taskt   workert	   timestampR   t   mxt   detail_widtht
   uuid_spacet
   uuid_widtht
   task_widtht   worker_widtht   row(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt
   format_rowK   s&    		c         C@ s   |  j  j ƒ  \ } } | S(   N(   t   wint   getmaxyx(   R%   t   _R8   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR1   g   s    c         C@ s   |  j  j ƒ  \ } } | S(   N(   R@   RA   (   R%   t   myRB   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   screen_heightl   s    c         C@ s   |  j  j ƒ  \ } } | t S(   N(   R@   RA   t   BORDER_SPACING(   R%   RB   R8   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR(   q   s    c         C@ s   |  j  j ƒ  \ } } | d S(   Ni
   (   R@   RA   (   R%   RC   RB   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   display_heightv   s    c         C@ s   |  j  S(   N(   RF   (   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   limit{   s    c         C@ sH   |  j  s d Sx4 t |  j  ƒ D]# \ } } |  j | d k r | Sq Wd S(   Ni    (   t   taskst	   enumeratet   selected_task(   R%   t   it   e(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   find_position   s    	c         C@ s   |  j  d ƒ d  S(   Niÿÿÿÿ(   t   move_selection(   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   ‡   s    c         C@ s   |  j  d ƒ d  S(   Ni   (   RN   (   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   Š   s    i   c         C@ sa   |  j  s d  S|  j ƒ  } y |  j  | | d |  _ Wn% t k
 r\ |  j  d d |  _ n Xd  S(   Ni    (   RH   RM   RJ   t
   IndexError(   R%   t	   directiont   pos(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyRN      s    	R   R   R   c         C@ sh   y |  j  j ƒ  j ƒ  } Wn d  SX|  j j | ƒ p9 | } |  j j | ƒ } | d  k	 rd | ƒ  n  d  S(   N(   R@   t   getkeyt   uppert   keyaliast   getR   R2   (   R%   t   keyt   handler(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   handle_keypressš   s    c         C@ sÝ   |  j  j ƒ  |  j  j ƒ  \ } } t d ƒ } } | rn |  j  j t | ƒ d | t j t j Bƒ t | ƒ n  | | | t | ƒ ƒ |  j  j | d d d t j ƒ |  j  j	 ƒ  x% y |  j  j
 ƒ  j ƒ  SWq´ q´ Xq´ Wd  S(   Ni   i   i   i    s   Press any key to continue...(   R@   t   eraseRA   R   t   addstrt   nextt   cursest   A_BOLDt   A_UNDERLINEt   refreshRR   RS   (   R%   t   callbackt   titleRC   R8   t   yt
   blank_line(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   alert¤   s     
c         C@ s  |  j  s t j ƒ  S|  j j |  j  } | j s9 t j ƒ  S|  j j ƒ  \ } } d } |  j j | d d | t j	 t j
 Bƒ |  j j | d t | ƒ d d | t | ƒ ƒ |  j | d d t | ƒ ƒ } | r
|  j j j | j | j ƒ  d t ƒ} |  j | ƒ n  d  S(   Ns   New rate limit: i   i   t    t   reply(   RJ   R\   t   beepR   RH   t   nameR@   RA   RZ   R]   R^   R3   t   readlineR   t   controlt
   rate_limitt   stript   Truet   alert_remote_control_reply(   R%   R5   RC   R8   t   rt   rlimitRf   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR    ¶   s    	
	
'2 c         @ s"   ‡  ‡ f d †  } ˆ j  | d ƒ S(   Nc   
      @ s3  t  | ƒ } ˆ  sE ˆ j j t | ƒ d d t j t j d ƒ ƒ d  Sxç ˆ  D]ß } t | ƒ } t t | ƒ ƒ \ } } d j | ƒ } ˆ j j | d | t j ƒ t j	 } d }	 d | k rÜ | d }	 | t j d ƒ O} n, d | k r| d }	 | t j d ƒ O} n  ˆ j j | d t
 | ƒ |	 | ƒ qL Wd  S(   Ni   s#   No replies received in 1s deadline.i   s   {0}: t    t   errort   ok(   R   R@   RZ   R[   R\   R]   t
   color_pairR
   R0   t   A_NORMALR3   (
   RC   R8   t   xsRb   t   subreplyt   curlinet   hostt   responset   attrt   text(   Rf   R%   (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR`   Ê   s(    		

s   Remote Control Command Replies(   Rd   (   R%   Rf   R`   (    (   Rf   R%   s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyRn   È   s    c         C@ sª   t  ƒ  } t j ƒ  z… d } xx |  j j | | | ƒ } | d k r | d t j f k r] Pn  | d k rv t  ƒ  } Pn  | t | ƒ 7} | d 7} q q WWd  t j ƒ  X| S(   Ni    iÿÿÿÿi
   i   i   (   i   (   t   strR\   t   echoR@   t   getcht	   KEY_ENTERt   chrt   noecho(   R%   t   xRb   t   bufferRK   t   ch(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyRi   å   s     	
	c         C@ sB   |  j  s t j ƒ  S|  j j j |  j  d t ƒ} |  j | ƒ d  S(   NRf   (   RJ   R\   Rg   R   Rj   t   revokeRm   Rn   (   R%   Rf   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   ø   s    	
c         @ s5   ˆ  j  s d  S‡  f d †  } ˆ  j | d j ˆ  ƒ ƒ S(   Nc      	   @ sÐ  ˆ  j  j ƒ  \ } }  t | ƒ } ˆ  j j ˆ  j } | j d d g ƒ } d | j d d  ƒ f d | j d d  ƒ f g t	 | j
 ƒ  ƒ } x@| D]8\ } } | d  k r® q n  t | ƒ } t | ƒ }	 | d }
 ˆ  j  j |	 d |
 t j ƒ t | |  d ƒ } t | ƒ d k rRˆ  j  j |	 t |
 ƒ d t | d	 ˆ  j t |
 ƒ d ƒ ƒ q xs | D]k } t | ƒ } | | d k r„d } n | | k r”Pn  ˆ  j  j | d t d | ˆ  j d ƒ t j ƒ qYWq Wd  S(   Nt   extraR   t   argst   kwargss   : i   i   i   i    Re   i   s   [...]s       s	       [...]s       (   R@   RA   R   R   RH   RJ   t   infot   popR2   t   listR
   R}   R[   RZ   R\   R]   R   R3   R   R1   Ru   (   R8   RC   Rv   Rb   R5   RŠ   t	   infoitemsRV   t   valueRx   t   keyst   wrappedt   sublinet   nexty(   R%   (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   alert_callback  s<    
	
		s"   Task details for {0.selected_task}(   RJ   Rd   R0   (   R%   R“   (    (   R%   s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   þ   s
    	#c         @ sm   ˆ  j  s t j ƒ  Sˆ  j j ˆ  j  ‰ ˆ j t j k rB t j ƒ  S‡  ‡ f d †  } ˆ  j | d j ˆ  ƒ ƒ S(   Nc         @ sI   t  | ƒ } x6 ˆ j j d ƒ D]" } ˆ  j j t | ƒ d | ƒ q Wd  S(   Ns   
i   (   R   t	   tracebackt   splitR@   RZ   R[   (   RC   R8   Rv   Rb   t   line(   R%   R5   (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR“   0  s    s.   Task Exception Traceback for {0.selected_task}(	   RJ   R\   Rg   R   RH   R   t   EXCEPTION_STATESRd   R0   (   R%   R“   (    (   R%   R5   s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   )  s    	

c         @ s5   ˆ  j  s d  S‡  f d †  } ˆ  j | d j ˆ  ƒ ƒ S(   Nc         @ s‡   t  | ƒ } ˆ  j j ˆ  j } t | d d  ƒ p@ t | d d  ƒ } x= t | pR d | d ƒ D]" } ˆ  j j t	 | ƒ d | ƒ q] Wd  S(   Nt   resultt	   exceptionRq   i   i   (
   R   R   RH   RJ   t   getattrR2   R   R@   RZ   R[   (   RC   R8   Rv   Rb   R5   R˜   R–   (   R%   (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR“   >  s     s!   Task Result for {0.selected_task}(   RJ   Rd   R0   (   R%   R“   (    (   R%   s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   :  s    	c   	      C@ sý   |  j  j | j ƒ } t j } | j |  j k r< t j } n  t j	 | j
 pQ t ƒ  ƒ } | j d ƒ } | j r{ | j j n d } |  j | j | j | | | j ƒ } |  j j | t | | ƒ | rù |  j j | t | ƒ t t d | j | | Bƒ n  d  S(   Ns   %H:%M:%Ss   *NONE*i   (   t   state_colorsRU   R   R\   Ru   R4   RJ   t
   A_STANDOUTR   t   utcfromtimestampR7   R   t   strftimeR6   t   hostnameR?   Rh   R@   RZ   t   LEFT_BORDER_OFFSETR3   R)   RE   (	   R%   t   linenoR5   t   state_colorR{   R7   t   timefRŸ   R–   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   display_task_rowK  s     	c         C@ s—  |  j  ˆ|  j } |  j ƒ  t } t d ƒ } } | j ƒ  \ } } | j ƒ  | j d t j	 d ƒ ƒ | j
 ƒ  | j d | |  j t j t j	 d ƒ Bƒ t | ƒ | j t | ƒ | |  j d d d d d	 ƒ t j t j Bƒ |  j } | rPx^ t | ƒ D]M \ } \ }	 }
 | |  j k r!Pn  |
 j r9t | ƒ } n  |  j | |
 ƒ qü Wn  t | ƒ | j | d
 | t j |  j d ƒ |  j rû| j | d | |  j t j ƒ d } d } y |  j j |  j } Wn t k
 rÝn~ X| j ƒ  } d | k rd j | d ƒ | d <n  d | k r6t  | d d ƒ | d <n  d j! d „  t" | ƒ Dƒ ƒ } d } t  | |  j t# |  j ƒ d | ƒ } | j | d | t# |  j ƒ | ƒ | | k rt# | ƒ t# | ƒ } | j | d | t# |  j ƒ | | t j ƒ qn | j | d | d t j$ ƒ |  j% r€| j | d | |  j& t j ƒ | j | d | t# |  j& ƒ d j! t' |  j% ƒ ƒ t j$ ƒ n | j | d | d ƒ | j | d | |  j( t j ƒ | j | d | t# |  j( ƒ t) j d |  j d t# g  t* |  j j% ƒ D] } | j+ rü| ^ qüƒ d t# |  j j% ƒ ƒ t j ƒ |  j, | d | |  j- t j ƒ |  j, | d | t# |  j- ƒ |  j. t j ƒ | j/ ƒ  Wd  QXd  S(   Ni   Re   i   i   t   UUIDt   TASKt   WORKERt   TIMEt   STATEi   i   s   Missing extended infoRq   t   runtimes   {0:.2f}R˜   i   c         s@ s'   |  ] \ } } d  j  | | ƒ Vq d S(   s   {0}={1}N(   R0   (   t   .0RV   RŽ   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pys	   <genexpr>Œ  s   s   ... -> key is   No task selecteds   , s   No workers discovered.i   t   st   w_alivet   w_all(0   R$   R@   RX   R    R   RA   RY   t   bkgdR\   Rt   t   borderRZ   t   greett   A_DIMR[   R?   R]   R^   RH   RI   RF   R4   R¤   t   hlinet	   ACS_HLINER1   RJ   t   selected_strR   t   KeyErrorRŠ   R0   R   t   joinR
   R3   Ru   t   workerst
   online_strt   sortedt   info_strt   STATUS_SCREENR   t   alivet   safe_add_strt
   help_titlet   helpR_   (   R%   R@   Rƒ   Rb   Rc   RC   R8   RH   R>   R4   R5   R¡   RŠ   t   detailt	   selectiont   infowint	   detailpost   w(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   draw_  sˆ    
	


)
		
$	 	$!	 " 		
 #
c         O@ sM   | t  | ƒ |  j k r- | |  j |  } n  |  j j | | | | | Ž d  S(   N(   R3   R1   R@   RZ   (   R%   Rb   Rƒ   t   stringRˆ   R‰   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR¾   ·  s    c         C@ sY  |  j  Jt j ƒ  |  _ |  j j t ƒ |  j j t ƒ t j ƒ  t j d |  j	 |  j
 ƒ t j d t j |  j
 ƒ t j d t j |  j
 ƒ t j d t j |  j
 ƒ t j d t j |  j
 ƒ t j d t j |  j	 ƒ i t j d ƒ t j 6t j d ƒ t j 6t j d ƒ t j 6|  _ x' t j D] } t j d ƒ |  j | <q%Wt j ƒ  Wd  QXd  S(   Ni   i   i   i   i   i   (   R$   R\   t   initscrR@   t   nodelayRm   t   keypadt   start_colort	   init_pairt
   foregroundt
   backgroundt	   COLOR_REDt   COLOR_GREENt   COLOR_MAGENTAt
   COLOR_BLUEt   COLOR_YELLOWRt   R   t   SUCCESSt   REVOKEDt   STARTEDR›   R—   t   cbreak(   R%   R   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   init_screen¼  s"    

c         C@ sB   |  j  3 t j ƒ  |  j j t ƒ t j ƒ  t j ƒ  Wd  QXd  S(   N(   R$   R\   t   nocbreakR@   RÊ   t   FalseR~   t   endwin(   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   resetscreenÖ  s
    


c         C@ s   t  j |  j ƒ d  S(   N(   R\   t   napmst   screen_delay(   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   napÝ  s    c         C@ s   t  |  j j d |  j ƒ ƒ S(   NRG   (   RŒ   R   t   tasks_by_timeRG   (   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyRH   à  s    c         C@ s2   g  t  |  j j ƒ D] \ } } | j r | ^ q S(   N(   R
   R   R¸   R½   (   R%   RŸ   RÅ   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR¸   ä  s    N(6   t   __name__t
   __module__R   R2   R@   R1   RÞ   RJ   t   selected_positionRµ   R\   t   COLOR_BLACKRÍ   t   COLOR_WHITERÎ   R¹   R¿   RÀ   R0   R   R±   R»   R'   R?   t   propertyRD   R(   RF   RG   RM   R   R   RN   t   KEY_DOWNt   KEY_UPR€   RT   RX   Rd   R    Rn   Ri   R   R   R   R   R¤   RÆ   R¾   RØ   RÜ   Rß   RH   R¸   (    (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR   -   sZ   							
	
					+				X				t   DisplayThreadc           B@ s   e  Z d  „  Z d „  Z RS(   c         C@ s&   | |  _  t |  _ t j j |  ƒ d  S(   N(   t   displayRÚ   t   shutdownR"   t   ThreadR'   (   R%   Rê   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR'   ì  s    		c         C@ s.   x' |  j  s) |  j j ƒ  |  j j ƒ  q Wd  S(   N(   Rë   Rê   RÆ   Rß   (   R%   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   runñ  s    (   Rá   Râ   R'   Rí   (    (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyRé   ê  s   	c      
   C@ sÒ   d „  } xÂ t  d d t j ƒ|  j ƒ   } yZ | j | |  j j ƒ |  j j | d i | j	 d 6ƒ} | j
 ƒ  | j ƒ  | j ƒ  Wn9 | j | j k
 rÃ } t  d j | ƒ d t j ƒn XWd  QXq Wd  S(   Nc         S@ s#   t  d j |  | ƒ d t j ƒd  S(   Ns'   Connection Error: {0!r}. Retry in {1}s.t   file(   t   printR0   t   syst   stderr(   t   exct   interval(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   on_connection_errorù  s    	s   -> evtop: starting capture...Rî   t   handlerst   *s   Connection lost: {0!r}(   Rï   Rð   Rñ   t
   connectiont   ensure_connectiont   conft   BROKER_CONNECTION_MAX_RETRIESt   eventst   Receivert   eventRÜ   RØ   t   capturet   connection_errorst   channel_errorsR0   (   R   R   Rê   Rô   t   connt   recvRò   (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   capture_events÷  s    		"

c         C@ sÉ   t  |  ƒ }  |  j j ƒ  } t | |  ƒ } | j ƒ  t | ƒ } | j ƒ  y t |  | | ƒ Wnd t k
 r‘ t	 | _
 | j ƒ  | j ƒ  ‚  n4 t t f k
 rÄ t	 | _
 | j ƒ  | j ƒ  n Xd  S(   N(   R	   Rû   t   StateR   RØ   Ré   t   startR  t	   ExceptionRm   Rë   R·   RÜ   t   KeyboardInterruptt
   SystemExit(   R   R   Rê   t	   refresher(    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyR     s"    

	

	
t   __main__(+   t   __doc__t
   __future__R    R   R\   Rð   R"   R   t	   itertoolsR   t   textwrapR   R   t   mathR   t   celeryR   R   t
   celery.appR	   t   celery.fiveR
   R   t   celery.utils.textR   R   t   __all__RE   R    R-   R)   R*   R,   R+   R¼   t   objectR   Rì   Ré   R  R2   R   Rá   (    (    (    s9   /tmp/pip-unpacked-wheel-gV1wwp/celery/events/cursesmon.pyt   <module>   s<   ÿ ¾	