o
    Ƌ|c3                    @   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yI   dZY nw 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dDd0d1Zd2d3 ZdDd4d5Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@Z"dEdAdBZ#e$e%Z&dS )Fr   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   lib/python3.10/mailbox.py__init__%   s   
zMailbox.__init__c                 C      t d)$Add message and return assigned key.&Method must be implemented by subclassNotImplementedErrorr   messager   r   r    add*      zMailbox.addc                 C   r"   )=Remove the keyed message; raise KeyError if it doesn't exist.r$   r%   r   keyr   r   r    remove.   r*   zMailbox.removec                 C   s   |  | d S N)r.   r,   r   r   r    __delitem__2   s   zMailbox.__delitem__c                 C   s&   z|  | W dS  ty   Y dS w z'If the keyed message exists, remove it.N)r.   KeyErrorr,   r   r   r    discard5   s
   zMailbox.discardc                 C   r"   )>Replace the keyed message; raise KeyError if it doesn't exist.r$   r%   r   r-   r(   r   r   r    __setitem__<   r*   zMailbox.__setitem__c                 C   s$   z|  |W S  ty   | Y S w )z9Return the keyed message, or default if it doesn't exist.)__getitem__r2   )r   r-   defaultr   r   r    get@   s
   zMailbox.getc                 C   sN   | j s| |S t| |}|  |W  d   S 1 s w   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    r7   G   s
   
$zMailbox.__getitem__c                 C   r"   )4Return a Message representation or raise a KeyError.r$   r%   r,   r   r   r    r:   O   r*   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   r"   )z8Return a byte string representation or raise a KeyError.r$   r%   r,   r   r   r    rC   Z   r*   zMailbox.get_bytesc                 C   r"   )6Return a file-like representation or raise a KeyError.r$   r%   r,   r   r   r    r=   ^   r*   zMailbox.get_filec                 C   r"   )Return an iterator over keys.r$   r%   r   r   r   r    iterkeysb   r*   zMailbox.iterkeysc                 C      t |  S )zReturn a list of keys.)listrH   rG   r   r   r    keysf      zMailbox.keysc              	   c   s:    |   D ]}z| | }W n	 ty   Y qw |V  qdS )z%Return an iterator over all messages.NrH   r2   r   r-   valuer   r   r    
itervaluesj   s   zMailbox.itervaluesc                 C   s   |   S r/   )rP   rG   r   r   r    __iter__s   s   zMailbox.__iter__c                 C   rI   )z,Return a list of messages. Memory intensive.)rJ   rP   rG   r   r   r    valuesv   rL   zMailbox.valuesc              	   c   s>    |   D ]}z| | }W n	 ty   Y qw ||fV  qdS )z.Return an iterator over (key, message) tuples.NrM   rN   r   r   r    	iteritemsz   s   zMailbox.iteritemsc                 C   rI   )z9Return a list of (key, message) tuples. Memory intensive.)rJ   rS   rG   r   r   r    items   rL   zMailbox.itemsc                 C   r"   )9Return True if the keyed message exists, False otherwise.r$   r%   r,   r   r   r    __contains__   r*   zMailbox.__contains__c                 C   r"   )*Return a count of messages in the mailbox.r$   r%   rG   r   r   r    __len__   r*   zMailbox.__len__c                 C   s   |   D ]}| | qdS )zDelete all messages.N)rK   r3   r,   r   r   r    clear   s   zMailbox.clearc                 C   s2   z| | }W n t y   | Y S w | | |S )z3Delete the keyed message and return it, or default.)r2   r3   )r   r-   r8   resultr   r   r    pop   s   
zMailbox.popc                 C   s&   |   D ]
}|| |f  S td)z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailbox)rH   r[   r2   r,   r   r   r    popitem   s   zMailbox.popitemc              	   C   sp   t |dr
| }nt |dr| }n|}d}|D ]\}}z|| |< W q ty/   d}Y qw |r6tddS )z4Change the messages that correspond to certain keys.rS   rT   FTzNo message with key(s)N)hasattrrS   rT   r2   )r   argsourceZbad_keyr-   r(   r   r   r    update   s   



zMailbox.updatec                 C   r"   )&Write any pending changes to the disk.r$   r%   rG   r   r   r    flush   r*   zMailbox.flushc                 C   r"   )Lock the mailbox.r$   r%   rG   r   r   r    lock   r*   zMailbox.lockc                 C   r"   )#Unlock the mailbox if it is locked.r$   r%   rG   r   r   r    unlock   r*   zMailbox.unlockc                 C   r"   )Flush and close the mailbox.r$   r%   rG   r   r   r    close   r*   zMailbox.closec                 C   s$   z| dW S  ty   tdw )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r?t }tj||d}|| |	d |
 }|dt}|| | jr;|ts=|t d
S d
S d
S t |tttjfrt |tjrYtdtd | }t |trc| |}|rk|dd}|dt}|| | jr|ts|t d
S d
S d
S t|drt|drtd	td |j}d
}	 | }|dr|d
d d }n|dr|d
d d }|sn|r|drd|dd
  }|dt}|| |}q| jr|r|ts|t d
S d
S d
S d
S tdt| )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 insteadNT   
      From s   >From    Invalid message type: %s)
isinstancerA   r(   r	   ioBytesIO	generatorBytesGeneratorflattenseekrp   replacelinesepwrite_append_newlineendswithstrbytesStringIOwarningswarnDeprecationWarninggetvaluerl   r]   rq   readline
startswith	TypeErrortype)	r   r(   targetZmangle_from_rq   gendataZlastlineliner   r   r    _dump_message   sf   










zMailbox._dump_messageNTr/   F)'__name__
__module____qualname____doc__r!   r)   r.   r0   r3   r6   r9   r7   r:   rD   rC   r=   rH   rK   rP   rQ   rR   rS   rT   rV   rX   rY   r[   r\   r`   rb   rd   rf   rh   rl   r   r   classmethodr   __class_getitem__r   r   r   r    r   "   sF    

		
	

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sE|r@t| jd | j	 D ]}t|d q6n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mkdirrR   r   _toc_toc_mtimes
_last_read_skewfactor)r   dirnamer   r   r   r   r   r    r!     s    

zMaildir.__init__c              
   C   sf  |   }z| || W n ty   |  t|j  w t| t|t	r;|
 }| j|  }|| jkr:d}nd}d}tj|j| jd }tj| j||| }t|t	rlt|jtj|j| f z'z	t|j| W n ttfy   t|j| Y W |S w t|j W |S  ty } zt|j |jtjkrtd|  d}~ww )r#    r   r   z$Name clash with existing message: %sN)_create_tmpr   BaseExceptionrh   r   r.   name_sync_closerz   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)   $  sR   



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 dS  ttfy   Y dS w r1   )r.   r2   FileNotFoundErrorr,   r   r   r    r3   R  s
   zMaildir.discardc                 C   s   |  |}| |}|  |}t|tr|}n|}tj|}| j|v r0| j|| jd  }nd}| 	| tj
| j|}	tj
| j||| }
t|tr]t|	tj|	| f t|	|
 dS )r4   rv   r   N)r   r)   rz   r
   r   r   r   r   r   r3   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    r6   Z  s$   






zMaildir.__setitem__c                 C   s   |  |}ttj| j|d}| jr| |}nt|}W d   n1 s(w   Y  tj|\}}|	| | j
|v rJ||| j
d  |tjtj| j| |S )r?   rbNrv   )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    r:   u  s   


zMaildir.get_messagec                 C   sP   t tj| j| |d}| tdW  d   S 1 s!w   Y  dS )2Return a bytes representation or raise a KeyError.r   rm   N)	r   r   r   r   r   r   rp   r   r   r   r-   r   r   r   r    rC     s   $zMaildir.get_bytesc                 C   s$   t tj| j| |d}t|S )rE   r   )r   r   r   r   r   r   
_ProxyFiler   r   r   r    r=     s   zMaildir.get_filec              	   c   sB    |    | jD ]}z| | W n	 ty   Y qw |V  qdS rF   N)_refreshr   r   r2   r,   r   r   r    rH     s   
zMaildir.iterkeysc                 C      |    || jv S rU   )r   r   r,   r   r   r    rV        
zMaildir.__contains__c                 C      |    t| jS rW   )r   lenr   rG   r   r   r    rX     r   zMaildir.__len__c                 C      dS )"Write any pending changes to disk.Nr   rG   r   r   r    rb     s   zMaildir.flushc                 C   r   )rc   Nr   rG   r   r   r    rd        zMaildir.lockc                 C   r   )re   Nr   rG   r   r   r    rf     r   zMaildir.unlockc                 C   r   rg   Nr   rG   r   r   r    rh     r   zMaildir.closec                 C   s\   g }t | jD ]#}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   rZ   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|s,t 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   rh   r   O_CREATO_WRONLY)r   r   r   rZ   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 s,|d dkr2td| qt |D ]!}|dkrY|dkrY|dkrYt jt j||rYtd||f q8t j|d	d
D ]#\}}}|D ]}t 	t j|| qh|D ]}t 
t j|| qwqat 
| 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 ]}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 r|dd}dt|t|d d t tj|f }tj	
| jd|}zt| W n! tya   t jd7  _zt|W  Y S  ty^   Y nw Y nw td	| )
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: %s)r   socketgethostnamer   intr   getpidr   _countr   r   r   statr   _create_carefullyFileExistsErrorr   )r   r   Zhostnamer   r   r   r   r    r     s0   zMaildir._create_tmpc                 C   s   t   | j d| j kr/d}| jD ]}tj| j| }|| j| kr%d}|| j|< q|s/dS i | _| jD ]/}| j| }t	|D ]"}tj
||}tj|rQqA|| jd }tj
||| j|< qAq5t   | _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   st   zt jt j| j| j| r| j| W S W n	 ty    Y nw |   z| j| W S  ty9   td| dw )z=Use TOC to return subpath for given key, or raise a KeyError.No message with key: %sN)r   r   r   r   r   r   r2   r   r,   r   r   r    r   &  s   zMaildir._lookupc                 C   sL   t | ds
|  | _	 z| t| j W S  ty   Y dS  ty%   Y q
w )z0Return the next message in a one-time iteration._onetime_keysTN)r]   rH   r	  nextStopIterationr2   rG   r   r   r    r
  4  s   

zMaildir.nextr   )r   r   r   r   r   r!   r)   r.   r3   r6   r:   rC   r=   rH   rV   rX   rb   rd   rf   rh   r   r   r   r   r   r  r   r   r   r
  r   r   r   r    r     s8    
*
	
$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 n7 tyG } z+|jtjkr,|r't| jd}nt| j|jtjtj	fv r<t| jd}n W Y d}~nd}~ww || _
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 )r4   TN)r   r  r   r  r5   r   r   r    r6   k  s   

z_singlefileMailbox.__setitem__c                 c   s    |    | j E dH  dS r   )r   r   rK   rG   r   r   r    rH   q  s   z_singlefileMailbox.iterkeysc                 C   r   r   )r   r   r,   r   r   r    rV   v  r   z_singlefileMailbox.__contains__c                 C   r   r   )r   r   r   rG   r   r   r    rX   {  r   z_singlefileMailbox.__len__c                 C   s   | j st| j d| _ dS dS )rc   TN)r  
_lock_filer  rG   r   r   r    rd        

z_singlefileMailbox.lockc                 C   s   | j rt| j d| _ dS dS re   FN)r  _unlock_filer  rG   r   r   r    rf     r  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r1td| j|f t	| j
}zSi }| | t| j D ]=}| j| \}}| j| | | | }	 | jtd|| j  }|son|| q^|| f||< | | qE| | _W n   |  t|j  t| | j  t| j
j}	t|j|	 z
t|j| j
 W n ty   t| j
 t|j| j
 Y nw t| j
d| _|| _d| _ d| _| jrt| jdd	 dS dS )
r   FNr   r  z4Size of mailbox file changed (expected %i, found %i)T   r  )dotlock) r  r  _sync_flushr  r   r   tellr  r   _create_temporaryr   _pre_mailbox_hooksortedrK   _pre_message_hookrp   minr   _post_message_hookrh   r   r.   r   r   r  st_modechmodr   r  r   r  r  )
r   Zcur_lenZnew_fileZnew_tocr-   startstopZ	new_startrq   moder   r   r    rb     sj   








z_singlefileMailbox.flushc                 C   r   ),Called before writing the mailbox to file f.Nr   r   r   r   r   r    r!    r   z$_singlefileMailbox._pre_mailbox_hookc                 C   r   )-Called before writing each message to file f.Nr   r,  r   r   r    r#    r   z$_singlefileMailbox._pre_message_hookc                 C   r   ,Called after writing each message to file f.Nr   r,  r   r   r    r%    r   z%_singlefileMailbox._post_message_hookc                 C   s   z#|    W z| jr|   W | j  dS W | j  dS | j  w z| jr3|   W | j  w W | j  w | j  w r   )rb   r  rf   r  rh   rG   r   r   r    rh     s   


z_singlefileMailbox.closec                 C   sH   | j du r	|   |dur"z| j | W S  ty!   td| dw dS )z'Return (start, stop) or raise KeyError.Nr  )r   _generate_tocr2   r,   r   r   r    r     s   
z_singlefileMailbox._lookupc                 C   s   | j dd | j  }t| jdkr| js| | j  z| | j  | |}| 	| j  W n t
y=   | j |  w | 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   truncaterb   r  )r   r(   ZbeforeZoffsetsr   r   r    r    s   


z"_singlefileMailbox._append_messager   r/   )r   r   r   r   r!   r)   r.   r6   rH   rV   rX   rd   rf   rb   r!  r#  r%  rh   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?       rm   rx   Nr   )r   r  r   r   r   r   rp   r  _message_factoryset_fromdecode)r   r-   r(  r)  	from_linestringr   r   r   r    r:   	  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    rD     s
   
z_mboxMMDF.get_stringc                 C   sJ   |  |\}}| j| |s| j  | j|| j  }|tdS )r:  rm   )r   r  r   r   rp   r  r   r   )r   r-   r<  r(  r)  r9  r   r   r    rC     s   
z_mboxMMDF.get_bytesc                 C   s<   |  |\}}| j| |s| j  t| j| j |S )rE   )r   r  r   r   _PartialFiler  )r   r-   r<  r(  r)  r   r   r    r=   !  s
   
z_mboxMMDF.get_filec                 C   s  d}t |tr| |}t |tr3|dr3|d}|dkr.|d| }||d d }n*|}d}n%t |trD| d}d| }nt |t	j
jrX| }|durX|d}|du rgdtt   }| j }| j|t  | || j| j | j }||fS )	z1Format a message and blindly write to self._file.Nrw   rm   rv   r   r4  r   s   From MAILER-DAEMON )rz   r   rl   r   r   find_mboxMMDFMessageget_fromri   rA   r(   r	   get_unixfromr   asctimegmtimer  r  r   r   r   _mangle_from_)r   r(   r8  newlineZauthorr(  r)  r   r   r    r1  )  s0   







z_mboxMMDF._install_messageNr   )
r   r   r   r   rD  r:   rD   rC   r=   r1  r   r   r   r    r3    s    



	r3  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      t | _t| ||| dS )zInitialize an mbox mailbox.N)r   r5  r3  r!   r   r   r   r    r!   O     zmbox.__init__c                 C   s   | t dS r.  r   r   r,  r   r   r    r%  T     zmbox._post_message_hookc                 C   s   g g }}d}| j d 	 | j  }| j  }|dr>t|t|k r6|r1||tt  n|| || d}n|sR|rL||tt  n|| n
|tkrYd}nd}qtt	t
||| _t| j| _| j  | _dS )0Generate key-to-(start, stop) table of contents.Fr   Trw   N)r  r   r  r   r   r   r   r   dict	enumeratezipr   r  r  )r   startsstopsZlast_was_emptyline_posr   r   r   r    r0  X  s2   






zmbox._generate_tocr   )	r   r   r   r   rD  r   r!   r%  r0  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   rF  )zInitialize an MMDF mailbox.N)r   r5  r3  r!   r   r   r   r    r!   }  rG  zMMDF.__init__c                 C      | dt  dS )r-     NrH  r,  r   r   r    r#       zMMDF._pre_message_hookc                 C   s   | td t  dS )r/  rR  NrH  r,  r   r   r    r%    s   zMMDF._post_message_hookc                 C   s   g g }}| j d d}	 |}| j  }| j  }|dt rM|| 	 |}| j  }| j  }|dt krC||tt  n	|sK|| nq'n|sPnqtt	t
||| _t| j| _| j dd | j  | _dS )rJ  r   TrR  r  N)r  r   r   r  r   r   r   r   rK  rL  rM  r   r  r  )r   rN  rO  next_posrP  r   r   r   r    r0    s8   







zMMDF._generate_tocr   )r   r   r   r   r!   r#  r%  r0  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s5|r0t| 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   rh   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}zQ| j	r+t
| z7z| || W n tyN   | j	rBt| t| d}t|  w t|trZ| || W | j	rbt| n	| j	rkt| w w W |sst| |S |s|t| w w )r#   r   r   FT)rK   r   maxr   r   r   r   r   r  r  r  r   r   r  r   r.   rz   r   _dump_sequences)r   r(   rK   Znew_keyr   r   closedr   r   r    r)     sJ   



zMH.addc              
   C   sl   t j| jt|}zt|d}W n ty* } z|jtjkr%t	d|  d}~ww |
  t | dS )r+   r  r  N)r   r   r   r   r   r   r   r   r  r2   rh   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y* } z|jtjkr%t	d|  d}~ww z?| j
r3t| z't t |t jt jB  | || t|trR| || W | j
rZt| n	| j
rct| w w W t| dS t| w )r4   r  r  N)r   r   r   r   r   r   r   r   r  r2   r  r  rh   r   O_TRUNCr   rz   r   rX  r  r   )r   r-   r(   r   r   r   r   r   r    r6     s4   

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y9 } z|jtj	kr4t
d|  d}~ww |& | j rDt| zt|}W | j rQt| n	| j rZt| w w W d   n1 sew   Y  |   D ]\}}||v r}|| qp|S )r?   r  r   r  N)r  r   r   r   r   r   r   r   r   r  r2   r  r   r  get_sequencesrT   add_sequence)r   r-   r   r   r   r   key_listr   r   r    r:     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y9 } z|jtj	kr4t
d|  d}~ww |) | j rDt| z| tdW | j rTt| W  d   S | j rdt| w w 1 shw   Y  dS )r   r  r   r  Nrm   )r  r   r   r   r   r   r   r   r   r  r2   r  rp   r   r   r  r   r-   r   r   r   r   r    rC     s.   
zMH.get_bytesc              
   C   sX   zt tj| jt|d}W t
|S  ty+ } z|jtjkr&t	d|  d}~ww )rE   r   r  N)r   r   r   r   r   r   r   r   r  r2   r   r^  r   r   r    r=   ,  s   zMH.get_filec                 C   s   t tdd t| jD S )rF   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   rG   r   r   r    rH   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    rV   <  s   zMH.__contains__c                 C   s   t t|  S r   )r   rJ   rH   rG   r   r   r    rX   @     z
MH.__len__c                 C   s6   | j sttj| jdd| _t| j d| _ dS dS )rc   rU  r  TN)r  r   r   r   r   r   r  r  rG   r   r   r    rd   D  s
   

zMH.lockc                 C   s,   | j rt| j t| j | `d| _ dS dS r  )r  r  r  r   rG   r   r   r    rf   K  s   


z	MH.unlockc                 C   r   )ra   Nr   rG   r   r   r    rb   S  r   zMH.flushc                 C   s   | j r	|   dS dS r   )r  rf   rG   r   r   r    rh   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   rd  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r"ntd| j t | dS )r   rU  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p}t|   |D ]^}zM|d\}}t }| D ]$}| r7|	t
| q)dd |dD \}}	|t||	d	  q) fd
dt|D ||< t|| dkrf||= W q tyv   td|  w W d   |S 1 sw   Y  |S )z=Return a name-to-key-list dictionary to define each sequence.rU  rASCIIencodingr   c                 s   s    | ]}t |V  qd S r/   )r   )r`  xr   r   r    ra        z#MH.get_sequences.<locals>.<genexpr>-r   c                    s   g | ]}| v r|qS r   r   )r`  r-   Zall_keysr   r    
<listcomp>  s    z$MH.get_sequences.<locals>.<listcomp>r   z"Invalid sequence specification: %sN)r   r   r   r   r   setrK   r   r_  r)   r   r`   ranger"  r   rk   r   rstrip)
r   resultsr   r   r   contentsrK   specr(  r)  r   rm  r    r[  z  s4   
zMH.get_sequencesc                 C   s  t tj| jdddd}zqtt |jtjtjB  |	 D ]W\}}t
|dkr+q ||d  d}d}tt|D ])}|d	 |krN|sMd
}|d n|r\d}|d||f  n|d|  |}q<|rr|t|d  q |d q W t| dS t| w )z:Set sequences using the given name-to-key-list dictionary.rU  zr+rg  rh  r   r   NFr   Trl  z%s %sz %s
)r   r   r   r   r   rh   r   r   rZ  rT   r   r   r"  ro  r   r   )r   	sequencesr   r   rK   prevZ
completingr-   r   r   r    set_sequences  s2   
zMH.set_sequencesc           	      C   s8  |   }d}g }|  D ]`}|d |krh|||d f zttj| jt|tj| jt|d  W n# t	t
fyZ   ttj| jt|tj| jt|d  Y nw ttj| jt| |d7 }q|d | _t|dkrzdS | D ]\}}|D ]\}}||v r||||< qq~| | dS )z?Re-name messages to eliminate numbering gaps. Invalidates keys.r   r   N)r[  rH   r   r   r   r   r   r   r   r   r   r   unlinkr  r   rT   indexrx  )	r   rv  rw  Zchangesr-   r   r]  oldr   r   r   r    pack  s6   

zMH.packc                 C   st   |  }|   }| D ]\}}||v r|| q||v r$|||= q|D ]}||vr2|g||< q'| | dS )z;Inspect a new MHMessage and update sequences appropriately.N)r[  rT   r   rz  rx  )r   r(   r-   Zpending_sequencesZall_sequencesr   r]  sequencer   r   r    rX    s   
zMH._dump_sequencesr   )r   r   r   r   r!   r)   r.   r6   r:   rC   r=   rH   rV   rX   rd   rf   rb   rh   r   r   r   r   r[  rx  r|  rX  r   r   r   r    r     s0    
"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.>   resentZfileddeleted	forwardedunseenZeditedansweredNTc                 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)   rz   r   
get_labelsr  )r   r(   r-   r   r   r    r)     s   
z	Babyl.addc                 C   s&   t | | || jv r| j|= dS dS r   )r  r.   r  r,   r   r   r    r.     s   
zBabyl.removec                 C   s.   t | || t|tr| | j|< dS dS )r4   N)r  r6   rz   r   r  r  r5   r   r   r    r6     s   
zBabyl.__setitem__c           
      C   s  |  |\}}| j| | j  t }	 | j }|dt ks$|s%n
||td qt }	 | j }|tks?|s@n
||td q4|| j	  }|dksWJ | j
|}|td}t| | }	|	|  || jv r|	| j|  |	S )r?   T   *** EOOH ***rm   r   )r   r  r   r   r{   r|   r   r   r   r  rp   r   r   set_visibler  
set_labels)
r   r-   r(  r)  original_headersr   Zvisible_headersnbodyr   r   r   r    r:     s4   



zBabyl.get_messagec           	      C   s   |  |\}}| j| | j  t }	 | j }|dt ks$|s%n
||td q	 | j }|tks;|s<nq0|	 }|| j
  }|dksNJ | j|}|td}|| S )r:  Tr  rm   r   )r   r  r   r   r{   r|   r   r   r   r   r  rp   )	r   r-   r(  r)  r  r   Zheadersr  r   r   r   r    rC     s*   


zBabyl.get_bytesc                 C   s   t | |dtS )rE   rm   )r{   r|   rC   r   r   r,   r   r   r    r=   (     zBabyl.get_filec                 C   s<   |    t }| j D ]}|| q|| j t|S )z4Return a list of user-defined labels in the mailbox.)r   ro  r  rR   r`   difference_update_special_labelsrJ   )r   labelsZ
label_listr   r   r    r  ,  s   zBabyl.get_labelsc                 C   s<  g g }}| j d d}g }	 |}| j  }| j  }|dt krOt|t|k r3||tt  || dd | j  dd dD }|| n(|d	ksY|d	t krkt|t|k rj||tt  n|sw||tt  nqtt	t
||| _tt	|| _t| j| _| j dd
 | j  | _dS )rJ  r   Ts   c                 S   s   g | ]
}|  r|  qS r   )stripr`  labelr   r   r    rn  C  s    z'Babyl._generate_toc.<locals>.<listcomp>r   N   ,   r  )r  r   r   r  r   r   r   r   rK  rL  rM  r   r  r  r  )r   rN  rO  rT  Zlabel_listsrP  r   r  r   r   r    r0  5  s:   



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/   )ri   r  r   r   r    ra  X  rk  z*Babyl._pre_mailbox_hook.<locals>.<genexpr>s   Labels:r  r  N)r   r  r   r   )r   r   Zbabylr  r   r   r    r!  S  s   zBabyl._pre_mailbox_hookc                 C   rQ  )r-     NrH  r,  r   r   r    r#  ]  rS  zBabyl._pre_message_hookc                 C   s   | td  dS )r/  r  NrH  r,  r   r   r    r%  a  rS  zBabyl._post_message_hookc                 C   s`  | j  }t|trXg }g }| D ]}|| jv r|| q|| q| j d |D ]}| j d|   q-| j d |D ]}| j d|  d  qB| j t	 n| j dt	  t|t
jjrt }t
j|dd}|| |d 	 | }| j |d
t	 |d
ks|snq~| j dt	  t|trt }	t
j|	dd}
|
|  	 |	 }| j |d
t	 |d
ks|snqn|d 	 | }| j |d
t	 |d
ks|snq	 |d}|sn| j |d
t	 qn)t|tttjfr{t|tjrtdtd | }t|tr%| |}|dd }|d dkrf| j |d| d
t	 | j dt	  | j |d| d
t	 | j ||d d
t	 n| j dt	 t	  | j |d
t	 nt |drt |drtdtd |j!}| }d	}	 | }|"dr|dd d
 }n|"dr|dd d
 }| j |d
t	 |d
ks|s|rd}| j dt	  || nnq	 | }|sn4|"dr|dd t	 }n|"dr|dd t	 }n|"d
r|dd t	 }| j | qnt#dt$| | j  }||fS )z0Write message contents and return (start, stop).   1s   , s   ,,    r  s   1,,Fr   Trm   r  r  rn   ro   s   

r  rv   Nr   rq   rr   rs   rt   ru   ry   )%r  r  rz   r   r  r  r   r   ri   r   rA   r(   r	   r{   r|   r}   r~   r   r   r   r   get_visiblerp   r   r   r   r   r   r   r   rl   r>  r]   rq   r   r   r   )r   r(   r(  Zspecial_labelsr  r  Zorig_bufferZorig_generatorr   Z
vis_bufferZvis_generatorrq   Z
body_startZoriginal_posZ
first_passr)  r   r   r    r1  e  s   










zBabyl._install_messager   )r   r   r   r   	frozensetr  r!   r)   r.   r6   r:   rC   r=   r  r0  r!  r#  r%  r1  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r| t| t |tr||  dS dS t |tr,| t	| dS t |t
r;| t| dS t |tjrK| t| dS t|drZ| t| dS |du rgtjj|  dS tdt| )zInitialize a Message instance.rp   Nry   )rz   rA   r(   r	   _become_messagecopyZdeepcopy_explain_tor   rB   r   Zmessage_from_stringr{   TextIOWrapperZmessage_from_filer]   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)z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)rz   r	   r   r'   r   r   r    r    s   
zMessage._explain_tor/   )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      | j S )zReturn 'new' or 'cur'.)r  rG   r   r   r    r        zMaildirMessage.get_subdirc                 C   s&   |dks|dkr|| _ dS td| )zSet subdir to 'new' or 'cur'.r   r   z!subdir must be 'new' or 'cur': %sN)r  rk   )r   r   r   r   r    r     s   
zMaildirMessage.set_subdirc                 C   s   | j dr| j dd S dS )*Return as a string the flags that are set.2,r  Nr   )r  r   rG   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  r  zMaildirMessage.set_flagsc                 C   $   |  dt|  t|B  dS z.Set the given flag(s) without changing others.r   Nr  r   ro  r  r   flagr   r   r    add_flag     $zMaildirMessage.add_flagc                 C   s0   |   r| dt|   t|  dS dS )7Unset the given string flag(s) without changing others.r   N)r  r  r   ro  r  r   r   r    remove_flag  s   $zMaildirMessage.remove_flagc                 C   r  )z<Return delivery date of message, in seconds since the epoch.)r  rG   r   r   r    r   !  r  zMaildirMessage.get_datec                 C   s.   zt || _W dS  ty   td| dw )z9Set delivery date of message, in seconds since the epoch.zcan't convert to float: %sN)floatr  rk   r   )r   dater   r   r    r   %  s
   zMaildirMessage.set_datec                 C   r  )z%Get the message's "info" as a string.)r  rG   r   r   r    r   ,  r  zMaildirMessage.get_infoc                 C   s$   t |tr
|| _dS tdt| )z Set the message's "info" string.zinfo must be a string: %sN)rz   r   r  r   r   )r   infor   r   r    r   0  s   

zMaildirMessage.set_infoc                 C   s  t |tr||   ||   ||   dS t |trct	|  }d|v r0|
d |  dkr;|
d d|v rD|
d d|v rM|
d d|v rV|
d |d	t|   dS t |trt	|  }d|vrw|d
 d|v r|d d|v r|d dS dS t |trt	|  }d|vr|d
 d|v r|d d|v r|d d|v r|d dS dS t |trdS tdt| )z;Copy Maildir-specific state to message insofar as possible.SRr   OTDFAMAILER-DAEMONr  repliedflaggedr  r  Pr  $Cannot convert to specified type: %sN)rz   r
   r  r  r   r   r   r   r?  ro  r  r6  r   rC  r   r\  r   	add_labelr	   r   r   )r   r(   r  r   r   r    r  7  sT   














zMaildirMessage._explain_tor/   )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 )r?  z/Message with mbox- or MMDF-specific properties._fromNc                 C   sV   |  dd t|tjjr#| }|dur#|dr#|  |dd  t| | dS )z'Initialize an mboxMMDFMessage instance.r  TNzFrom rx   )r6  rz   rA   r(   r	   rA  r   r!   )r   r(   r;  r   r   r    r!   h  s   z_mboxMMDFMessage.__init__c                 C   r  )z Return contents of "From " line.)r  rG   r   r   r    r@  q  r  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   rC  rB  r  )r   r<  Ztime_r   r   r    r6  u  s
   
z_mboxMMDFMessage.set_fromc                 C   s   |  dd|  dd S )r  Statusr   X-Status)r9   rG   r   r   r    r  }  r  z_mboxMMDFMessage.get_flagsc                 C   s   t |}d\}}dD ]}||v r||7 }|| q
dD ]}||v r+||7 }|| q|dt|7 }z| d| W n tyL   | d| Y nw z	| d| W dS  tyf   | d| Y dS w )r  )r   r   )r  r  )r  r  r  r   r  r  N)ro  r.   r   r"  replace_headerr2   Z
add_header)r   r  Zstatus_flagsZxstatus_flagsr  r   r   r    r    s.   

z_mboxMMDFMessage.set_flagsc                 C   r  r  r  r  r   r   r    r    r  z_mboxMMDFMessage.add_flagc                 C   s8   d| v sd| v r|  dt|  t|  dS dS )r  r  r  r   Nr  r  r   r   r    r    s   $z_mboxMMDFMessage.remove_flagc              	   C   s  t |trgt|  }d|v r|d d|v r|d d|v r&|d d|v r/|d d|v r8|d |d	= |d
= d|   dd }z|	t
t|d W dS  ttfyf   Y dS w t |tr|||   ||   dS t |trt|  }d|vr|d d|v r|d d|v r|d |d	= |d
= dS t |trt|  }d|vr|d d|v r|d d|v r|d |d	= |d
= dS t |trdS tdt| )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 %Yr  r  r  r  r  r  )rz   r
   ro  r  r   r  r   r@  r   r   calendarZtimegmr   strptimerk   OverflowErrorr?  r  r6  r   r\  r   r  r	   r   r   )r   r(   r  Z
maybe_dater   r   r    r    sd   

















z_mboxMMDFMessage._explain_tor/   )r   r   r   r   r  r!   r@  r6  r  r  r  r  r  r   r   r   r    r?  c  s    
	
r?  c                   @      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         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      | j dd S )z4Return a list of sequences that include the message.N)r  rG   r   r   r    r[    rI  zMHMessage.get_sequencesc                 C      t || _dS )z3Set the list of sequences that include the message.N)rJ   r  )r   rv  r   r   r    rx    rI  zMHMessage.set_sequencesc                 C   8   t |tr|| jvr| j| dS dS tdt| )z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rz   r   r  r   r   r   r   r}  r   r   r    r\    
   

zMHMessage.add_sequencec                 C   (   z	| j | W dS  ty   Y dS w )zARemove sequence from the list of sequences including the message.N)r  r.   rk   r  r   r   r    remove_sequence  
   zMHMessage.remove_sequencec                 C   sP  t |tr5t|  }d|v r|d n
|d |d d|v r(|d d|v r3|d dS dS t |tret|  }d|vrJ|d n|d	 d|v rX|d d|v rc|d
 dS dS t |trx|  D ]}|| qndS t |t	rt|  }d|v r|
d d|v r|
d dS dS t |trdS tdt| )z6Copy MH-specific state to message insofar as possible.r  r   r  r  r  r  r  ROr  r  r  r  N)rz   r
   ro  r[  r   r  r?  r   r\  r   r  r	   r   r   )r   r(   rv  r}  r   r   r    r    sJ   










zMHMessage._explain_tor/   )r   r   r   r   r  r!   r[  rx  r\  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.r  _visibleNc                 C   s   g | _ t | _t| | dS )z#Initialize a BabylMessage instance.N)r  r	   r  r!   r'   r   r   r    r!   %  s   zBabylMessage.__init__c                 C   r  )z'Return a list of labels on the message.N)r  rG   r   r   r    r  +  rI  zBabylMessage.get_labelsc                 C   r  )z&Set the list of labels on the message.N)rJ   r  )r   r  r   r   r    r  /  rI  zBabylMessage.set_labelsc                 C   r  )z+Add label to list of labels on the message.zlabel must be a string: %sN)rz   r   r  r   r   r   r   r  r   r   r    r  3  r  zBabylMessage.add_labelc                 C   r  )z4Remove label from the list of labels on the message.N)r  r.   rk   r  r   r   r    remove_label;  r  zBabylMessage.remove_labelc                 C   s
   t | jS )z3Return a Message representation of visible headers.r	   r  rG   r   r   r    r  B  s   
zBabylMessage.get_visiblec                 C   r  )z2Set the Message representation of visible headers.Nr  )r   Zvisibler   r   r    r  F  rI  zBabylMessage.set_visiblec                 C   sb   | j  D ]}|| v r| j || |  q| j |= qdD ]}|| v r.|| j vr.| | | j |< qdS )z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)r  rK   r  )r   headerr   r   r    update_visibleJ  s   
zBabylMessage.update_visiblec                 C   sx  t |trBt|  }d|v r|d n
|d |d d|v s'd|v r,|d d|v r5|d d	|v r@|d
 dS dS t |trrt|  }d|vrW|d n|d d	|v re|d d|v rp|d dS dS t |trt|  }d|v r|d d|v r|d dS dS t |t	r|
|   |  D ]}|| qdS t |trdS tdt| )z9Copy Babyl-specific state to message insofar as possible.r  r   r  r  r~  r  r  r  r  r  r  r  r  r  r  r  N)rz   r
   ro  r  r   r  r?  r   r\  r   r  r  r  r	   r   r   )r   r(   r  r  r   r   r    r  U  sP   











zBabylMessage._explain_tor/   )r   r   r   r   r  r!   r  r  r  r  r  r  r  r  r   r   r   r    r      s    
r   c                   @   r  )r   z&Message with MMDF-specific properties.Nr  r   r   r   r    r     r  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| | _dS || _dS )zInitialize a _ProxyFile.N)r  r  _pos)r   r   posr   r   r    r!     s   
z_ProxyFile.__init__c                 C      |  || jjS zRead bytes.)_readr  rp   r   sizer   r   r    rp     rc  z_ProxyFile.readc                 C   r  r  )r  r  read1r  r   r   r    r    rc  z_ProxyFile.read1c                 C   r  )zRead a line.)r  r  r   r  r   r   r    r     rc  z_ProxyFile.readlinec                 C   s>   g }| D ]}| | |dur|t|8 }|dkr |S q|S )zRead multiple lines.Nr   )r   r   )r   sizehintrZ   r   r   r   r    	readlines  s   
 z_ProxyFile.readlinesc                 c   s    	 |   }|s
dS |V  q)zIterate over lines.TN)r   )r   r   r   r   r    rQ     s   z_ProxyFile.__iter__c                 C   r  )zReturn the position.)r  rG   r   r   r    r    r  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   s@   t | drzt | jdr| j  W | `dS W | `dS | `w dS )zClose the file.r  rh   N)r]   r  rh   rG   r   r   r    rh     s   
z_ProxyFile.closec                 C   s2   |du rd}| j | j ||}| j  | _|S )z"Read size bytes using read_method.Nrv   r  )r   r  read_methodrZ   r   r   r    r    s   z_ProxyFile._readc                 C   s   | S )z$Context management protocol support.r   rG   r   r   r    	__enter__  r   z_ProxyFile.__enter__c                 G   s   |    d S r/   )rh   )r   excr   r   r    __exit__  s   z_ProxyFile.__exit__c                 C   
   | j  S r/   )r  readablerG   r   r   r    r       
z_ProxyFile.readablec                 C   r  r/   )r  writablerG   r   r   r    r    r  z_ProxyFile.writablec                 C   r  r/   )r  seekablerG   r   r   r    r    r  z_ProxyFile.seekablec                 C   r  r/   )r  rb   rG   r   r   r    rb     r  z_ProxyFile.flushc                 C   s&   t | dsdS t | jdsdS | jjS )Nr  TrY  F)r]   r  rY  rG   r   r   r    rY    s
   
z_ProxyFile.closedr/   r   )r   r   r   r   r!   rp   r  r   r  rQ   r  r   rh   r  r  r  r  r  r  rb   propertyrY  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 )r=  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  rG   r   r   r    r    rc  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 s|dk s||kr|}t| ||S )z;Read size bytes using read_method, honoring start and stop.r   r4  N)r  r  r   r  )r   r  r  Z	remainingr   r   r    r    s   z_PartialFile._readc                 C   s   t | dr	| `d S d S )Nr  )r]   r  rG   r   r   r    rh     s   
z_PartialFile.close)NNr  )	r   r   r   r   r!   r  r   r  rh   r   r   r   r    r=    s    


	r=  Tc              
   C   s  d}zt r1zt | t jt jB  W n ty0 } z|jtjtjtjfv r+t	d| j
  d}~ww |rzt| j
d }|  W n ty^ } z|jtjtjfv rYW Y d}~W dS  d}~ww z4zt|j
| j
d  d}W n ttfy   t|j
| j
d  d}Y nw t|j
 W W dS W W dS  ty   t|j
 t	d| j
 w W dS    t rt | t j |rt| j
d   )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   rh   r   r   r   r   r   ry  r  r.   LOCK_UN)r   r  Zdotlock_doner   Zpre_lockr   r   r    r    s\   r  c                 C   s<   t r	t | t j tj| jd rt| jd  dS 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   s@   t | t jt jB t jB d}zt| dW t | S t | w )zCCreate a file if it doesn't exist and open for reading and writing.r   r  )r   r   r   rV  O_RDWRrh   )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 dS )z0Ensure changes to file f are physically on disk.fsyncN)rb   r]   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  rh   r   r   r   r    r   T  s   r   c                   @   r  )r   z"Raised for module-specific errors.Nr  r   r   r   r    r   Z  r  r   c                   @   r  )r   z:The specified mailbox does not exist and won't be created.Nr  r   r   r   r    r   ]  r  r   c                   @   r  )r   z>The specified mailbox is not empty and deletion was requested.Nr  r   r   r   r    r   `  r  r   c                   @   r  )r   z)Another process caused an action to fail.Nr  r   r   r   r    r   c  r  r   c                   @   r  )r   z)A file appears to have an invalid format.Nr  r   r   r   r    r   f  r  r   )T)2r   r   r   r  r   r   r  r   rA   Zemail.messageZemail.generatorr{   r;   typesr   r  ImportError__all__r   ri   r   r   r  r3  r   r   r   r   r(   r	   r
   r?  r   r   r   r   r   r=  r  r  r  r   r  r   	Exceptionr   r   r   r   r   r   r   r   r    <module>   sp     j  8 DB4-  3 z%mqH_e
'*