
Gh\c           @   sX  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 m	 Z	 d  d l
 Z
 d  d l j 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 d  d l m Z d  d l m Z d  d l m Z d  d	 l m Z d
 Z  e j! j" d  d Z# d   Z$ d e% f d     YZ& d S(   iN(   t   OptionParser(   t   UI_LISTt   setglobaluit   getglobalui(   t
   threadutilt   accountst   foldert   mbnames(   t   globals(   t   CustomConfigParser(   t
   stacktrace(   t
   Repository(   t   MSGCOPY_NAMESPACEt   MAX_ACCOUNTSt    i    c         C   s   t  j   } xf |  D]^ } t j | |  } t  j t d | j d d | } | j t  | j	   | j
 |  q W| j   d S(   sD   The target when in multithreading mode for running accounts threads.t   targett   names   Account sync %sN(   R   t   accountThreadsR   t   SyncableAccountt   InstanceLimitedThreadt   ACCOUNT_LIMITED_THREAD_NAMEt
   syncrunnert	   setDaemont   Truet   startt   addt   wait(   t   list_accountst   configt   threadst   accountnamet   accountt   thread(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt	   syncitall.   s    	
t   OfflineImapc           B   sn   e  Z d  Z d   Z d   Z d   Z d d d  Z d   Z d   Z d	   Z	 d
   Z
 d   Z d   Z RS(   s   The main class that encapsulates the high level use of OfflineImap.

    To invoke OfflineImap you would call it with::

      oi = OfflineImap()
      oi.run()
    c         C   sJ   d t  j t  j t f } y# d d  l } d | | j f } Wn n X| S(   Ns   imaplib2 v%s (%s), Python v%sis   %s, %s(   t   imaplibt   __version__t   DESCt   PYTHON_VERSIONt   sslt   OPENSSL_VERSION(   t   selft   infoR'   (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   get_env_infoK   s    c         C   s   |  j    \ } } | j r+ |  j |  n | j rD |  j |  nq | j r t j |  j |  j	 | j
  t j |  j j d d   t j   n# | j r |  j |  S|  j |  Sd S(   s+   Parse the commandline and invoke everythingt   generalR   N(   t   _OfflineImap__parse_cmd_optionst   diagnosticst   _OfflineImap__serverdiagnosticst   migrate_fmd5t   _OfflineImap__migratefmd5t   mbnames_pruneR   t   initR   t   uit   dryrunt   prunet   gett   writet   deletefoldert   _OfflineImap__deletefoldert   _OfflineImap__sync(   R)   t   optionst   args(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   runV   s    				c      
   C   s|	  t  d t j d d t j t j f  } | j d d d d d d t d	 d
 | j d d d d d d t d	 d | j d d d d d d t d	 d | j d d d d d d t d	 d | j d d d d d d	 d | j d d d d d d	 d | j d d d d d d d  d	 d  | j d! d d" d d# d	 d$ | j d% d d& d d d	 d' | j d( d d d d) d t d	 d* | j d+ d d, d d- d	 d. | j d/ d d0 d d1 d d2 d	 d3 | j d4 d d d d5 d t d	 d6 | j d7 d d d d8 d t d	 d9 | j d: d d; d	 d< | j d= d d> d d  d d? d	 d@ | j dA d d d dB d t d	 dC | j dD d d d dE d t d	 dF | j   \ } } t	 j
 |  | j rdG t j |  j   f GHt j dH  n  | j sdI } | t j k st j | r)t j j dJ  } n t j | } t j j | dK dL  | _ t j j | j  s~t j j dM  | _ n  | j } n t j j | j  } t   } t j j |  st j dN |  t j dO  n  | j |  | j rf| j st j dP  t | _ n  t j j | j  r?t j dQ | j  n t j | j  t j dR | j  n  | j rx~ | j D]p } | j  dS dO  \ }	 }
 dT |	 k r|	 j  dT dO  \ } }	 | j! dU dV  } n dW } | j" | |	 |
  qyWn  | j# dW dX dY  } | j$ d  k r | j$ } n  dZ | k rb| j  dZ  d[ } t j% d\ d] j t& j'     n  | j( rtdY } n  | j) r| j" dW d^ d_  } n  | j* dW d^ d`  y t& | j+   |  |  _, WnD t- k
 rt j da | d] j t& j'    f  t j dO  n Xt. |  j,  | j/ r8|  j, j0 | j/  n  | j1 rQ|  j, j2   n  |  j, j3   |  j, j4 |  j    | j5 rY|  j, j6 j7 t j8  | j5 j+   db k rdc | _5 n  dd | j5 j  de  k o| j s|  j, j9 df  t | _ n  | j5 j  de  dg g } xK | D]@ } | j:   } |  j, j; |  | j+   dh k rdi t< _= qqWn  | j> r| j? dj dk  r| j@ dj dk  n  x. tA jB |  D] } | j@ dl | dk  qWn  | jC rx1 tA jB |  D] } | j" dl | d8 d  qWn  | jD r| jD j  de  } dm | } dn } x` tA jB |  D]L } dl | } do | jE | dp  } | j" | dq |  | j" | dr |  q0Wn  | j/ r|  j, j/ t _F n  | jG dW ds dH  } | dH k rtH jI |  n  tJ jK tL | jG dW dt dO   xx | jM du  D]g } x^ tA jN | tO | g D]E } | j r>	tJ jK | dO  q	tJ jK | | jG do | dv dw   q	WqW| |  _P | | f S(x   Nt   versiont   descriptions   %s.

%ss   -Vt   actiont
   store_truet   destt   defaultt   helps   show full version infoss	   --dry-runR5   s   dry run modes   --infoR.   s7   output information on the configured email repositoriess   -1t   singlethreadings6   (the number one) disable all multithreading operationss   -Pt
   profiledirt   metavart   DIRs#   sets OfflineIMAP into profile mode.s   -aR   s   account1[,account2[,...]]s   list of accounts to syncs   -ct
   configfilet   FILEs%   specifies a configuration file to uses   -dt	   debugtypes   type1[,type2[,...]]sA   enables debugging for OfflineIMAP  (types: imap, maildir, thread)s   -lt   logfiles   log to FILEs   -st   syslogs   log to syslogs   -ft   folderss   folder1[,folder2[,...]]s   only sync the specified folderss   -kt   configoverridet   appends   [section:]option=values"   override configuration file options   -ot   runonces"   run only once (ignore autorefresh)s   -qt   quicks4   run only quick synchronizations (don't update flags)s   -ut	   interfaces_   specifies an alternative user interface (quiet, basic, syslog, ttyui, blinkenlights, machineui)s   --delete-folderR9   t
   FOLDERNAMEs*   Delete a folder (on the remote repository)s   --migrate-fmd5-using-nametransR0   s0   migrate FMD5 hashes from versions prior to 6.3.5s   --mbnames-pruneR2   s3   remove mbnames entries for accounts not in accountss   offlineimap v%s, %si    t   XDG_CONFIG_HOMEs	   ~/.configt   offlineimapR   s   ~/.offlineimaprcs/    *** Config file '%s' does not exist; aborting!i   s(   Profile mode: Forcing to singlethreaded.s,   Profile mode: Directory '%s' already exists!s<   Profile mode: Potentially large data will be created in '%s't   =t   :t   _R   R,   R4   t   ttyuit   .is2   Using old interface name, consider using one of %ss   , s   dry-runR   t   Falses)   UI '%s' does not exist, choose one of: %st   alls   imap,maildir,threadR    t   ,s&   Debug mode: Forcing to singlethreaded.t    u   imapi   t   DEFAULTt   autorefreshs   Account s   lambda f: f in %ss   []s   Repository t   remoterepositoryt   folderfiltert   folderincludest   socktimeoutt   maxsyncaccountsR   t   maxconnectionsi   (Q   R    RW   R$   t   __copyright__t   __license__t
   add_optionR]   t   Nonet
   parse_argst   globt   set_optionsR?   R+   t   syst   exitRJ   t   ost   environt   patht
   expandusert   joint   existsR	   t   loggingt   errort   readRG   RF   t   warnR   t   mkdirRP   t   splitt   replacet   sett
   getdefaultRT   t   warningR   t   keysR.   R5   t   set_if_not_existst   lowerR4   t   KeyErrorR   RM   t
   setlogfileRN   t   setup_sysloghandlert   init_bannerR*   RL   t   loggert   setLevelt   DEBUGt   _msgt   stript	   add_debugR#   t   DebugRR   t
   has_optiont   remove_optionR   t   getaccountlistRS   RO   R7   t   stderrt   getdefaultintt   sockett   setdefaulttimeoutR   t   initInstanceLimitR   t   getsectionlistt   FOLDER_NAMESPACER   R   (   R)   t   parserR<   R=   t   xdg_vart   xdg_homet   configfilenameR   t   optiont   keyt   valuet   secnamet   sectiont   ui_typeR5   t
   debugtypest   dtypet   foldernamesRd   Re   R   t   account_sectiont   remote_repo_sectionRf   t	   reposnamet	   namespace(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __parse_cmd_optionsg   sl   																			
			

			i   i   c      	   C   s  t  j   j } d   } g  } x t j   j   D] \ } } g  } x] t j |  D]L \ }	 }
 } } | j d |	 |
 | f  | rS | j d | j	    qS qS W| | k r | | d  } | j d  n  | j |  q1 W| |  } |  j
 j d d  x^ | D]V \ } } | d k r&d	 } n d
 } |  j
 j d | | d j | | d  f  qW|  j
 j d d t t j   j     d S(   s=    Signal handler: dump a stack trace for each existing thread.c         S   sS   t  j d    } x$ |  D] } | t |  c d 7<q Wt d   | j   D  S(   Nc           S   s   d S(   Ni    (    (    (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   <lambda>m  R`   i   c         s   s!   |  ] \ } } | | f Vq d  S(   N(    (   t   .0t   kt   v(    (    s*   /usr/share/offlineimap/offlineimap/init.pys	   <genexpr>p  s    (   t   collectionst   defaultdictt   tuplet   listt   items(   t   lt   dR   (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   unique_countl  s    s     File: "%s", line %d, in %ss       %si   s'     => Stopped to handle current signal. R    s   ** Thread List:
i   s   %s Thread is at:
%s
s   %s Threads are at:
%s
s   
s   Dumped a total of %d Threads.N(   t	   threadingt   currentThreadt   identRp   t   _current_framesR   t	   tracebackt   extract_stackRQ   R   R4   t   debugRv   t   lenR   (   R)   t   contextt   sighandler_deept   currentThreadIdR   t   stack_displayst   threadIdt   stackt   stack_displayt   filenamet   linenoR   t   linet   stackst   timest   msg(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __dumpstacksg  s.    	"		3c         C   s  g  } d  } |  j j d d  } | j r6 | j } n  g  | j d  D] } | j   ^ qF } t j |  j  } xQ | D]I } | | k r | j |  qw d d j |  } |  j	 j
 d |  qw Wt |  d k  r d } n  | d  k	 r|  j	 j d d	 | n  | S(
   NR,   R   R_   s   Valid accounts are: %ss   , s   The account '%s' does not existi   s   No accounts are defined!t   errormsg(   Rl   R   R7   R   R}   t   lstripR   RQ   Rv   R4   Ry   R   t	   terminate(   R)   R<   t   activeaccountsR   t   activeaccountnamest   xt   allaccountsR   (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   _get_activeaccounts  s$    	(	c            s    f d   } y>d   _  t j t j |  t j t j |  t j t j |  t j t j |  t j t j |  t j t j |  t j t j |    j	 |  } t
 j   j   j | j  | j r   j | | j  nG t j d t d d d |   j f  } t j | _ | j   t j   t
 j     j j   d SWnD t k
 rc  n1 t k
 r}   j j |    j j   d SXd S(	   s   Invoke the correct single/multithread syncing

        self.config is supposed to have been correctly initialized
        already.c            s@  |  t  j k r( t j j   j d  n|  t  j t  j f k ri t   j	 d  t j j   j d  n |  t  j
 t  j t  j f k rt   j	 d  t j j   j d  d   j j k r   j d  n    j d 7_   j d k r<t   j	 d  t j d  q<n, |  t  j k r<t j t j  t j   n  d  S(	   Ni   s   Terminating after this sync...i   sl   Preparing to shutdown after sync (this may take some time), press CTRL-C three times to shutdown immediatelyi   R    i   s   Signaled thrice. Aborting!(   t   signalt   SIGUSR1R   t   Accountt   set_abort_eventR   t   SIGUSR2t   SIGABRTR   R{   t   SIGTERMt   SIGINTt   SIGHUPR4   t	   debuglistt   _OfflineImap__dumpstackst   num_sigtermRp   Rq   t   SIGQUITR
   t   dumpR   Rr   t   abort(   t   sigt   frame(   R)   (    s*   /usr/share/offlineimap/offlineimap/init.pyt   sig_handler  s"    i    R   R   s   Sync RunnerR=   i   N(   R   R   R   R   R   R   R   R   R   R   R   R3   R   R4   R5   RF   t!   _OfflineImap__sync_singlethreadedRG   R   t   ExitNotifyThreadR!   t   STOP_MONITORt   exit_messageR   t   monitorR8   R   t
   SystemExitt	   ExceptionRy   (   R)   R<   R   R   t   tt   e(    (   R)   s*   /usr/share/offlineimap/offlineimap/init.pyt   __sync  s<    			


c   	      C   s  x| D]} t  j |  j |  } d | j   t j   _ | sN | j   q y d d l } Wn t	 k
 r} d d l
 } n X| j   } y | j d t   t    } Wn t k
 r n Xd d l m } | j   j d  } | j t j j | d | | j   f   q Wd S(   sm   Executed in singlethreaded mode only.

        :param accs: A list of accounts that should be synced
        s   Account sync %siNs   account.syncrunner()(   t   datetimes   %Y%m%d%H%M%Ss
   %s_%s.prof(   R   R   R   t   getnameR   R   R   R   t   cProfilet   ImportErrort   profilet   Profilet   runctxR   t   localsR   R   t   nowt   strftimet
   dump_statsRr   Rt   Rv   (	   R)   R   RG   R   R   R   t   profR   t   dt(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __sync_singlethreaded  s$    c         C   s]   |  j  j d t j t j f  x6 |  j |  D]% } t j |  j |  } | j	   q0 Wd  S(   Ns     imaplib2: %s (%s)(
   R4   R*   R#   R$   R%   R   R   R   R   t   serverdiagnostics(   R)   R<   R   R   (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __serverdiagnostics  s     c         C   s`   |  j  |  } t |  d k r5 |  j j d  d St j |  j | j    } | j | j  S(   Ni   s*   you must supply only one account with '-a'(	   R   R   R4   Ry   R   R   R   t   popR9   (   R)   R<   R   R   (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __deletefolder  s    c         C   s   x |  j  |  D]u } t j |  j |  } t | d  } | j   t j j k rX q n  | j	   } x | D] } | j
 | j  qk Wq Wd  S(   Nt   local(   R   R   R   R   R   t   getfoldertypeR   t   Maildirt   MaildirFoldert
   getfolderst   migratefmd5R5   (   R)   R<   R   R   t	   localrepoRO   t   f(    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   __migratefmd5  s    (   t   __name__t
   __module__t   __doc__R+   R>   R-   R   R   R;   R   R/   R:   R1   (    (    (    s*   /usr/share/offlineimap/offlineimap/init.pyR"   B   s   			 #		H			('   Rr   Rp   R   R   R   Rx   R   R   t   optparseR    RW   t   offlineimap.virtual_imaplib2t   virtual_imaplib2R#   t   offlineimap.uiR   R   R   R   R   R   R   R   Rn   t   offlineimap.CustomConfigR	   t   offlineimap.utilsR
   t   offlineimap.repositoryR   t   offlineimap.folder.IMAPR   R   R?   R}   R&   R!   t   objectR"   (    (    (    s*   /usr/share/offlineimap/offlineimap/init.pyt   <module>   s*   "	