a
   >_! 8                   @   s>  d 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dlmZ zddlZW n ey   dZY n0 g dZejdZG dd dZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd dejjZG dd deZG dd deZG dd deZ G dd deZ!G d d! d!eZ"G d"d# d#eZ#G d$d% d%Z$G d&d' d'e$Z%d?d)d*Z&d+d, Z'd-d. Z(d/d0 Z)d1d2 Z*d3d4 Z+G d5d6 d6e,Z-G d7d8 d8e-Z.G d9d: d:e-Z/G d;d< d<e-Z0G d=d> d>e-Z1dS )@zDRead/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.    N)GenericAlias)MailboxMaildirmboxMHBabylMMDFMessageMaildirMessagemboxMessage	MHMessageBabylMessageMMDFMessageErrorNoSuchMailboxErrorNotEmptyErrorExternalClashErrorFormatErrorasciic                   @   s  e Zd ZdZdCddZdd Zdd	 Zd
d Zdd Zdd Z	dDddZ
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ ZdEd0d1Zd2d3 ZdFd4d5Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@Z"dGdAdBZ#e$e%Z&dS )Hr   z*A group of messages in a particular place.NTc                 C   s    t jt j|| _|| _dS )zInitialize a Mailbox instance.N)ospathabspath
expanduser_path_factoryselfr   factorycreate r   /usr/lib/python3.9/mailbox.py__init__%   s    zMailbox.__init__c                 C   s   t ddS )$Add message and return assigned key.&Method must be implemented by subclassNNotImplementedErrorr   messager   r   r    add*   s    zMailbox.addc                 C   s   t ddS )=Remove the keyed message; raise KeyError if it doesn't exist.r#   Nr$   r   keyr   r   r    remove.   s    zMailbox.removec                 C   s   |  | d S N)r,   r*   r   r   r    __delitem__2   s    zMailbox.__delitem__c                 C   s&   z|  | W n ty    Y n0 dS z'If the keyed message exists, remove it.N)r,   KeyErrorr*   r   r   r    discard5   s    zMailbox.discardc                 C   s   t ddS )>Replace the keyed message; raise KeyError if it doesn't exist.r#   Nr$   r   r+   r'   r   r   r    __setitem__<   s    zMailbox.__setitem__c                 C   s(   z|  |W S  ty"   | Y S 0 dS )z9Return the keyed message, or default if it doesn't exist.N)__getitem__r0   )r   r+   defaultr   r   r    get@   s    zMailbox.getc                 C   sN   | j s| |S t| |}|  |W  d   S 1 s@0    Y  dS )z=Return the keyed message; raise KeyError if it doesn't exist.N)r   get_message
contextlibclosingget_file)r   r+   filer   r   r    r5   G   s    
zMailbox.__getitem__c                 C   s   t ddS )4Return a Message representation or raise a KeyError.r#   Nr$   r*   r   r   r    r8   O   s    zMailbox.get_messagec                 C   s   t | | S )zReturn a string representation or raise a KeyError.

        Uses email.message.Message to create a 7bit clean string
        representation of the message.emailmessage_from_bytes	get_bytesZ	as_stringr*   r   r   r    
get_stringS   s    zMailbox.get_stringc                 C   s   t ddS )z8Return a byte string representation or raise a KeyError.r#   Nr$   r*   r   r   r    rA   Z   s    zMailbox.get_bytesc                 C   s   t ddS )6Return a file-like representation or raise a KeyError.r#   Nr$   r*   r   r   r    r;   ^   s    zMailbox.get_filec                 C   s   t ddS )Return an iterator over keys.r#   Nr$   r   r   r   r    iterkeysb   s    zMailbox.iterkeysc                 C   s   t |  S )zReturn a list of keys.)listrF   rE   r   r   r    keysf   s    zMailbox.keysc              	   c   s<   |   D ].}z| | }W n ty.   Y qY n0 |V  qdS )z%Return an iterator over all messages.NrF   r0   r   r+   valuer   r   r    
itervaluesj   s    
zMailbox.itervaluesc                 C   s   |   S r-   )rL   rE   r   r   r    __iter__s   s    zMailbox.__iter__c                 C   s   t |  S )z,Return a list of messages. Memory intensive.)rG   rL   rE   r   r   r    valuesv   s    zMailbox.valuesc              	   c   s@   |   D ]2}z| | }W n ty.   Y qY n0 ||fV  qdS )z.Return an iterator over (key, message) tuples.NrI   rJ   r   r   r    	iteritemsz   s    
zMailbox.iteritemsc                 C   s   t |  S )z9Return a list of (key, message) tuples. Memory intensive.)rG   rO   rE   r   r   r    items   s    zMailbox.itemsc                 C   s   t ddS )9Return True if the keyed message exists, False otherwise.r#   Nr$   r*   r   r   r    __contains__   s    zMailbox.__contains__c                 C   s   t ddS )*Return a count of messages in the mailbox.r#   Nr$   rE   r   r   r    __len__   s    zMailbox.__len__c                 C   s   |   D ]}| | qdS )zDelete all messages.N)rH   r1   r*   r   r   r    clear   s    zMailbox.clearc                 C   s2   z| | }W n t y"   | Y S 0 | | |S )z3Delete the keyed message and return it, or default.)r0   r1   )r   r+   r6   resultr   r   r    pop   s    

zMailbox.popc                 C   s*   |   D ]}|| |f  S tddS )z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)rF   rW   r0   r*   r   r   r    popitem   s    zMailbox.popitemc              	   C   sr   t |dr| }nt |dr(| }n|}d}|D ],\}}z|| |< W q4 ty^   d}Y q40 q4|rntddS )z4Change the messages that correspond to certain keys.rO   rP   FTzNo message with key(s)N)hasattrrO   rP   r0   )r   argsourceZbad_keyr+   r'   r   r   r    update   s    



zMailbox.updatec                 C   s   t ddS )&Write any pending changes to the disk.r#   Nr$   rE   r   r   r    flush   s    zMailbox.flushc                 C   s   t ddS )Lock the mailbox.r#   Nr$   rE   r   r   r    lock   s    zMailbox.lockc                 C   s   t ddS )#Unlock the mailbox if it is locked.r#   Nr$   rE   r   r   r    unlock   s    zMailbox.unlockc                 C   s   t ddS )Flush and close the mailbox.r#   Nr$   rE   r   r   r    close   s    zMailbox.closec                 C   s,   z| dW S  ty&   tdY n0 d S )Nr   z?String input must be ASCII-only; use bytes or a Message instead)encodeUnicodeError
ValueErrorr&   r   r   r    _string_to_bytes   s    zMailbox._string_to_bytesFc           	      C   s  t |tjjrvt }tj||d}|| |	d |
 }|dt}|| | jrr|tsr|t nt |tttjfrt |tjrtdtd | }t |tr| |}|r|dd}|dt}|| | jr|ts|t nt|drt|dr2td	td |j}d
}| }|dr\|d
d d }n|drx|d
d d }|sq|r|drd|dd
  }|dt}|| |}q6| jr|r|ts|t ntdt| d
S )z%Dump message contents to target file.r      
8Use of StringIO input is deprecated, use BytesIO instead   s   
From s   
>From readbufferDUse of text mode files is deprecated, use a binary mode file insteadN   
      From s   >From    Invalid message type: %s)
isinstancer?   r'   r	   ioBytesIO	generatorBytesGeneratorflattenseekrl   replacelinesepwrite_append_newlineendswithstrbytesStringIOwarningswarnDeprecationWarninggetvaluerh   rY   rm   readline
startswith	TypeErrortype)	r   r'   targetZmangle_from_rm   gendataZlastlineliner   r   r    _dump_message   s\    






zMailbox._dump_message)NT)N)N)N)F)'__name__
__module____qualname____doc__r!   r(   r,   r.   r1   r4   r7   r5   r8   rB   rA   r;   rF   rH   rL   rM   rN   rO   rP   rR   rT   rU   rW   rX   r\   r^   r`   rb   rd   rh   r   r   classmethodr   __class_getitem__r   r   r   r    r   "   sD   

		
	

6r   c                   @   s   e Zd ZdZdZd6ddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZdS )7r   zA qmail-style Maildir mailbox.:NTc                 C   s   t | ||| tj| jdtj| jdtj| jdd| _tj| js|rt| jd | j	 D ]}t|d qln
t
| ji | _ddd| _d| _d| _d	S )
zInitialize a Maildir instance.tmpnewcur)r   r   r     r   )r   r   g?N)r   r!   r   r   joinr   _pathsexistsmkdirrN   r   _toc_toc_mtimes
_last_read_skewfactor)r   dirnamer   r   r   r   r   r    r!     s    
zMaildir.__init__c              
   C   s|  |   }z| || W n( ty@   |  t|j  Y n0 t| t|t	rz|
 }| j|  }|| jkrd}nd}d}tj|j| jd }tj| j||| }t|t	rt|jtj|j| f zJzt|j| W n& ttfy   t|j| Y n0 t|j W nP tyv } z6t|j |jtjkr`td| n W Y d}~n
d}~0 0 |S )r"    r   r   z$Name clash with existing message: %sN)_create_tmpr   BaseExceptionrd   r   r,   name_sync_closerv   r
   
get_subdircolonget_infor   basenamesplitr   r   utimegetatimeget_datelinkAttributeErrorPermissionErrorrenameOSErrorerrnoZEEXISTr   )r   r'   Ztmp_filesubdirsuffixuniqdester   r   r    r(   $  sF    


zMaildir.addc                 C   s    t t j| j| | dS r)   N)r   r,   r   r   r   _lookupr*   r   r   r    r,   N  s    zMaildir.removec              	   C   s*   z|  | W n ttfy$   Y n0 dS r/   )r,   r0   FileNotFoundErrorr*   r   r   r    r1   R  s    zMaildir.discardc                 C   s   |  |}| |}|  |}t|tr.|}n|}tj|}| j|v r`| j|| jd  }nd}| 	| tj
| j|}	tj
| j||| }
t|trt|	tj|	| f t|	|
 dS )r2   rr   r   N)r   r(   rv   r
   r   r   r   r   r   r1   r   r   r   r   r   r   )r   r+   r'   Zold_subpathZtemp_keyZtemp_subpathZdominant_subpathr   r   Ztmp_pathnew_pathr   r   r    r4   Z  s$    






zMaildir.__setitem__c                 C   s   |  |}ttj| j|d*}| jr4| |}nt|}W d   n1 sP0    Y  tj|\}}|	| | j
|v r||| j
d  |tjtj| j| |S )r=   rbNrr   )r   openr   r   r   r   r   r
   r   
set_subdirr   set_infoset_dategetmtime)r   r+   Zsubpathfmsgr   r   r   r   r    r8   u  s    
&

zMaildir.get_messagec                 C   sP   t tj| j| |d }| tdW  d   S 1 sB0    Y  dS )2Return a bytes representation or raise a KeyError.r   ri   N)	r   r   r   r   r   r   rl   r}   r~   r   r+   r   r   r   r    rA     s    zMaildir.get_bytesc                 C   s$   t tj| j| |d}t|S )rC   r   )r   r   r   r   r   r   
_ProxyFiler   r   r   r    r;     s    zMaildir.get_filec              	   c   sD   |    | jD ]0}z| | W n ty6   Y qY n0 |V  qdS rD   N)_refreshr   r   r0   r*   r   r   r    rF     s    

zMaildir.iterkeysc                 C   s   |    || jv S rQ   )r   r   r*   r   r   r    rR     s    zMaildir.__contains__c                 C   s   |    t| jS rS   )r   lenr   rE   r   r   r    rT     s    zMaildir.__len__c                 C   s   dS )"Write any pending changes to disk.Nr   rE   r   r   r    r^     s    zMaildir.flushc                 C   s   dS )r_   Nr   rE   r   r   r    r`     s    zMaildir.lockc                 C   s   dS )ra   Nr   rE   r   r   r    rb     s    zMaildir.unlockc                 C   s   dS rc   Nr   rE   r   r   r    rd     s    zMaildir.closec                 C   s\   g }t | jD ]F}t|dkr|d dkrt jt j| j|r||dd  q|S )Return a list of folder names.   r   .N)r   listdirr   r   r   isdirr   appendr   rV   entryr   r   r    list_folders  s    zMaildir.list_foldersc                 C   s    t tj| jd| | jddS )z/Return a Maildir instance for the named folder.r   Fr   r   )r   r   r   r   r   r   r   folderr   r   r    
get_folder  s    zMaildir.get_folderc                 C   s\   t j| jd| }t|| jd}t j|d}t j|sXt t |t j	t j
B d |S )z>Create a folder and return a Maildir instance representing it.r   r   Zmaildirfolder  )r   r   r   r   r   r   r   rd   r   O_CREATO_WRONLY)r   r   r   rV   Zmaildirfolder_pathr   r   r    
add_folder  s    zMaildir.add_folderc                 C   s  t j| jd| }t t j|dt t j|d D ](}t|dk sX|d dkr<td| q<t |D ]B}|dkrp|dkrp|dkrpt jt j||rptd||f qpt j|d	d
D ]F\}}}|D ]}t 	t j|| q|D ]}t 
t j|| qqt 
| dS )-Delete the named folder, which must be empty.r   r   r   r   r   zFolder contains message(s): %sr   z%Folder contains subdirectory '%s': %sF)topdownN)r   r   r   r   r   r   r   r   walkr,   rmdir)r   r   r   r   rootdirsfilesr   r   r    remove_folder  s&    zMaildir.remove_folderc                 C   sX   t   }ttj| jdD ]4}tj| jd|}|tj| dkrt| qdS )zDelete old files in "tmp".r   i@ N)timer   r   r   r   r   r   r,   )r   nowr   r   r   r   r    clean  s
    zMaildir.cleanr   c                 C   s   t   }t }d|v r$|dd}d|v r8|dd}dt|t|d d t tj|f }tj	
| jd|}zt| W nB ty   t jd7  _zt|W  Y S  ty   Y n0 Y n0 td	| d
S )z=Create a file in the tmp subdirectory and open and return it./z\057r   z\072z%s.M%sP%sQ%s.%sr   g    .Ar   z&Name clash prevented file creation: %sN)r   socketgethostnamer}   intr   getpidr   _countr   r   r   statr   _create_carefullyFileExistsErrorr   )r   r   hostnamer   r   r   r   r    r     s*    zMaildir._create_tmpc                 C   s   t   | j d| j kr^d}| jD ]2}tj| j| }|| j| krJd}|| j|< q"|s^dS i | _| jD ]^}| j| }t	|D ]D}tj
||}tj|rq|| jd }tj
||| j|< qqjt   | _dS )z!Update table of contents mapping.   FTNr   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   Zrefreshr   mtimer   r   pr   r   r   r    r     s&    


zMaildir._refreshc                 C   s|   z.t jt j| j| j| r,| j| W S W n ty@   Y n0 |   z| j| W S  tyv   td| dY n0 dS )z=Use TOC to return subpath for given key, or raise a KeyError.No message with key: %sN)r   r   r   r   r   r   r0   r   r*   r   r   r    r   &  s    zMaildir._lookupc                 C   sT   t | ds|  | _z| t| j W S  ty8   Y dS  tyL   Y qY q0 qdS )z0Return the next message in a one-time iteration._onetime_keysN)rY   rF   r   nextStopIterationr0   rE   r   r   r    r   4  s    

zMaildir.next)NT)r   r   r   r   r   r!   r(   r,   r1   r4   r8   rA   r;   rF   rR   rT   r^   r`   rb   rd   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r     s6   
*
	
$r   c                   @   s   e Zd ZdZd$ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd%d d!Zd"d# ZdS )&_singlefileMailboxzA single-file mailbox.NTc              
   C   s   t | ||| zt| jd}W np ty } zX|jtjkrZ|rNt| jd}q|t| jn"|jtjtj	fv rzt| jd}n W Y d}~n
d}~0 0 || _
d| _d| _d| _d| _d| _d| _dS )z!Initialize a single-file mailbox.rb+zwb+r   Nr   F)r   r!   r   r   r   r   ENOENTr   EACCESEROFS_filer   	_next_key_pending_pending_sync_locked_file_length)r   r   r   r   r   r   r   r   r    r!   D  s$    z_singlefileMailbox.__init__c                 C   s8   |    | || j| j< |  jd7  _d| _| jd S )r"   r   T)r   _append_messager   r  r
  r&   r   r   r    r(   [  s
    z_singlefileMailbox.addc                 C   s   |  | | j|= d| _dS )r)   TN)r   r   r	  r*   r   r   r    r,   e  s    
z_singlefileMailbox.removec                 C   s$   |  | | || j|< d| _dS )r2   TN)r   r  r   r	  r3   r   r   r    r4   k  s    
z_singlefileMailbox.__setitem__c                 c   s   |    | j E dH  dS r   )r   r   rH   rE   r   r   r    rF   q  s    z_singlefileMailbox.iterkeysc                 C   s   |    || jv S r   )r   r   r*   r   r   r    rR   v  s    z_singlefileMailbox.__contains__c                 C   s   |    t| jS r   )r   r   r   rE   r   r   r    rT   {  s    z_singlefileMailbox.__len__c                 C   s   | j st| j d| _ dS )r_   TN)r  
_lock_filer  rE   r   r   r    r`     s    
z_singlefileMailbox.lockc                 C   s   | j rt| j d| _ dS ra   FN)r  _unlock_filer  rE   r   r   r    rb     s    
z_singlefileMailbox.unlockc           
      C   s  | j s | jrt| j d| _dS | jdus.J | jdd | j }|| jkrbtd| j|f t	| j
}zi }| | t| j D ]x}| j| \}}| j| | | | }| jtd|| j  }|sq|| q|| f||< | | q| | _W n"   |  t|j  Y n0 t| | j  t| j
j}	t|j|	 zt|j| j
 W n0 ty   t| j
 t|j| j
 Y n0 t| j
d| _|| _d| _ d| _| jrt| jdd dS )	r   FNr   r   z4Size of mailbox file changed (expected %i, found %i)   r  )dotlock) r	  r
  _sync_flushr  r   r|   tellr  r   _create_temporaryr   _pre_mailbox_hooksortedrH   _pre_message_hookrl   minr   _post_message_hookrd   r   r,   r   r   r   st_modechmodr   r   r   r  r  )
r   Zcur_lenZnew_fileZnew_tocr+   startstopZ	new_startrm   moder   r   r    r^     sb    







z_singlefileMailbox.flushc                 C   s   dS ),Called before writing the mailbox to file f.Nr   r   r   r   r   r    r    s    z$_singlefileMailbox._pre_mailbox_hookc                 C   s   dS )-Called before writing each message to file f.Nr   r!  r   r   r    r    s    z$_singlefileMailbox._pre_message_hookc                 C   s   dS ,Called after writing each message to file f.Nr   r!  r   r   r    r    s    z%_singlefileMailbox._post_message_hookc                 C   sh   z6|    W z| jr|   W | j  qd| j  0 n,z| jrH|   W | j  n| j  0 0 dS r   )r^   r  rb   r  rd   rE   r   r   r    rd     s    


z_singlefileMailbox.closec                 C   sL   | j du r|   |durHz| j | W S  tyF   td| dY n0 dS )z'Return (start, stop) or raise KeyError.Nr   )r   _generate_tocr0   r*   r   r   r    r     s    
z_singlefileMailbox._lookupc                 C   s   | j dd | j  }t| jdkr8| js8| | j  z&| | j  | |}| 	| j  W n  t
y~   | j |  Y n0 | j   | j  | _|S )z;Append message to mailbox and return (start, stop) offsets.r   r   )r  r|   r  r   r   r	  r  r  _install_messager  r   truncater^   r  )r   r'   beforeZoffsetsr   r   r    r    s    


z"_singlefileMailbox._append_message)NT)N)r   r   r   r   r!   r(   r,   r4   rF   rR   rT   r`   rb   r^   r  r  r  rd   r   r  r   r   r   r    r  A  s"   

@

r  c                   @   sB   e Zd ZdZdZdd ZdddZddd	Zdd
dZdd Z	dS )	_mboxMMDFzAn mbox or MMDF mailbox.Tc                 C   sp   |  |\}}| j| | j td}| j|| j  }| |td}|	|dd 
d |S )r=       ri   rt   Nr   )r   r  r|   r   r}   r~   rl   r  _message_factoryset_fromdecode)r   r+   r  r  	from_linestringr   r   r   r    r8   	  s    z_mboxMMDF.get_messageFc                 C   s   t | ||j|dS )3Return a string representation or raise a KeyError.)unixfromr>   )r   r+   from_r   r   r    rB     s
    
z_mboxMMDF.get_stringc                 C   sJ   |  |\}}| j| |s(| j  | j|| j  }|tdS )r0  ri   )r   r  r|   r   rl   r  r}   r~   )r   r+   r2  r  r  r/  r   r   r    rA     s    
z_mboxMMDF.get_bytesc                 C   s<   |  |\}}| j| |s(| j  t| j| j |S )rC   )r   r  r|   r   _PartialFiler  )r   r+   r2  r  r  r   r   r    r;   !  s
    
z_mboxMMDF.get_filec                 C   s  d}t |tr| |}t |trf|drf|d}|dkr\|d| }||d d }q|}d}nJt |tr| d}d| }n(t |t	j
jr| }|dur|d}|du rdtt   }| j }| j|t  | || j| j | j }||fS )	z1Format a message and blindly write to self._file.Nrs   ri   rr   r   r*  r   s   From MAILER-DAEMON )rv   r   rh   r   r   find_mboxMMDFMessageget_fromre   r?   r'   r	   get_unixfromr   asctimegmtimer  r  r   r~   r   _mangle_from_)r   r'   r.  newlineZauthorr  r  r   r   r    r&  )  s0    







z_mboxMMDF._install_messageN)F)F)F)
r   r   r   r   r:  r8   rB   rA   r;   r&  r   r   r   r    r)    s   


	
r)  c                   @   s2   e Zd ZdZdZdZd
ddZdd Zdd	 ZdS )r   zA classic mbox mailbox.TNc                 C   s   t | _t| ||| dS )zInitialize an mbox mailbox.N)r   r+  r)  r!   r   r   r   r    r!   O  s    zmbox.__init__c                 C   s   | t dS r#  r   r~   r!  r   r   r    r  T  s    zmbox._post_message_hookc                 C   s   g g  }}d}| j d | j  }| j  }|drzt|t|k rj|r`||tt  n
|| || d}q|s|r||tt  q|| qq|tkrd}qd}qtt	t
||| _t| j| _| j  | _dS )0Generate key-to-(start, stop) table of contents.Fr   rs   TN)r  r|   r  r   r   r   r   r~   dict	enumeratezipr   r  r  )r   startsstopsZlast_was_emptyline_posr   r   r   r    r%  X  s.    






zmbox._generate_toc)NT)	r   r   r   r   r:  r   r!   r  r%  r   r   r   r    r   F  s   
r   c                   @   s2   e Zd ZdZdddZdd Zdd	 Zd
d ZdS )r   zAn MMDF mailbox.NTc                 C   s   t | _t| ||| dS )zInitialize an MMDF mailbox.N)r   r+  r)  r!   r   r   r   r    r!   }  s    zMMDF.__init__c                 C   s   | dt  dS )r"     Nr<  r!  r   r   r    r    s    zMMDF._pre_message_hookc                 C   s   | td t  dS )r$  rD  Nr<  r!  r   r   r    r    s    zMMDF._post_message_hookc                 C   s   g g  }}| j d d}|}| j  }| j  }|dt r|| |}| j  }| j  }|dt kr||tt  qqJ|sJ|| qqJq|sqqtt	t
||| _t| j| _| j dd | j  | _dS )r=  r   rD  r   N)r  r|   r   r  r   r~   r   r   r>  r?  r@  r   r  r  )r   rA  rB  next_posrC  r   r   r   r    r%    s.    






zMMDF._generate_toc)NT)r   r   r   r   r!   r  r  r%  r   r   r   r    r   z  s
   
r   c                   @   s   e Zd ZdZd0ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ ZdS )1r   zAn MH mailbox.NTc                 C   st   t | ||| tj| jsj|r`t| jd tttj	| jdtj
tjB tjB d n
t| jd| _dS )zInitialize an MH instance.r   .mh_sequencesi  FN)r   r!   r   r   r   r   r   rd   r   r   r   O_EXCLr   r   r  r   r   r   r    r!     s    
zMH.__init__c                 C   s   |   }t|dkrd}nt|d }tj| jt|}t|}d}z| j	rVt
| zrz| || W n8 ty   | j	rt| t| d}t|  Y n0 t|tr| || W | j	rt| n| j	rt| 0 W |st| n|st| 0 |S )r"   r   r   FT)rH   r   maxr   r   r   r   r   r   r  r  r   r   r  r   r,   rv   r   _dump_sequences)r   r'   rH   Znew_keyr   r   closedr   r   r    r(     s>    




zMH.addc              
   C   sz   t j| jt|}zt|d}W n@ tyb } z(|jtjkrLt	d| n W Y d}~nd}~0 0 |
  t | dS )r)   r  r   N)r   r   r   r   r   r   r   r   r  r0   rd   r,   )r   r+   r   r   r   r   r   r    r,     s    z	MH.removec              
   C   s   t j| jt|}zt|d}W n@ tyb } z(|jtjkrLt	d| n W Y d}~n
d}~0 0 zz| j
rtt| zNt t |t jt jB  | || t|tr| || W | j
rt| n| j
rt| 0 W t| n
t| 0 dS )r2   r  r   N)r   r   r   r   r   r   r   r   r  r0   r  r  rd   r   O_TRUNCr   rv   r   rI  r  r   )r   r+   r'   r   r   r   r   r   r    r4     s(    

zMH.__setitem__c              
   C   s  z@| j r$ttj| jt|d}nttj| jt|d}W n@ ty } z(|jtj	krjt
d| n W Y d}~n
d}~0 0 |J | j rt| zt|}W | j rt| n| j rt| 0 W d   n1 s0    Y  |   D ]\}}||v r|| q|S )r=   r  r   r   N)r  r   r   r   r   r   r   r   r   r  r0   r  r   r  get_sequencesrP   add_sequence)r   r+   r   r   r   r   key_listr   r   r    r8     s*    

(zMH.get_messagec              
   C   s   z@| j r$ttj| jt|d}nttj| jt|d}W n@ ty } z(|jtj	krjt
d| n W Y d}~n
d}~0 0 |` | j rt| z0| tdW | j rt| W  d   S n| j rt| 0 W d   n1 s0    Y  dS )r   r  r   r   Nri   )r  r   r   r   r   r   r   r   r   r  r0   r  rl   r}   r~   r  r   r+   r   r   r   r   r    rA     s(     zMH.get_bytesc              
   C   sh   zt tj| jt|d}W n@ ty^ } z(|jtjkrHt	d| n W Y d}~n
d}~0 0 t
|S )rC   r   r   N)r   r   r   r   r   r   r   r   r  r0   r   rO  r   r   r    r;   ,  s    zMH.get_filec                 C   s   t tdd t| jD S )rD   c                 s   s   | ]}|  rt|V  qd S r-   )isdigitr   ).0r   r   r   r    	<genexpr>9  s   zMH.iterkeys.<locals>.<genexpr>)iterr  r   r   r   rE   r   r   r    rF   7  s    zMH.iterkeysc                 C   s   t jt j| jt|S r   )r   r   r   r   r   r   r*   r   r   r    rR   <  s    zMH.__contains__c                 C   s   t t|  S r   )r   rG   rF   rE   r   r   r    rT   @  s    z
MH.__len__c                 C   s2   | j s.ttj| jdd| _t| j d| _ dS )r_   rF  r  TN)r  r   r   r   r   r   r  r  rE   r   r   r    r`   D  s    
zMH.lockc                 C   s(   | j r$t| j t| j | `d| _ dS r  )r  r  r  r   rE   r   r   r    rb   K  s
    

z	MH.unlockc                 C   s   dS )r]   Nr   rE   r   r   r    r^   S  s    zMH.flushc                 C   s   | j r|   dS r   )r  rb   rE   r   r   r    rd   W  s    zMH.closec                 C   s<   g }t | jD ]&}t jt j| j|r|| q|S )r   )r   r   r   r   r   r   r   r   r   r   r    r   \  s
    zMH.list_foldersc                 C   s   t tj| j|| jddS )z+Return an MH instance for the named folder.Fr   r   r   r   r   r   r   r   r   r   r    r   d  s    zMH.get_folderc                 C   s   t tj| j|| jdS )z:Create a folder and return an MH instance representing it.r   rT  r   r   r   r    r   i  s    zMH.add_folderc                 C   s`   t j| j|}t |}|dgkr:t t j|d n|g krDntd| j t | dS )r   rF  zFolder not empty: %sN)r   r   r   r   r   r,   r   r   )r   r   r   entriesr   r   r    r   n  s    

zMH.remove_folderc           
   
      s  i }t tj| jdddd}t|   |D ]}z|d\}}t }| D ]H}| rn|	t
| qRdd |dD \}}	|t||	d	  qR fd
dt|D ||< t|| dkr||= W q0 ty   td|  Y q00 q0W d   n1 s
0    Y  |S )z=Return a name-to-key-list dictionary to define each sequence.rF  rASCIIencodingr   c                 s   s   | ]}t |V  qd S r-   )r   )rQ  xr   r   r    rR    r*  z#MH.get_sequences.<locals>.<genexpr>-r   c                    s   g | ]}| v r|qS r   r   )rQ  r+   Zall_keysr   r    
<listcomp>  s   z$MH.get_sequences.<locals>.<listcomp>r   z"Invalid sequence specification: %sN)r   r   r   r   r   setrH   r   rP  r(   r   r\   ranger  r   rg   r   rstrip)
r   resultsr   r   r   contentsrH   specr  r  r   r\  r    rL  z  s(    
.zMH.get_sequencesc                 C   s
  t tj| jdddd}ztt |jtjtjB  |	 D ]\}}t
|dkrVq@||d  d}d}tt|D ]R}|d	 |kr|sd
}|d n*|rd}|d||f  n|d|  |}qx|r|t|d  q@|d q@W t| n
t| 0 dS )z:Set sequences using the given name-to-key-list dictionary.rF  zr+rW  rX  r   r   NFr   Tr[  z%s %sz %s
)r   r   r   r   r   rd   r   r   rK  rP   r   r   r  r^  r   r   )r   	sequencesr   r   rH   prevZ
completingr+   r   r   r    set_sequences  s.    zMH.set_sequencesc           	      C   s<  |   }d}g }|  D ]}|d |kr|||d f z4ttj| jt|tj| jt|d  W nF t	t
fy   ttj| jt|tj| jt|d  Y n0 ttj| jt| |d7 }q|d | _t|dkrdS | D ]0\}}|D ]"\}}||v r||||< qq| | dS )z?Re-name messages to eliminate numbering gaps. Invalidates keys.r   r   N)rL  rF   r   r   r   r   r   r   r   r   r   r   unlinkr  r   rP   indexrg  )	r   re  rf  Zchangesr+   r   rN  oldr   r   r   r    pack  s0    



zMH.packc                 C   st   |  }|   }| D ]0\}}||v r4|| q||v r|||= q|D ]}||vrN|g||< qN| | dS )z;Inspect a new MHMessage and update sequences appropriately.N)rL  rP   r   ri  rg  )r   r'   r+   Zpending_sequencesZall_sequencesr   rN  sequencer   r   r    rI    s    zMH._dump_sequences)NT)r   r   r   r   r!   r(   r,   r4   r8   rA   r;   rF   rR   rT   r`   rb   r^   rd   r   r   r   r   rL  rg  rk  rI  r   r   r   r    r     s.   
"r   c                   @   s   e Zd ZdZeh dZdddZdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS ) r   zAn Rmail-style Babyl mailbox.>   unseenZedited	forwardedZfileddeletedansweredresentNTc                 C   s   t | ||| i | _dS )zInitialize a Babyl mailbox.N)r  r!   _labelsr   r   r   r    r!     s    zBabyl.__init__c                 C   s(   t | |}t|tr$| | j|< |S )r"   )r  r(   rv   r   
get_labelsrr  )r   r'   r+   r   r   r    r(     s    
z	Babyl.addc                 C   s"   t | | || jv r| j|= dS r   )r  r,   rr  r*   r   r   r    r,     s    
zBabyl.removec                 C   s*   t | || t|tr&| | j|< dS )r2   N)r  r4   rv   r   rs  rr  r3   r   r   r    r4     s    
zBabyl.__setitem__c           
      C   s   |  |\}}| j| | j  t }| j }|dt ks\|sHq\||td q,t }| j }|tks|s|q||td qd|| j	  }|dksJ | j
|}|td}t| | }	|	|  || jv r|	| j|  |	S )r=      *** EOOH ***ri   r   )r   r  r|   r   rw   rx   r~   r   r}   r  rl   r   r   set_visiblerr  
set_labels)
r   r+   r  r  original_headersr   Zvisible_headersnbodyr   r   r   r    r8     s,    



zBabyl.get_messagec           	      C   s   |  |\}}| j| | j  t }| j }|dt ks\|sHq\||td q,| j }|tksv|s\qvq\|	 }|| j
  }|dksJ | j|}|td}|| S )r0  rt  ri   r   )r   r  r|   r   rw   rx   r~   r   r}   r   r  rl   )	r   r+   r  r  rw  r   Zheadersrx  r   r   r   r    rA     s"    


zBabyl.get_bytesc                 C   s   t | |dtS )rC   ri   )rw   rx   rA   r}   r~   r*   r   r   r    r;   (  s    zBabyl.get_filec                 C   s<   |    t }| j D ]}|| q|| j t|S )z4Return a list of user-defined labels in the mailbox.)r   r^  rr  rN   r\   difference_update_special_labelsrG   )r   labelsZ
label_listr   r   r    rs  ,  s    zBabyl.get_labelsc                 C   s:  g g  }}| j d d}g }|}| j  }| j  }|dt krt|t|k rd||tt  || dd | j  dd dD }|| q|dks|dt krt|t|k r||tt  q|s||tt  qqtt	t
||| _tt	|| _t| j| _| j dd	 | j  | _dS )
r=  r   s   c                 S   s   g | ]}|  r|  qS r   )striprQ  labelr   r   r    r]  C  s   z'Babyl._generate_toc.<locals>.<listcomp>r   N   ,   r   )r  r|   r   r  r~   r   r   r   r>  r?  r@  r   rr  r  r  )r   rA  rB  rE  Zlabel_listsrC  r   r|  r   r   r    r%  5  s4    



zBabyl._generate_tocc                 C   sV   dt  }|dt  7 }|  }dd |D }|dd| t  7 }|d7 }|| dS )	r   s   BABYL OPTIONS:s
   Version: 5c                 s   s   | ]}|  V  qd S r-   )re   r~  r   r   r    rR  X  r*  z*Babyl._pre_mailbox_hook.<locals>.<genexpr>s   Labels:r  r  N)r~   rs  r   r   )r   r   Zbabylr|  r   r   r    r  S  s    zBabyl._pre_mailbox_hookc                 C   s   | dt  dS )r"     Nr<  r!  r   r   r    r  ]  s    zBabyl._pre_message_hookc                 C   s   | td  dS )r$  r  Nr<  r!  r   r   r    r  a  s    zBabyl._post_message_hookc                 C   sx  | j  }t|trg }g }| D ]$}|| jv r>|| q$|| q$| j d |D ]}| j d|   qZ| j d |D ]}| j d|  d  q| j t	 n| j dt	  t|t
jjrt }t
j|dd}|| |d | }| j |d	t	 |d	ks,|sq,q| j d
t	  t|trt }	t
j|	dd}
|
|  |	 }| j |d	t	 |d	ks|snqqnn>|d | }| j |d	t	 |d	ks|sqq|d}|sqf| j |d	t	 qnTt|tttjfrt|tjrJtdtd | }t|tr`| |}|dd }|d dkr| j |d| d	t	 | j d
t	  | j |d| d	t	 | j ||d d	t	 n(| j d
t	 t	  | j |d	t	 nXt |drVt |dr:tdtd |j!}| }d}| }|"drl|dd d	 }n|"dr|dd d	 }| j |d	t	 |d	ks|sF|rd}| j d
t	  || nqڐqF| }|sqf|"dr
|dd t	 }n:|"dr(|dd t	 }n|"d	rD|dd t	 }| j | qnt#dt$| | j  }||fS )z0Write message contents and return (start, stop).   1s   , s   ,,    r  s   1,,Fr   ri   rt  r  rj   rk   s   

r   rr   Nr   rm   rn   Tro   rp   rq   ru   )%r  r  rv   r   rs  r{  r   r   re   r~   r?   r'   r	   rw   rx   ry   rz   r{   r|   r   r}   get_visiblerl   r   r   r   r   r   r   r   rh   r4  rY   rm   r   r   r   )r   r'   r  Zspecial_labelsr|  r  Zorig_bufferZorig_generatorr   Z
vis_bufferZvis_generatorrm   Z
body_startZoriginal_posZ
first_passr  r   r   r    r&  e  s    









zBabyl._install_message)NT)r   r   r   r   	frozensetr{  r!   r(   r,   r4   r8   rA   r;   rs  r%  r  r  r  r&  r   r   r   r    r     s   
	
r   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
r	   z0Message with mailbox-format-specific properties.Nc                 C   s   t |tjjr4| t| t |tr||  nt |trP| t	| n~t |t
rl| t| nbt |tjr| t| nDt|dr| t| n(|du rtjj|  ntdt| dS )zInitialize a Message instance.rl   Nru   )rv   r?   r'   r	   _become_messagecopydeepcopy_explain_tor   r@   r   Zmessage_from_stringrw   TextIOWrapperZmessage_from_filerY   Zmessage_from_binary_filer!   r   r   r&   r   r   r    r!     s    



zMessage.__init__c                 C   s4   t |dg }|jD ]}||vr|j| | j|< qdS )z0Assume the non-format-specific state of message._type_specific_attributesN)getattr__dict__)r   r'   Ztype_specificr   r   r   r    r    s    
zMessage._become_messagec                 C   s   t |trdS tddS )z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)rv   r	   r   r&   r   r   r    r    s    
zMessage._explain_to)N)r   r   r   r   r!   r  r  r   r   r   r    r	     s   
r	   c                   @   sz   e Zd ZdZg dZdddZdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )r
   z)Message with Maildir-specific properties.)_subdir_info_dateNc                 C   s&   d| _ d| _t | _t| | dS )z%Initialize a MaildirMessage instance.r   r   N)r  r  r   r  r	   r!   r&   r   r   r    r!     s    
zMaildirMessage.__init__c                 C   s   | j S )zReturn 'new' or 'cur'.)r  rE   r   r   r    r     s    zMaildirMessage.get_subdirc                 C   s(   |dks|dkr|| _ ntd| dS )zSet subdir to 'new' or 'cur'.r   r   z!subdir must be 'new' or 'cur': %sN)r  rg   )r   r   r   r   r    r     s    zMaildirMessage.set_subdirc                 C   s"   | j dr| j dd S dS dS )*Return as a string the flags that are set.2,r   Nr   )r  r   rE   r   r   r    	get_flags  s    zMaildirMessage.get_flagsc                 C   s   dd t| | _dS ))Set the given flags and unset all others.r  r   N)r   r  r  )r   flagsr   r   r    	set_flags  s    zMaildirMessage.set_flagsc                 C   s$   |  dt|  t|B  dS z.Set the given flag(s) without changing others.r   Nr  r   r^  r  r   flagr   r   r    add_flag  s    zMaildirMessage.add_flagc                 C   s,   |   r(| dt|   t|  dS )7Unset the given string flag(s) without changing others.r   N)r  r  r   r^  r  r   r   r    remove_flag  s    zMaildirMessage.remove_flagc                 C   s   | j S )z<Return delivery date of message, in seconds since the epoch.)r  rE   r   r   r    r   !  s    zMaildirMessage.get_datec                 C   s4   zt || _W n  ty.   td| dY n0 dS )z9Set delivery date of message, in seconds since the epoch.zcan't convert to float: %sN)floatr  rg   r   )r   dater   r   r    r   %  s    zMaildirMessage.set_datec                 C   s   | j S )z%Get the message's "info" as a string.)r  rE   r   r   r    r   ,  s    zMaildirMessage.get_infoc                 C   s&   t |tr|| _ntdt| dS )z Set the message's "info" string.zinfo must be a string: %sN)rv   r   r  r   r   )r   infor   r   r    r   0  s    
zMaildirMessage.set_infoc                 C   s  t |tr8||   ||   ||   nht |trt	|  }d|v r`|
d |  dkrv|
d d|v r|
d d|v r|
d d|v r|
d |d	t|   nt |trt	|  }d|vr|d
 d|v r|d d|v r|d nt |trt	|  }d|vrD|d
 d|v rX|d d|v rl|d d|v r|d nt |trntdt| dS )z;Copy Maildir-specific state to message insofar as possible.SRr   OTDFAMAILER-DAEMONrm  repliedflaggedro  rp  Prn  $Cannot convert to specified type: %sN)rv   r
   r  r  r   r   r   r   r5  r^  r  r,  r   r9  r   rM  r   	add_labelr	   r   r   )r   r'   r  r   r   r    r  7  sP    

















zMaildirMessage._explain_to)N)r   r   r   r   r  r!   r   r   r  r  r  r  r   r   r   r   r  r   r   r   r    r
     s   
r
   c                   @   sZ   e Zd ZdZdgZdddZdd Zddd	Zd
d Zdd Z	dd Z
dd Zdd ZdS )r5  z/Message with mbox- or MMDF-specific properties._fromNc                 C   sV   |  dd t|tjjrF| }|durF|drF|  |dd  t| | dS )z'Initialize an mboxMMDFMessage instance.r  TNzFrom rt   )r,  rv   r?   r'   r	   r7  r   r!   )r   r'   r1  r   r   r    r!   h  s    z_mboxMMDFMessage.__init__c                 C   s   | j S )z Return contents of "From " line.)r  rE   r   r   r    r6  q  s    z_mboxMMDFMessage.get_fromc                 C   s4   |dur*|du rt  }|dt | 7 }|| _dS )z>Set "From " line, formatting and appending time_ if specified.NT )r   r9  r8  r  )r   r2  Ztime_r   r   r    r,  u  s
    z_mboxMMDFMessage.set_fromc                 C   s   |  dd|  dd S )r  Statusr   X-Status)r7   rE   r   r   r    r  }  s    z_mboxMMDFMessage.get_flagsc                 C   s   t |}d\}}dD ]}||v r||7 }|| qdD ]}||v r8||7 }|| q8|dt|7 }z| d| W n ty   | d| Y n0 z| d| W n ty   | d| Y n0 dS )r  )r   r   )r  r  )r  r  r  r   r  r  N)r^  r,   r   r  replace_headerr0   Z
add_header)r   r  Zstatus_flagsZxstatus_flagsr  r   r   r    r    s&    z_mboxMMDFMessage.set_flagsc                 C   s$   |  dt|  t|B  dS r  r  r  r   r   r    r    s    z_mboxMMDFMessage.add_flagc                 C   s4   d| v sd| v r0|  dt|  t|  dS )r  r  r  r   Nr  r  r   r   r    r    s    z_mboxMMDFMessage.remove_flagc              	   C   s  t |trt|  }d|v r(|d d|v r:|d d|v rL|d d|v r^|d d|v rp|d |d	= |d
= d|   dd }z|	t
t|d W n ttfy   Y n0 n
t |tr||   ||   nt |trXt|  }d|vr"|d d|v r6|d d|v rJ|d |d	= |d
= nt |trt|  }d|vr|d d|v r|d d|v r|d |d	= |d
= nt |trntdt| dS )zACopy mbox- or MMDF-specific state to message insofar as possible.r  r   r  r  r  r  r  r  statuszx-statusr  Nz%a %b %d %H:%M:%S %Yrm  r  r  ro  rp  r  )rv   r
   r^  r  r   r  r   r6  r   r   calendarZtimegmr   strptimerg   OverflowErrorr5  r  r,  r   rM  r   r  r	   r   r   )r   r'   r  Z
maybe_dater   r   r    r    sb    



















z_mboxMMDFMessage._explain_to)N)N)r   r   r   r   r  r!   r6  r,  r  r  r  r  r  r   r   r   r    r5  c  s   
	
r5  c                   @   s   e Zd ZdZdS )r   z&Message with mbox-specific properties.Nr   r   r   r   r   r   r   r    r     s   r   c                   @   sH   e Zd ZdZdgZdddZdd Zdd	 Zd
d Zdd Z	dd Z
dS )r   z$Message with MH-specific properties.
_sequencesNc                 C   s   g | _ t| | dS )z!Initialize an MHMessage instance.N)r  r	   r!   r&   r   r   r    r!     s    zMHMessage.__init__c                 C   s   | j dd S )z4Return a list of sequences that include the message.N)r  rE   r   r   r    rL    s    zMHMessage.get_sequencesc                 C   s   t || _dS )z3Set the list of sequences that include the message.N)rG   r  )r   re  r   r   r    rg    s    zMHMessage.set_sequencesc                 C   s6   t |tr"|| jvr2| j| ntdt| dS )z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rv   r   r  r   r   r   r   rl  r   r   r    rM    s    

zMHMessage.add_sequencec                 C   s(   z| j | W n ty"   Y n0 dS )zARemove sequence from the list of sequences including the message.N)r  r,   rg   r  r   r   r    remove_sequence  s    zMHMessage.remove_sequencec                 C   sF  t |trdt|  }d|v r*|d n|d |d d|v rP|d d|v rb|d nt |trt|  }d|vr|d n
|d	 d|v r|d d|v r|d
 nt |tr|  D ]}|| qn`t |t	r$t|  }d|v r|
d d|v rB|
d nt |tr2ntdt| dS )z6Copy MH-specific state to message insofar as possible.rm  r   r  r  r  r  r  ROr  r  rp  r  N)rv   r
   r^  rL  r   r  r5  r   rM  r   r  r	   r   r   )r   r'   re  rl  r   r   r    r    sB    










zMHMessage._explain_to)N)r   r   r   r   r  r!   rL  rg  rM  r  r  r   r   r   r    r     s   
r   c                   @   sb   e Zd ZdZddgZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )r   z'Message with Babyl-specific properties.rr  _visibleNc                 C   s   g | _ t | _t| | dS )z#Initialize a BabylMessage instance.N)rr  r	   r  r!   r&   r   r   r    r!   %  s    zBabylMessage.__init__c                 C   s   | j dd S )z'Return a list of labels on the message.N)rr  rE   r   r   r    rs  +  s    zBabylMessage.get_labelsc                 C   s   t || _dS )z&Set the list of labels on the message.N)rG   rr  )r   r|  r   r   r    rv  /  s    zBabylMessage.set_labelsc                 C   s6   t |tr"|| jvr2| j| ntdt| dS )z+Add label to list of labels on the message.zlabel must be a string: %sN)rv   r   rr  r   r   r   r   r  r   r   r    r  3  s    

zBabylMessage.add_labelc                 C   s(   z| j | W n ty"   Y n0 dS )z4Remove label from the list of labels on the message.N)rr  r,   rg   r  r   r   r    remove_label;  s    zBabylMessage.remove_labelc                 C   s
   t | jS )z3Return a Message representation of visible headers.r	   r  rE   r   r   r    r  B  s    zBabylMessage.get_visiblec                 C   s   t || _dS )z2Set the Message representation of visible headers.Nr  )r   Zvisibler   r   r    ru  F  s    zBabylMessage.set_visiblec                 C   sb   | j  D ](}|| v r*| j || |  q
| j |= q
dD ]$}|| v r8|| j vr8| | | j |< q8dS )z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)r  rH   r  )r   headerr   r   r    update_visibleJ  s    
zBabylMessage.update_visiblec                 C   sr  t |tr~t|  }d|v r*|d n|d |d d|v sNd|v rX|d d|v rj|d d	|v r||d
 nt |trt|  }d|vr|d n
|d d	|v r|d d|v r|d nt |trt|  }d|v r|d d|v rn|d nTt |t	rP|
|   |  D ]}|| q<nt |tr^ntdt| dS )z9Copy Babyl-specific state to message insofar as possible.rm  r   r  rn  rq  r  rp  r  ro  r  r  r  r  r  r  r  N)rv   r
   r^  rs  r   r  r5  r   rM  r   ru  r  r  r	   r   r   )r   r'   r|  r  r   r   r    r  U  sH    










zBabylMessage._explain_to)N)r   r   r   r   r  r!   rs  rv  r  r  r  ru  r  r  r   r   r   r    r      s   
r   c                   @   s   e Zd ZdZdS )r   z&Message with MMDF-specific properties.Nr  r   r   r   r    r     s   r   c                   @   s   e Zd ZdZd&ddZd'ddZd(ddZd)d	d
Zd*ddZdd Z	dd Z
d+ddZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zed$d% ZeeZdS ),r   zA read-only wrapper of a file.Nc                 C   s$   || _ |du r| | _n|| _dS )zInitialize a _ProxyFile.N)r  r  _pos)r   r   posr   r   r    r!     s    z_ProxyFile.__init__c                 C   s   |  || jjS zRead bytes.)_readr  rl   r   sizer   r   r    rl     s    z_ProxyFile.readc                 C   s   |  || jjS r  )r  r  read1r  r   r   r    r    s    z_ProxyFile.read1c                 C   s   |  || jjS )zRead a line.)r  r  r   r  r   r   r    r     s    z_ProxyFile.readlinec                 C   s<   g }| D ].}| | |dur|t|8 }|dkr q8q|S )zRead multiple lines.Nr   )r   r   )r   sizehintrV   r   r   r   r    	readlines  s    
z_ProxyFile.readlinesc                 c   s   |   }|sdS |V  q dS )zIterate over lines.N)r   )r   r   r   r   r    rM     s    z_ProxyFile.__iter__c                 C   s   | j S )zReturn the position.)r  rE   r   r   r    r    s    z_ProxyFile.tellr   c                 C   s4   |dkr| j | j | j || | j  | _dS )zChange position.r   Nr  r|   r  r  r   offsetwhencer   r   r    r|     s    z_ProxyFile.seekc                 C   s4   t | dr0zt | jdr"| j  W | `n| `0 dS )zClose the file.r  rd   N)rY   r  rd   rE   r   r   r    rd     s
    
z_ProxyFile.closec                 C   s2   |du rd}| j | j ||}| j  | _|S )z"Read size bytes using read_method.Nrr   r  )r   r  read_methodrV   r   r   r    r    s    z_ProxyFile._readc                 C   s   | S )z$Context management protocol support.r   rE   r   r   r    	__enter__  s    z_ProxyFile.__enter__c                 G   s   |    d S r-   )rd   )r   excr   r   r    __exit__  s    z_ProxyFile.__exit__c                 C   s
   | j  S r-   )r  readablerE   r   r   r    r    s    z_ProxyFile.readablec                 C   s
   | j  S r-   )r  writablerE   r   r   r    r    s    z_ProxyFile.writablec                 C   s
   | j  S r-   )r  seekablerE   r   r   r    r    s    z_ProxyFile.seekablec                 C   s
   | j  S r-   )r  r^   rE   r   r   r    r^     s    z_ProxyFile.flushc                 C   s&   t | dsdS t | jdsdS | jjS )Nr  TrJ  F)rY   r  rJ  rE   r   r   r    rJ    s
    
z_ProxyFile.closed)N)N)N)N)N)r   )r   r   r   r   r!   rl   r  r   r  rM   r  r|   rd   r  r  r  r  r  r  r^   propertyrJ  r   r   r   r   r   r   r    r     s(   





		
r   c                   @   s<   e Zd ZdZdddZdd Zddd	Zd
d Zdd ZdS )r3  z&A read-only wrapper of part of a file.Nc                 C   s   t | || || _|| _dS )zInitialize a _PartialFile.N)r   r!   _start_stop)r   r   r  r  r   r   r    r!     s    z_PartialFile.__init__c                 C   s   t | | j S )z*Return the position with respect to start.)r   r  r  rE   r   r   r    r    s    z_PartialFile.tellr   c                 C   s<   |dkr| j | _d}n|dkr*| j| _d}t| || dS )z8Change position, possibly with respect to start or stop.r   r   r   N)r  r  r  r   r|   r  r   r   r    r|     s    z_PartialFile.seekc                 C   sB   | j | j }|dkrdS |du s0|dk s0||kr4|}t| ||S )z;Read size bytes using read_method, honoring start and stop.r   r*  N)r  r  r   r  )r   r  r  Z	remainingr   r   r    r    s    z_PartialFile._readc                 C   s   t | dr| `d S )Nr  )rY   r  rE   r   r   r    rd     s    
z_PartialFile.close)NN)r   )	r   r   r   r   r!   r  r|   r  rd   r   r   r   r    r3    s   


	r3  Tc              
   C   s  d}zft rrzt | t jt jB  W nL typ } z4|jtjtjtjfv rZt	d| j
 n W Y d}~n
d}~0 0 |rjzt| j
d }|  W nH ty } z0|jtjtjfv rW Y d}~W dS  W Y d}~n
d}~0 0 z^zt|j
| j
d  d}W n0 ttfy*   t|j
| j
d  d}Y n0 t|j
 W n. tyh   t|j
 t	d| j
 Y n0 W n8   t rt | t j |rt| j
d   Y n0 dS )z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sN.lockTzdot lock unavailable: %s)fcntllockfZLOCK_EXZLOCK_NBr   r   ZEAGAINr  r  r   r   r  rd   r   r   r   r   r   rh  r   r,   LOCK_UN)r   r  Zdotlock_doner   Zpre_lockr   r   r    r    sL    
r  c                 C   s8   t rt | t j tj| jd r4t| jd  dS )z*Unlock file f using lockf and dot locking.r  N)r  r  r  r   r   r   r   r,   r   r   r   r    r  9  s    r  c              	   C   sD   t | t jt jB t jB d}zt| dW t | S t | 0 dS )zCCreate a file if it doesn't exist and open for reading and writing.r   r  N)r   r   r   rG  O_RDWRrd   )r   fdr   r   r    r   @  s    

r   c                 C   s$   t d| tt t t f S )zBCreate a temp file based on path and open for reading and writing.z%s.%s.%s.%s)r   r   r   r   r   r   r   )r   r   r   r    r  H  s    r  c                 C   s$   |    ttdr t|   dS )z0Ensure changes to file f are physically on disk.fsyncN)r^   rY   r   r  filenor  r   r   r    r  N  s    
r  c                 C   s   t |  |   dS )z:Close file f, ensuring all changes are physically on disk.N)r  rd   r  r   r   r    r   T  s    r   c                   @   s   e Zd ZdZdS )r   z"Raised for module-specific errors.Nr  r   r   r   r    r   Z  s   r   c                   @   s   e Zd ZdZdS )r   z:The specified mailbox does not exist and won't be created.Nr  r   r   r   r    r   ]  s   r   c                   @   s   e Zd ZdZdS )r   z>The specified mailbox is not empty and deletion was requested.Nr  r   r   r   r    r   `  s   r   c                   @   s   e Zd ZdZdS )r   z)Another process caused an action to fail.Nr  r   r   r   r    r   c  s   r   c                   @   s   e Zd ZdZdS )r   z)A file appears to have an invalid format.Nr  r   r   r   r    r   f  s   r   )T)2r   r   r   r  r   r   r  r   r?   Zemail.messageZemail.generatorrw   r9   typesr   r  ImportError__all__r~   re   r   r   r  r)  r   r   r   r   r'   r	   r
   r5  r   r   r   r   r   r3  r  r  r   r  r  r   	Exceptionr   r   r   r   r   r   r   r   r    <module>   sl   
 j  8 DB4-  3 z%mqH_e'
*