ó
é±Wc           @   sD  d  d l  Z  y d  d l Z Wn e k
 r; d  d l Z n Xd  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l	 Z	 d  d l
 Z
 d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d Z d dR d „  ƒ  YZ e j a d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z e ƒ  Z d „  Z  d „  Z! d „  Z" d „  Z# d „  Z$ d „  Z% 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 d# „  Z4 d$ „  Z5 d% „  Z6 d& „  Z7 d' „  Z8 e9 d( „ Z: d) „  Z; d* „  Z< d+ „  Z= d, „  Z> e? d- k r@e j e j@ e jA ƒ e j e jB e> ƒ e= ƒ  \ ZC ZD e; ƒ  ZE e< eE d. ƒ d/ e jF ƒ  d0 e  jG d1 d2 !f ZH e jI jJ eC jK d3 ƒ eC jK e jI jJ eC jK d4 ƒ e jI jJ eC jK eH ƒ g e  jI d1 *e jL jM d5 ƒ d k	 rse jL jM d5 ƒ ZO nz e jI jP eC jQ ƒ sÅeE jR d6 d6 jJ e
 jS d7 eC jQ f ƒ ƒ ƒ e  jT d8 ƒ n  eU eC jQ ƒ jV ƒ  jW ƒ  ZO eO e jL d5 <eC jX d k r,eC jY d k	 r,eE jR d6 d9 ƒ e  jT d8 ƒ n  eC jZ d: Z[ d  d l\ Z\ e\ j] d; e[ d< eO d= e^ d> d? d@ d ƒ Z_ e j ƒ  Z` eC ja r¸e< eE d ƒ eE jb dA ƒ e7 e^ ƒ e  jT d1 ƒ n  eC jc sódB Zd eC je d k	 rìdC ed eC je f Zd n% eC jZ d k	 rdD ed eC jZ f Zd n  e jf dE dF e jL dG dH ed g dI e jg dJ e jg ƒZh eh ji ƒ  \ Zj Zk x– el em ej jn ƒ  ƒ D]| Zo eo e jp ƒ  k speo e jq ƒ  k r qpn  eE jb dK eo f ƒ y e jr eo e jB ƒ Wqpes k
 rëeE jt dL ƒ qpXqpWn  eC je d k	 r2e eC je ƒ e dM ƒ k r2e9 eC _u e9 eC _v n  eC jw d k rPe6 ƒ  eC _w n  eC jx d k rudN eC jZ f eC _x n  eC jv rÉe jy ƒ  Zz ez d1 k rÏe j{ a e< eE dO ƒ e5 eC ƒ e  jT d1 ƒ qÏn d Zz e j| a d  d l} Z} dP Z~ eC je d k	 re~ dQ eC je f 7Z~ n  e< eE e~ ƒ e j e j@ e j ƒ e. eC ƒ n  d S(S   iÿÿÿÿNt   CountingBackoffc           B   s/   e  Z d  d „ Z d „  Z d „  Z d „  Z RS(   i
   c         C   s   d |  _  | |  _ d  S(   Ni    (   t   number_of_retriest   maximum_retries(   t   selfR   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   __init__,   s    	c         C   s   |  j  |  j k  S(   N(   R   R   (   R   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt
   keep_going0   s    c         C   s   d |  _  d  S(   Ni    (   R   (   R   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   succeed3   s    c         C   s    t  |  j d |  j ƒ |  _ d  S(   Ni   (   t   minR   R   (   R   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   fail6   s    (   t   __name__t
   __module__R   R   R   R   (    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR    +   s   		t   RandomExponentialBackoffc           B   s   e  Z d  „  Z RS(   c         C   s    t  |  j d |  j ƒ |  _ t d |  j d d ƒ d } | t j d | ƒ } d | | d f } y t j | ƒ Wn t k
 rŽ | GHn Xt	 j
 | ƒ d  S(   Ni   i   g       @s*   Sleeping for %ss [max %s] before retrying.(   R   R   R   t   intt   randomt   randintt   loggert   warningt	   NameErrort   timet   sleep(   R   t   delay_scalet   delayt   message(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR   ;   s    	(   R	   R
   R   (    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR   :   s   s   https://zephyr.zulipchat.comt   Statesc           B   s    e  Z e d  ƒ \ Z Z Z Z RS(   i   (   R	   R
   t   ranget   Startupt   ZulipToZephyrt   ZephyrToZulipt   ChildSending(    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR   K   s   c         C   sˆ   d |  k r$ |  j  d ƒ \ } } n |  d } } | j ƒ  d k rl | j ƒ  d k r^ d } n  | j ƒ  d S| j ƒ  d | j ƒ  d S(   Nt   @s   ATHENA.MIT.EDUt   golemt   ctls   @mit.edut   |(   t   splitt   uppert   lower(   t   zephyr_usernamet   usert   realm(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   to_zulip_usernameO   s    	c         C   s¢   |  j  d ƒ \ } } d | k rJ | j ƒ  d k r< d } n  | j ƒ  d St j d | ƒ } | sx t d |  f ƒ ‚ n  | j d ƒ j ƒ  d | j d	 ƒ j ƒ  S(
   NR   R    R   R   s   @ATHENA.MIT.EDUs   ([a-zA-Z0-9_]+)\|(.+)s4   Could not parse Zephyr realm for cross-realm user %si   i   (   R!   R#   t   ret   matcht	   Exceptiont   groupR"   (   t   zulip_usernameR%   R&   t
   match_user(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   to_zephyr_username[   s    	c         C   sl   | j  ƒ  } t |  d | d ƒ t | ƒ d k  pk t |  d | d ƒ d k  pk t |  ƒ t | d ƒ k  S(   Nt    i    gš™™™™™é?i2   (   R!   t   len(   t   linet	   next_linet   words(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   different_paragraphq   s    (c      	   C   sü   |  j  d ƒ } d } | d } xÌ | d D]À } | j ƒ  } t j d | d t j ƒrƒ t j d | d t j ƒrƒ | | d 7} na | d k sÅ | d k sÅ t j d | d t j ƒsÅ t | | ƒ rÖ | | d 7} n | | d 7} | } q* W| | 7} | S(	   Ns   
t    i    i   s   ^\Wt   flagss   

R/   (   R!   t   rstripR(   R)   t   UNICODER4   (   t   bodyt   linest   resultt   previous_lineR1   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   unwrap_linesy   s"    


c         C   sr  i  } t  j r d | d <n  |  d | d <|  d | d <t |  d ƒ | d <d |  k rm |  d d  | d <n  |  d d k r|  d d	 k r¹ |  d j ƒ  | d
 <d |  d f | d <q|  d d k rõ |  d j ƒ  | d
 <d |  d f | d <q|  d | d
 <n |  d | d
 <t |  d ƒ | d <t  j ret  j t k ret j	 d t
 | ƒ f ƒ i d d 6St j | ƒ S(   Nt   yest   forgedt   typeR   t   sendert   subjecti<   t   streamR   t   tos   instance %ss   tabbott-test5s   test instance %st	   recipientt   contents   Message is: %st   successR;   (   t   optionst   forward_class_messagesR'   R#   R=   t	   test_modet   sitet   DEFAULT_SITER   t   debugt   strt   zulip_clientt   send_message(   t   zephR   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt
   send_zulip�   s,    	c         C   s3   i d d 6t  d 6t  d 6|  d 6} t j | ƒ d  S(   Nt   privateR@   RA   RD   RF   (   t   zulip_account_emailRO   RP   (   t	   error_msgR   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   send_error_zulip°   s
    

c         C   s3  y t  j j |  ƒ WnO t k
 re t j d ƒ t j d g  |  D] \ } } } | ^ qA f ƒ d  SXy/ g  t  j j ƒ  D] \ } } } | ^ qy } Wn t k
 r¶ t j d ƒ d  SXxu |  D]m \ } } } | | k rt j d | f ƒ y t  j j	 | | | ƒ Wq+t k
 rq+Xq¾ t
 j | ƒ q¾ Wd  S(   Ns8   Error subscribing to streams (will retry automatically):s   Streams were: %ss*   Error getting current Zephyr subscriptionss/   Zephyr failed to subscribe us to %s; will retry(   t   zephyrt   _zt   subAllt   IOErrorR   t	   exceptionR   t   getSubscriptionst   errort   subt   current_zephyr_subst   add(   t   subst   clst   instanceRE   t   _t   actual_zephyr_subs(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zephyr_bulk_subscribe¹   s&    0/c          C   sþ   y5 t  t j d ƒ }  t j |  j ƒ  ƒ } |  j ƒ  Wn t j d ƒ d  SXt	 ƒ  } x| | D]t } | j
 d ƒ } t j d  k	 r© t j | ƒ j ƒ  j t j ƒ r© q] n  | t k r» q] n  | j | d d f ƒ q] Wt | ƒ d k rú t t | ƒ ƒ n  d  S(   Nt   rs   Error reading public streams:s   utf-8t   *i    (   t   fileRH   t   stream_file_patht
   simplejsont   loadst   readt   closeR   R[   t   sett   encodet   shardt   Nonet   hashlibt   sha1t	   hexdigestt
   startswithR_   R`   R0   Rf   t   list(   t   ft   public_streamst   classes_to_subscribeRC   t   zephyr_class(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   update_subscriptionsÜ   s$    	"c           C   sK   y& t  d  k	 r% t j t  t j ƒ n  Wn t k
 rF t j d ƒ n Xd  S(   NR5   (	   t	   child_pidRr   t   ost   killt   signalt   SIGTERMt   OSErrorR   R[   (    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   maybe_kill_childó   s
    c           C   s9  t  j t  j j t j d d ƒ ƒ j t k sx t j d k sK t j d k r5t  j t  j j t j d d ƒ ƒ j t k r5t	 j
 d ƒ t	 j
 d ƒ t ƒ  y t j j ƒ  Wn t k
 rÊ t	 j d ƒ n Xxg t r1y, t  j t  j j t j d d	 ƒ t j ƒ WqÎ t k
 r-t	 j d
 ƒ t j d ƒ qÎ XqÎ Wn  d  S(   Nt   stampst   restart_stampt   tabbotts   tabbott/extrat   tabbott_stampR5   s7   zephyr mirroring script has been updated; restarting...t	   user_roots   zephyr_mirror_backend.pys=   Error restarting mirroring script; trying again... Traceback:i   (   R~   t   statt   patht   joinRH   t	   root_patht   st_mtimet
   start_timeR%   R   R   Rƒ   RW   RX   t
   cancelSubsRZ   R[   t   Truet   execvpt   syst   argvR*   R   R   (    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   maybe_restart_mirroring_scriptû   s     --	,c         C   s¬  d } t  j  ƒ  } x“t r§t j t j j ƒ  g g  g  d ƒ yr xk t r­ t j d t ƒ } | d  k rk Pn  y t	 | |  ƒ WqC t
 k
 r© t j d ƒ t  j d ƒ qC XqC WWn. t
 k
 rß t j d ƒ t  j d ƒ q n Xt  j  ƒ  | d k r t  j  ƒ  } y- t ƒ  | d k r.t j d ƒ d } n  Wn7 t
 k
 rh| d	 k  rit j d
 ƒ | d 7} qin Xt j r¤y t ƒ  Wq¡t
 k
 r�t j d ƒ q¡Xq¤q q Wd  S(   Ni    i   t   blocks   Error relaying zephyr:i   s   Error checking for new zephyrs:i   s<   Stopped getting errors checking whether restart is required.i   s+   Error checking whether restart is required:s(   Error updating subscriptions from Zulip:(   R   R�   t   selectRW   RX   t   getFDt   receivet   FalseRr   t   process_noticeR*   R   R[   R   R”   t   infoRH   RI   R|   (   t   logt   restart_check_countt   last_check_timet   notice(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   process_loop  sD    	"		c         C   sG   y |  j  d d ƒ \ } } Wn t k
 r< d |  } } n X| | f S(   Nt    i   R5   (   R!   t
   ValueError(   t   zephyr_datat   zsigR9   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   parse_zephyr_body5  s
    c         C   sê   y& t  t j j t j d d ƒ ƒ } Wn t k
 r: d  SXx¨ | j ƒ  D]š } | j ƒ  d k rf qH n  t	 j
 d | ƒ } | d  k r— t j d ƒ qH n  | j ƒ  } | d j ƒ  |  k rH d | k rH | j d ƒ d	 k rH | d SqH Wd  S(
   Nt   HOMEs   .crypt-tableR5   sK   ^crypt-(?P<class>[^:]+):\s+((?P<algorithm>(AES|DES)):\s+)?(?P<keypath>\S+)$s   Invalid crypt_table line!t   classt   keypatht	   algorithmt   AES(   Ri   R~   RŠ   R‹   t   environRZ   Rr   t	   readlinest   stripR(   R)   R   RM   t	   groupdictR#   t   get(   R{   Rc   t   crypt_tableR1   R)   t   groups(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   parse_crypt_table<  s     &"c         C   s²   t  |  | ƒ } | d  k r | St j t j t j ƒ t j d d d d d d d d d	 d
 | g d t j d t j d t j ƒ} | j d | ƒ \ } } t j t j t j	 ƒ | S(   Nt   gpgs	   --decrypts   --no-optionss   --no-default-keyrings   --keyring=/dev/nulls   --secret-keyring=/dev/nulls   --batchs   --quiets   --no-use-agents   --passphrase-filet   stdint   stdoutt   stderrt   input(
   R²   Rr   R€   t   SIGCHLDt   SIG_DFLt
   subprocesst   Popent   PIPEt   communicatet   SIG_IGN(   R{   Rc   R9   R¨   t   pt	   decryptedRd   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   decrypt_zephyrQ  s*    				c         C   s„  t  |  j ƒ \ } } t } t } |  j d k r4 d  S|  j j ƒ  } | t j k r~ t t j	 d ƒ � } | j
 d ƒ Wd  QXd  S|  j d k r– t } n  | rª t j rª d  S| t k rÞ | rÞ t j d | |  j | f ƒ d  S|  j j d ƒ s|  j j d ƒ rt j d ƒ d  S| d	 k rH|  j j ƒ  d
 k rH| rHt j rHd  S| rã| j d ƒ rãt } g  | j d ƒ d d j ƒ  D] } t | j ƒ  ƒ ^ q�}	 |  j |	 k rÇ|	 j t |  j ƒ ƒ n  | j d d ƒ d } qãn  t j r|  j j ƒ  d k rt | |  j j ƒ  | ƒ } n  i t |  j ƒ d 6|  j d 6| d 6| d 6}
 | rjd |
 d <|	 |
 d <ns | r�d |
 d <t |  j ƒ |
 d <nM d |
 d <| |
 d <|  j j ƒ  d k rÉ|  j |
 d <n d |  j f |
 d <| rŽ|  j j ƒ  d k r#|  j j d k r#d |  j |  j f } nV |  j j ƒ  d k rKd |  j f } n. |  j j ƒ  d k rsd |  j f } n d } | |
 d |
 d <n  t |
 ƒ }
 t j  d  | |  j |  j f ƒ | d  k	 rí| j
 t" j# |
 ƒ d ƒ | j$ ƒ  n  t% j& ƒ  d k r€t' j( a) zd y? t* |
 ƒ } | j+ d! ƒ d" k rIt j, d# |
 | f ƒ n  Wn t- k
 rjt j. d$ ƒ n XWd  t% j/ d ƒ Xn  d  S(%   Nt   PINGt   ws   0
R5   s   Skipping ... %s/%s/%ss   Zephyr error: Sees   @(@color(blue))s#   Skipping message we got from Zulip!t   mailt   inboxs   CC:s   
i    i   i   t   cryptR   RA   R¤   RF   RS   R@   RE   RC   RB   s   (instance "%s")R   t   personals   [-c %s -i %s]
s   [-c %s]
s   [-i %s]
s&   Received a message on %s/%s from %s...R;   RG   s   Error relaying zephyr:
%s
%ss   Error relaying zephyr:(0   R¥   R   R™   t   opcodeRb   R#   RH   t   nagios_classRi   t   nagios_patht   writeRE   R�   t   forward_personalsR_   R   RM   Rc   t   formatRv   t   endswitht   forward_mail_zephyrsR!   R'   R­   RA   t   appendRI   RÁ   RN   R   t   decode_unicode_byte_stringsR›   Rr   Rk   t   dumpst   flushR~   t   forkR   R   t   CURRENT_STATERR   R¯   R]   R*   R[   t   _exit(   RŸ   Rœ   R¤   R9   t   is_personalt	   is_huddleR{   Rx   t   xt   huddle_recipientsRQ   t   headingt   res(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyRš   o  s”    		$'
9





'		 c         C   sy   xr |  j  ƒ  D]d } t |  | t ƒ r y |  | j d ƒ } Wn$ t k
 rc |  | j d ƒ } n X| |  | <q q W|  S(   Ns   utf-8s
   iso-8859-1(   t   keyst
   isinstanceRN   t   decodeR*   (   RQ   t   fieldt   decoded(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyRÑ   Ñ  s    c         C   s%   t  j |  ƒ t ƒ  t j d ƒ d  S(   Ni   (   R   R]   Rƒ   R’   t   exit(   R   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   quit_failed_initializationÛ  s    c          C   sq   t  ƒ  }  xW |  j ƒ  rb y t j ƒ  |  j ƒ  d  SWq t k
 r^ t j d ƒ |  j ƒ  q Xq Wt	 d ƒ d  S(   Ns9   Error initializing Zephyr library (retrying).  Traceback:s.   Could not initialize Zephyr library, quitting!(
   R   R   RW   t   initR   RZ   R   R[   R   Rã   (   t   backoff(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zephyr_init_autoretryà  s    	

c         C   s˜   t  ƒ  } x~ | j ƒ  r‰ yC t |  d ƒ j ƒ  } t j j ƒ  t j j | ƒ t t _	 d  SWq t
 k
 r… t j d ƒ | j ƒ  q Xq Wt d ƒ d  S(   NRg   s:   Error loading saved Zephyr session (retrying).  Traceback:s.   Could not load saved Zephyr session, quitting!(   R   R   Ri   Rm   RW   RX   t
   initializet   load_sessionR�   t   __initedRZ   R   R[   R   Rã   (   t   session_pathRå   t   session(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zephyr_load_session_autoretryï  s    		c         C   sz   t  ƒ  } x` | j ƒ  rk y% t j ƒ  j |  ƒ | j ƒ  d  SWq t k
 rg t j d ƒ | j	 ƒ  q Xq Wt
 d ƒ d  S(   Ns6   Error subscribing to personals (retrying).  Traceback:s+   Could not subscribe to personals, quitting!(   R   R   RW   t   SubscriptionsR`   R   RZ   R   R[   R   Rã   (   R^   Rå   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zephyr_subscribe_autoretryþ  s    	
c         C   s  |  j  r; t j j |  j ƒ r; t j d ƒ t |  j ƒ nŠ t ƒ  |  j	 rU t
 ƒ  n  |  j ru t d ƒ t d ƒ n  |  j r— t |  j d d f ƒ n  |  j  rÅ t |  j d ƒ j t j j ƒ  ƒ n  |  j d  k	 rÄt |  j d ƒ �Ù } xÏ | D]Ç } y“ t j | ƒ } t | ƒ } d	 | k r1| d	 | d
 <n  d | k rN| d | d <n  t j d | j d
 | j d ƒ ƒ | d f ƒ t | ƒ Wqð t k
 r¶t j d ƒ t j d ƒ qð Xqð WWd  QXn  t j d ƒ |  j d  k	 rt |  j d ƒ � } t  | ƒ Wd  QXn
 t  d  ƒ d  S(   Ns   Loading old sessionR   Rh   s   %me%RÄ   RÅ   RÃ   Rg   R§   RC   Rc   RB   s&   sending saved message to %s from %s...RE   RA   s   Could not send saved zephyr:i   s0   Successfully initialized; Starting receive loop.t   a(   s   messageRh   s   %me%(   s   mails   inboxs   %me%(!   t   use_sessionsR~   RŠ   t   existsRê   R   R›   Rì   Ræ   RI   R|   RÌ   Rî   RÉ   Ri   RË   RW   RX   t   dump_sessiont   logs_to_resendRr   t   openRk   Rl   RÑ   R¯   RR   R*   R[   R   R   t   resend_log_pathR    (   RH   Rœ   t   lnRQ   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zephyr_to_zulip  sF    	
	
		%	c         C   sá   t  j |  d t  j d t  j d t  j ƒ} | j d | j d ƒ ƒ \ } } | j r” t j d d j |  ƒ | j f ƒ | rº t j	 d | ƒ qº n& | rº t j
 d	 d j |  ƒ f ƒ n  | rÔ t j
 d
 | ƒ n  | j | f S(   NR´   Rµ   R¶   R·   s   utf-8s/   zwrite command '%s' failed with return code %d:R/   s   stdout: s2   zwrite command '%s' printed the following warning:s   stderr: (   Rº   R»   R¼   R½   Rp   t
   returncodeR   R]   R‹   R›   R   (   t   zwrite_argsRF   R¿   Rµ   R¶   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   send_zephyr@  s    !			c         C   s   t  |  | ƒ S(   N(   Rú   (   Rù   RF   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   send_authed_zephyrP  s    c         C   s   t  |  d g | ƒ S(   Ns   -d(   Rú   (   Rù   RF   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   send_unauthed_zephyrS  s    c         C   s�   t  |  | ƒ } | d  k r d  St j d d d d d d d d d	 d
 d d d | g d t j d t j d t j ƒ} | j d | ƒ \ } } | S(   NR³   s   --symmetrics   --no-optionss   --no-default-keyrings   --keyring=/dev/nulls   --secret-keyring=/dev/nulls   --batchs   --quiets   --no-use-agents   --armors   --cipher-algoRª   s   --passphrase-fileR´   Rµ   R¶   R·   (   R²   Rr   Rº   R»   R¼   R½   (   R{   Rc   RF   R¨   R¿   t	   encryptedRd   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zcrypt_encrypt_contentV  s*    				c      
      s   d } d } t  j d t d t ƒ ‰  d j ‡  f d †  |  d j d d	 ƒ j d ƒ Dƒ ƒ } d
 d d |  d d d g } |  d d k rª t d k rª | j d d g ƒ n  |  d d k r~|  d } |  d } t j	 d | ƒ } | rø | j
 d ƒ } nS | d | f k s| d | f k rK| j d ƒ r<| } d } qK| } d } n  | j d | d | g ƒ t j d  | | f ƒ n|  d d! k rœt |  d ƒ d k rÈt |  d d" d# ƒ } | g }	 n° t |  d ƒ d$ k r5d% } xB |  d D]6 }
 |
 d# j ƒ  t j ƒ  k rït |
 d# ƒ } PqïqïW| g }	 nC | j d& g ƒ g  |  d D]" } t | d# ƒ j d' d% ƒ ^ qP}	 t j d( |	 f ƒ | j |	 ƒ n  |  j d) ƒ rùt | | | ƒ } | d  k rÝt d* | | f ƒ S| } | j d+ d, g ƒ n  t j r&t j d- | | j d. ƒ f ƒ d  St | | ƒ \ } } | d" k rW| d% k rWd  S| d" k rzt d/ | | | f ƒ S| d" k ré| j d0 ƒ s¤| j d1 ƒ rét | | ƒ \ } } | d" k rét j rÒd  St d2 | | f ƒ Sn  t d3 | | | f ƒ S(4   Ns2   Hi there! This is an automated message from Zulip.sb   If you have any questions, please be in touch through the Feedback button or at support@zulip.com.t   break_long_wordst   break_on_hyphenss   
c         3   s'   |  ] } d  j  ˆ  j | ƒ ƒ Vq d S(   s   
N(   R‹   t   wrap(   t   .0R1   (   t   wrapper(    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pys	   <genexpr>u  s   RF   R   s   @@t   zwrites   -ns   -st   sender_full_names   -Fs/   Zephyr error: See http://zephyr.1ts.org/wiki/dfR@   RC   s   ctl@mit.edus   -SR   t   display_recipientRB   s   ^\(instance "(\s*)"\)$i   s   instance %ss   test instance %st   tests   tabbott-test5R   s   -cs   -is+   Forwarding message to class %s, instance %sRS   i    t   emaili   R5   s   -Cs   @ATHENA.MIT.EDUs   Forwarding message to %st   invite_only_streamsP  %s

Your Zulip-Zephyr mirror bot was unable to forward that last message from Zulip to Zephyr because you were sending to a zcrypted Zephyr class and your mirroring bot does not have access to the relevant key (perhaps because your AFS tokens expired). That means that while Zulip users (like you) received it, Zephyr users did not.

%ss   -ORÆ   s   Would have forwarded: %s
%ss   utf-8sm   %s

Your last message was successfully mirrored to zephyr, but zwrite returned the following warning:

%s

%ss/   zwrite: Ticket expired while sending notice to s;   zwrite: No credentials cache found while sending notice to sB  %s

Your last message was forwarded from Zulip to Zephyr unauthenticated, because your Kerberos tickets have expired. It was sent successfully, but please renew your Kerberos tickets in the screen session where you are running the Zulip-Zephyr mirroring bot, so we can send authenticated Zephyr messages for you again.

%ssÚ   %s

Your Zulip-Zephyr mirror bot was unable to forward that last message from Zulip to Zephyr. That means that while Zulip users (like you) received it, Zephyr users did not.  The error message from zwrite was:

%s

%s(   t   textwrapt   TextWrapperR™   R‹   t   replaceR!   RT   t   extendR(   R)   R+   Rv   R   R›   R0   R.   R#   R¯   Rþ   Rr   RV   RH   RJ   RM   Rp   Rû   Rü   t   ignore_expired_tickets(   R   t   support_headingt   support_closingt   wrapped_contentRù   R{   Rc   t   match_whitespace_instanceRE   t
   recipientsRg   R%   R;   t   codeR¶   (    (   R  sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   forward_to_zephyro  s„    &

		0			c         C   s÷   |  d t  k ró |  d d k pc |  d d k oc t g  |  d D] } | d j ƒ  j d ƒ ^ q> k sj d  St j j ƒ  j d ƒ } t |  d	 ƒ t | ƒ d
 k  rÁ t j	 d |  d	 | f ƒ d  Sy t
 |  ƒ Wqó t k
 rï t j d ƒ qó Xn  d  S(   Nt   sender_emailR@   RC   RS   R  R  s   mit.edus   %st	   timestampi   s&   Skipping out of order message: %s < %ss   Error forwarding message:(   RT   R™   R#   RÎ   t   datetimet   nowt   strftimet   floatR   R   R  R*   R[   (   R   t   ut   timestamp_now(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   maybe_forward_to_zephyrè  s    0 	c         C   s]   t  j d ƒ xI t rX y t j t ƒ Wq t k
 rT t  j d ƒ t j	 d ƒ q Xq Wd  S(   Ns   Starting syncing messages.s   Error syncing messages:i   (
   R   R›   R�   RO   t   call_on_each_messageR  R*   R[   R   R   (   RH   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   zulip_to_zephyrý  s    	c          C   s‘   t  j j d ƒ }  |  d  k	 r( |  d k SxU t d t ƒ D]D \ } } } | j ƒ  d k r8 | j ƒ  d k r8 d t  j d <t Sq8 Wd t  j d <t S(   Nt   HUMBUG_FORWARD_MAIL_ZEPHYRSR�   t   verboseRÄ   RÅ   R™   (   R~   R«   R¯   Rr   t   parse_zephyr_subsR™   R#   R�   (   t   stored_resultRb   Rc   RE   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   subscribed_to_mail_messages  s    
$c      
   C   sç  t  ƒ  } t  ƒ  } xOt d |  ƒ D]>\ } } } | j ƒ  d k r¢ | d k rU q" n  | d k r� | d k r" | j | | | d f ƒ q" q" n  | j | ƒ q" n± | j ƒ  d k rÌ | j ƒ  d k rÌ q" n‡ t | ƒ d k rý | j | | | d f ƒ q" nV | d k r(| j | | | d	 f ƒ q" n+ | d k rS| j | | | d
 f ƒ q" n  | j | ƒ q" Wt | ƒ d k rít j t d „  | Dƒ ƒ d t ƒ} | j	 d ƒ d k rÌt
 j d | d f ƒ d  S| j	 d ƒ } | j	 d ƒ } | j	 d ƒ }	 |  rí| d  k	 rGt | ƒ d k rGt
 j d d j | j ƒ  d ƒ f ƒ n  | d  k	 r�t | ƒ d k r�t
 j d d j | j ƒ  d ƒ f ƒ n  |	 d  k	 rêt |	 ƒ d k rêt
 j d d j t j d ƒ ƒ d d j |	 ƒ f ƒ qêqín  t | ƒ d k r2|  r2t
 j d d j t j d ƒ ƒ d ƒ q2n  xi | D]a \ } } } }
 |  r9|
 d k r}t
 j d | | | |
 f ƒ qšt
 j d | | | f ƒ q9q9Wt | ƒ d k rã|  rãt
 j d d j t j d ƒ ƒ d ƒ qãn  d  S(    NR"  R   Rh   s5   subscribing to all of class message is not supported.RÄ   RÅ   i<   s   Class longer than 60 characterss   Unsupported non-* instances   Unsupported non-* recipient.i    c         s   s   |  ] } i | d  6Vq d S(   t   nameN(    (   R  RC   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pys	   <genexpr>6  s    t   authorization_errors_fatalR;   RG   s    Error subscribing to streams:
%st   msgt   already_subscribedt
   subscribedt   unauthorizeds   
Already subscribed to: %ss   , s   
Successfully subscribed to: %ss   
s8  The following streams you have NOT been subscribed to,
because they have been configured in Zulip as invitation-only streams.
This was done at the request of users of these Zephyr classes, usually
because traffic to those streams is sent within the Zephyr world encrypted
via zcrypt (in Zulip, we achieve the same privacy goals through invitation-only streams).
If you wish to read these streams in Zulip, you need to contact the people who are
on these streams and already use Zulip.  They can subscribe you to them via the
"streams" page in the Zulip web interface:
s   

  %ssµ  You have some lines in ~/.zephyr.subs that could not be
synced to your Zulip subscriptions because they do not
use "*" as both the instance and recipient and not one of
the special cases (e.g. personals and mail zephyrs) that
Zulip has a mechanism for forwarding.  Zulip does not
allow subscribing to only some subjects on a Zulip
stream, so this tool has not created a corresponding
Zulip subscription to these lines in ~/.zephyr.subs:
R5   s     [%s,%s,%s] (%s)s     [%s,%s,%s]s‚   If you wish to be subscribed to any Zulip streams related
to these .zephyrs.subs lines, please do so via the Zulip
web interface.
(   Ro   R#  R#   R`   R0   RO   t   add_subscriptionsRw   R™   R¯   R   R]   Rr   R›   R‹   t   valuesR
  R  (   R"  t   zephyr_subscriptionst   skippedRb   Rc   RE   RÜ   t   alreadyt   newR+  t   reason(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   add_zulip_subscriptions  sl    		$	**	:	' !c         C   s
   |  d k S(   NR5   (    (   R&  (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   valid_stream_namek  s    c         C   s  t  ƒ  } t j j t j d d ƒ } t j j | ƒ sQ |  rM t j d ƒ n  g  Sx't | d ƒ j	 ƒ  D]} | j
 ƒ  } t | ƒ d k r‘ qg n  yŠ | j d ƒ \ } } } | j d t j ƒ } | j d t j ƒ } | j d t j ƒ } t | ƒ s|  rt j d | f ƒ n  wg n  Wn1 t k
 rN|  rg t j d	 | f ƒ qg qg n X| j | j
 ƒ  | j
 ƒ  | j
 ƒ  f ƒ qg W| S(
   NR¦   s   .zephyr.subss   Couldn't find ~/.zephyr.subs!Rg   i    t   ,s   %me%s5   Skipping subscription to unsupported class name: [%s]s(   Couldn't parse ~/.zephyr.subs line: [%s](   Ro   R~   RŠ   R‹   R«   Rñ   R   R]   Ri   R¬   R­   R0   R!   R  RH   R%   R4  R*   R`   (   R"  R.  t	   subs_fileR1   Rb   Rc   RE   (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR#  n  s2    	
,c          C   så   t  j d  k	 r t  j }  nY t  j r? t  j r6 d }  qt d }  n5 t j d d t  j f d t ƒ } | j	 }  | j
 ƒ  t j t ƒ } d } t j | ƒ } t j d | ƒ | j t j ƒ t j |  ƒ } | j | ƒ | j | ƒ | S(   Ns   /var/log/zulip/test-mirror-logs   /var/log/zulip/mirror-logt   prefixs   zulip-log.%s.t   deletes"   %(asctime)s <initial>: %(message)sRÍ   (   RH   t   log_pathRr   RI   RJ   t   tempfilet   NamedTemporaryFileR%   R™   R&  Rn   t   loggingt	   getLoggerR	   t	   Formattert   basicConfigt   setLevelt   DEBUGt   FileHandlert   setFormattert
   addHandler(   t   log_fileRx   R   t
   log_formatt	   formattert   file_handler(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   open_loggerŠ  s&    						
c         C   s„   | d  k r d } n d | d } t j | ƒ } x |  j D] } | j | ƒ q< Wt j ƒ  } x | j D] } | j | ƒ qi Wd  S(   Ns   %(message)ss   %(asctime)s [s   ] %(message)s(   Rr   R<  R>  t   handlersRC  R=  (   R   t   direction_nameRF  RG  t   handlert   root_logger(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   configure_logger£  s    	c       
   C   sí  t  j ƒ  }  |  j d d t d t  j d d ƒ|  j d d t  j ƒ|  j d d t d t  j d d ƒ|  j d d	 d
 d t  j ƒ|  j d d	 d d t  j ƒ|  j d d	 d d t  j ƒ|  j d d	 d d d d t  j ƒ|  j d d	 d d t  j d t d d ƒ|  j d d	 d d t  j d t d d ƒ|  j d d t d	 d d t  j d d ƒ|  j d d t d t  j d d ƒ|  j d d t d d ƒ|  j d d t d d ƒ|  j d d t d t  j ƒ|  j d d d  d t  j ƒ|  j d d t j	 d d t  j ƒ|  j d  d d! d t  j ƒ|  j d" d d  d t  j ƒ|  j d# d d  d t  j ƒ|  j d$ d d  d t  j ƒ|  j d% d t d d d t  j ƒ|  j d& d t d t  j d d ƒ|  j d' d t j
 j t j	 d( d) d* ƒ ƒ|  j ƒ  S(+   Ns   --forward-class-messagest   defaultt   helpt   actiont
   store_trues   --shards	   --noshards   --resend-logt   destRó   s   --enable-resend-logRõ   s
   --log-pathR9  s   --stream-file-pathRj   s   /home/zulip/public_streamss   --no-forward-personalsRÌ   t   store_falses   --forward-mail-zephyrsRÏ   s   --no-forward-from-zulipt   forward_from_zulips	   --verboses   --sync-subscriptionss   --ignore-expired-ticketss   --sites   --on-startup-commands   --usert   USERs   --root-paths0   /afs/athena.mit.edu/user/t/a/tabbott/for_friendss   --session-paths   --nagios-classs   --nagios-paths   --use-sessionss   --test-modes   --api-key-fileR¦   t   Privates   .zulip-api-key(   t   optparset   OptionParsert
   add_optionR™   t   SUPPRESS_HELPR�   RL   Rr   R~   R«   RŠ   R‹   t
   parse_args(   t   parser(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyR\  ±  s¢    	
	



				







	 c         C   s�   t  t j k s t  t j k r. t j d ƒ n  t  t j k r| t j r| y t	 j
 j ƒ  Wq| t k
 rx t j d ƒ q| Xn  t j d ƒ d  S(   Ni   R5   (   RÕ   R   R   R   R~   RÖ   R   RH   Rð   RW   RX   R�   RZ   R   R[   R’   Râ   (   R€   t   frame(    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   die_gracefully  s    t   __main__t   parents$   python-zephyr/build/lib.linux-%s-%s/i   i    i   t   apis   python-zephyrt   HUMBUG_API_KEYs   
st   Could not find API key file.
You need to either place your api key file at %s,
or specify the --api-key-file option.i   s*   nagios_path is required with nagios_class
s   @mit.eduR  t   api_keyR"  t   clientt   zephyr_mirrorRK   s8   Syncing your ~/.zephyr.subs to your Zulip Subscriptions!s   python.*zephyr_mirrors   %s.*--shard=%ss   %s.*--user=%st   pgreps   -URV  s   -fRµ   R¶   s*   Killing duplicate zephyr_mirror process %sR5   Rï   s   /var/tmp/%ss   zulip=>zephyrs   zephyr=>zulips   (%s)(    (€   R’   Rk   t   ImportErrort   jsonR(   R   Rº   RX  R~   R  R
  R€   R<  Rs   R:  R   R–   t   objectR    R   RL   R   R   RÕ   R'   R.   R4   R=   RR   RV   Ro   R_   Rf   R|   Rƒ   R”   R    R¥   R²   RÁ   Rš   RÑ   Rã   Ræ   Rì   Rî   R÷   Rú   Rû   Rü   Rþ   R  R  R   R%  R3  R4  R™   R#  RI  RN  R\  R_  R	   R¸   R¹   t   SIGINTRH   t   argsR   t   unamet   versiont   pyzephyr_lib_pathRŠ   R‹   RŒ   R«   R¯   Rr   Rd  Rñ   t   api_key_fileR]   R  Râ   Ri   Rm   R­   RÊ   RÉ   R%   RT   t   zulipt   ClientR�   RO   RŽ   t   sync_subscriptionsR›   RJ   t   pgrep_queryRq   R»   R¼   t   procR½   t   outt   _err_unusedt   mapR   R!   t   pidt   getpidt   getppidR   R‚   R[   RÌ   RU  RÏ   Rê   RÔ   R}   R   R   RW   t   logger_nameR¾   (    (    (    sS   /afs/athena.mit.edu/user/t/a/tabbott/for_friends/user_root/zephyr_mirror_backend.pyt   <module>   s  						 			#				'				b	
					3					y		
		V				S		$"			
	"	$*			
	