
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3

  \ 3 ã               @   sR  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yddlZW n ek
rˆ   dZY nX ddddddd	d
dddddddddgZej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%d0d1„ Z&d2d3„ Z'd4d5„ Z(d6d7„ Z)G d8d„ de*ƒZ+G d9d„ de+ƒZ,G d:d„ de+ƒZ-G d;d„ de+ƒZ.G d<d„ de+ƒZ/dS )>zDRead/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.é    NÚ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#dS )Hr   z*A group of messages in a particular place.NTc             C   s    t jjt jj|ƒƒ| _|| _dS )zInitialize a Mailbox instance.N)ÚosÚpathÚabspathÚ
expanduserÚ_pathÚ_factory)Úselfr   ÚfactoryÚcreate© r   ú/usr/lib64/python3.6/mailbox.pyÚ__init__$   s    zMailbox.__init__c             C   s   t dƒ‚dS )z$Add message and return assigned key.z&Method must be implemented by subclassN)ÚNotImplementedError)r   Úmessager   r   r   Úadd)   s    zMailbox.addc             C   s   t dƒ‚dS )z=Remove the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r    )r   Úkeyr   r   r   Úremove-   s    zMailbox.removec             C   s   | j |ƒ d S )N)r$   )r   r#   r   r   r   Ú__delitem__1   s    zMailbox.__delitem__c             C   s(   y| j |ƒ W n tk
r"   Y nX dS )z'If the keyed message exists, remove it.N)r$   ÚKeyError)r   r#   r   r   r   Údiscard4   s    zMailbox.discardc             C   s   t dƒ‚dS )z>Replace the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r    )r   r#   r!   r   r   r   Ú__setitem__;   s    zMailbox.__setitem__c             C   s$   y
| j |ƒS  tk
r   |S X dS )z9Return the keyed message, or default if it doesn't exist.N)Ú__getitem__r&   )r   r#   Údefaultr   r   r   Úget?   s    
zMailbox.getc          	   C   s6   | j s| j|ƒS tj| j|ƒƒ�}| j |ƒS Q R X 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   r)   F   s    
zMailbox.__getitem__c             C   s   t dƒ‚dS )z4Return a Message representation or raise a KeyError.z&Method must be implemented by subclassN)r    )r   r#   r   r   r   r,   N   s    zMailbox.get_messagec             C   s   t j| j|ƒƒjƒ S )zœReturn 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_bytesÚ	as_string)r   r#   r   r   r   Ú
get_stringR   s    zMailbox.get_stringc             C   s   t dƒ‚dS )z8Return a byte string representation or raise a KeyError.z&Method must be implemented by subclassN)r    )r   r#   r   r   r   r3   Y   s    zMailbox.get_bytesc             C   s   t dƒ‚dS )z6Return a file-like representation or raise a KeyError.z&Method must be implemented by subclassN)r    )r   r#   r   r   r   r/   ]   s    zMailbox.get_filec             C   s   t dƒ‚dS )zReturn an iterator over keys.z&Method must be implemented by subclassN)r    )r   r   r   r   Úiterkeysa   s    zMailbox.iterkeysc             C   s   t | jƒ ƒS )zReturn a list of keys.)Úlistr6   )r   r   r   r   Úkeyse   s    zMailbox.keysc             c   s@   x:| j ƒ D ].}y| | }W n tk
r0   w
Y nX |V  q
W dS )z%Return an iterator over all messages.N)r6   r&   )r   r#   Úvaluer   r   r   Ú
itervaluesi   s    zMailbox.itervaluesc             C   s   | j ƒ S )N)r:   )r   r   r   r   Ú__iter__r   s    zMailbox.__iter__c             C   s   t | jƒ ƒS )z,Return a list of messages. Memory intensive.)r7   r:   )r   r   r   r   Úvaluesu   s    zMailbox.valuesc             c   sD   x>| j ƒ D ]2}y| | }W n tk
r0   w
Y nX ||fV  q
W dS )z.Return an iterator over (key, message) tuples.N)r6   r&   )r   r#   r9   r   r   r   Ú	iteritemsy   s    zMailbox.iteritemsc             C   s   t | jƒ ƒS )z9Return a list of (key, message) tuples. Memory intensive.)r7   r=   )r   r   r   r   Úitems‚   s    zMailbox.itemsc             C   s   t dƒ‚dS )z9Return True if the keyed message exists, False otherwise.z&Method must be implemented by subclassN)r    )r   r#   r   r   r   Ú__contains__†   s    zMailbox.__contains__c             C   s   t dƒ‚dS )z*Return a count of messages in the mailbox.z&Method must be implemented by subclassN)r    )r   r   r   r   Ú__len__Š   s    zMailbox.__len__c             C   s    x| j ƒ D ]}| j|ƒ q
W dS )zDelete all messages.N)r8   r'   )r   r#   r   r   r   ÚclearŽ   s    zMailbox.clearc             C   s0   y| | }W n t k
r    |S X | j|ƒ |S )z3Delete the keyed message and return it, or default.)r&   r'   )r   r#   r*   Úresultr   r   r   Úpop“   s    
zMailbox.popc             C   s*   x$| j ƒ D ]}|| j|ƒfS W tdƒ‚dS )z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)r6   rC   r&   )r   r#   r   r   r   Úpopitemœ   s    zMailbox.popitemc             C   sx   t |dƒr|jƒ }nt |dƒr(|jƒ }n|}d}x6|D ].\}}y|| |< W q6 tk
rb   d}Y q6X q6W |rttdƒ‚dS )z4Change the messages that correspond to certain keys.r=   r>   FTzNo message with key(s)N)Úhasattrr=   r>   r&   )r   ÚargÚsourceZbad_keyr#   r!   r   r   r   Úupdate£   s    



zMailbox.updatec             C   s   t dƒ‚dS )z&Write any pending changes to the disk.z&Method must be implemented by subclassN)r    )r   r   r   r   Úflush´   s    zMailbox.flushc             C   s   t dƒ‚dS )zLock the mailbox.z&Method must be implemented by subclassN)r    )r   r   r   r   Úlock¸   s    zMailbox.lockc             C   s   t dƒ‚dS )z#Unlock the mailbox if it is locked.z&Method must be implemented by subclassN)r    )r   r   r   r   Úunlock¼   s    zMailbox.unlockc             C   s   t dƒ‚dS )zFlush and close the mailbox.z&Method must be implemented by subclassN)r    )r   r   r   r   ÚcloseÀ   s    zMailbox.closec             C   s,   y
|j dƒS  tk
r&   tdƒ‚Y nX d S )Nr   z?String input must be ASCII-only; use bytes or a Message instead)ÚencodeÚUnicodeErrorÚ
ValueError)r   r!   r   r   r   Ú_string_to_bytesÄ   s    
zMailbox._string_to_bytesFc       	      C   s  t |tjjƒrxtjƒ }tjj||dƒ}|j|ƒ |j	dƒ |j
ƒ }|jdtƒ}|j|ƒ | jrt|jtƒ rt|jtƒ �n†t |tttjfƒ�rt |tjƒr®tjdtdƒ |jƒ }t |tƒrÂ| j|ƒ}|rÒ|jddƒ}|jdtƒ}|j|ƒ | joø|jtƒ �rþ|jtƒ nöt|dƒ�rît|dƒ�r4tjd	tdƒ |j}d
}xŒ|jƒ }|jdƒ�r`|d
d… d }n|jdƒ�r||d
d… d }|�s„P |�r¦|jdƒ�r¦d|dd
…  }|jdtƒ}|j|ƒ |}�q:W | j�rþ|�rþ|jtƒ �rþ|jtƒ ntdt|ƒ ƒ‚d
S )z%Dump message contents to target file.r   ó   
z8Use of StringIO input is deprecated, use BytesIO insteadé   s   
From s   
>From ÚreadÚbufferzDUse of text mode files is deprecated, use a binary mode file insteadNs   
é   ó   é   s   From s   >From é   zInvalid message type: %séþÿÿÿéÿÿÿÿ)Ú
isinstancer1   r!   r   ÚioÚBytesIOÚ	generatorÚBytesGeneratorÚflattenÚseekrS   ÚreplaceÚlinesepÚwriteÚ_append_newlineÚendswithÚstrÚbytesÚStringIOÚwarningsÚwarnÚDeprecationWarningÚgetvaluerP   rE   rT   ÚreadlineÚ
startswithÚ	TypeErrorÚtype)	r   r!   ÚtargetZmangle_from_rT   ÚgenÚdataZlastlineÚliner   r   r   Ú_dump_messageÑ   sZ    







zMailbox._dump_message)NT)N)N)N)F)$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r"   r$   r%   r'   r(   r+   r)   r,   r5   r3   r/   r6   r8   r:   r;   r<   r=   r>   r?   r@   rA   rC   rD   rH   rI   rJ   rK   rL   rP   re   rv   r   r   r   r   r   !   sB   

		
	
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 j| |||ƒ tjj| jdƒtjj| jdƒtjj| jdƒdœ| _tjj| jƒsŽ|r„tj| jdƒ x*| jj	ƒ D ]}tj|dƒ qnW n
t
| jƒ‚i | _dddœ| _d| _d| _d	S )
zInitialize a Maildir instance.ÚtmpÚnewÚcur)r|   r}   r~   iÀ  r   )r~   r}   gš™™™™™¹?N)r   r   r   r   Újoinr   Ú_pathsÚexistsÚmkdirr<   r   Ú_tocÚ_toc_mtimesÚ
_last_readÚ_skewfactor)r   Údirnamer   r   r   r   r   r   r     s    
zMaildir.__init__c             C   s~  | j ƒ }y| j||ƒ W n* tk
rB   |jƒ  tj|jƒ ‚ Y nX t|ƒ t|t	ƒr||j
ƒ }| j|jƒ  }|| jkr„d}nd}d}tjj|jƒj| jƒd }tjj| j||| ƒ}t|t	ƒrÞtj|jtjj|jƒ|jƒ fƒ yLytj|j|ƒ W n( ttfk
�r   tj|j|ƒ Y nX tj|jƒ W nN tk
�rx } z0tj|jƒ |jtjk�rftd| ƒ‚n‚ W Y dd}~X nX |S )z$Add message and return assigned key.Ú r}   r   z$Name clash with existing message: %sN)Ú_create_tmprv   ÚBaseExceptionrL   r   r$   ÚnameÚ_sync_closer[   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"   !  sB    



zMaildir.addc             C   s    t jt jj| j| j|ƒƒƒ dS )z=Remove the keyed message; raise KeyError if it doesn't exist.N)r   r$   r   r   r   Ú_lookup)r   r#   r   r   r   r$   K  s    zMaildir.removec             C   s,   y| j |ƒ W n ttfk
r&   Y nX dS )z'If the keyed message exists, remove it.N)r$   r&   ÚFileNotFoundError)r   r#   r   r   r   r'   O  s    zMaildir.discardc             C   sÊ   | j |ƒ}| j|ƒ}| j |ƒ}t|tƒr.|}n|}tjj|ƒ}| j|kr`| j|j| jƒd  }nd}| j	|ƒ tjj
| j|ƒ}	tjj
| j||| ƒ}
t|tƒrºtj|	tjj|	ƒ|jƒ fƒ tj|	|
ƒ dS )z>Replace the keyed message; raise KeyError if it doesn't exist.rW   rˆ   NrZ   )r    r"   r[   r	   r   r   r‡   rŽ   r‘   r'   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   r(   W  s"    






zMaildir.__setitem__c             C   s¢   | j |ƒ}ttjj| j|ƒdƒ� }| jr4| j|ƒ}nt|ƒ}W dQ R X tjj|ƒ\}}|j	|ƒ | j
|kr€|j|j| j
ƒd ƒ |jtjjtjj| j|ƒƒƒ |S )z4Return a Message representation or raise a KeyError.ÚrbNrW   rZ   )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,   r  s    


zMaildir.get_messagec          
   C   s8   t tjj| j| j|ƒƒdƒ�}|jƒ jtdƒS Q R X dS )z2Return a bytes representation or raise a KeyError.r£   rQ   N)	r¤   r   r   r   r   r    rS   rb   rc   )r   r#   r©   r   r   r   r3   �  s    zMaildir.get_bytesc             C   s$   t tjj| j| j|ƒƒdƒ}t|ƒS )z6Return a file-like representation or raise a KeyError.r£   )r¤   r   r   r   r   r    Ú
_ProxyFile)r   r#   r©   r   r   r   r/   †  s    zMaildir.get_filec             c   sH   | j ƒ  x:| jD ]0}y| j|ƒ W n tk
r8   wY nX |V  qW dS )zReturn an iterator over keys.N)Ú_refreshrƒ   r    r&   )r   r#   r   r   r   r6   ‹  s    zMaildir.iterkeysc             C   s   | j ƒ  || jkS )z9Return True if the keyed message exists, False otherwise.)r¬   rƒ   )r   r#   r   r   r   r?   •  s    zMaildir.__contains__c             C   s   | j ƒ  t| jƒS )z*Return a count of messages in the mailbox.)r¬   Úlenrƒ   )r   r   r   r   r@   š  s    zMaildir.__len__c             C   s   dS )z"Write any pending changes to disk.Nr   )r   r   r   r   rI   Ÿ  s    zMaildir.flushc             C   s   dS )zLock the mailbox.Nr   )r   r   r   r   rJ   ¥  s    zMaildir.lockc             C   s   dS )z#Unlock the mailbox if it is locked.Nr   )r   r   r   r   rK   ©  s    zMaildir.unlockc             C   s   dS )zFlush and close the mailbox.Nr   )r   r   r   r   rL   ­  s    zMaildir.closec             C   s`   g }xVt j| jƒD ]F}t|ƒdkr|d dkrt jjt jj| j|ƒƒr|j|dd… ƒ qW |S )zReturn a list of folder names.rW   r   Ú.N)r   Úlistdirr   r­   r   Úisdirr   Úappend)r   rB   Úentryr   r   r   Úlist_folders±  s    zMaildir.list_foldersc             C   s    t tj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| jd| ƒ}t|| jd�}t jj|dƒ}t jj|ƒsXt jt j|t j	t j
B dƒƒ |S )z>Create a folder and return a Maildir instance representing it.r®   )r   Zmaildirfolderi¶  )r   r   r   r   r   r   r�   rL   r¤   ÚO_CREATÚO_WRONLY)r   r´   r   rB   Zmaildirfolder_pathr   r   r   Ú
add_folderÀ  s    zMaildir.add_folderc             C   s,  t jj| jd| ƒ}xTt jt jj|dƒƒt jt jj|dƒƒ D ](}t|ƒdk sZ|d dkr>td| ƒ‚q>W xPt j|ƒD ]B}|dkrv|dkrv|dkrvt jjt jj||ƒƒrvtd||f ƒ‚qvW x`t j|d	d
�D ]N\}}}x |D ]}t j	t jj||ƒƒ qÜW x |D ]}t j
t jj||ƒƒ qþW qÌW t j
|ƒ dS )z-Delete the named folder, which must be empty.r®   r}   r~   rW   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   s\   t j ƒ }xNtjtjj| jdƒƒD ]4}tjj| jd|ƒ}|tjj|ƒ dkr tj|ƒ q W 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.cleanrW   c             C   sÒ   t j ƒ }tjƒ }d|kr$|jddƒ}d|kr8|jddƒ}dt|ƒt|d d ƒtjƒ tj|f }tj	j
| jd|ƒ}ytj|ƒ W n@ tk
rÀ   t jd7  _yt|ƒS  tk
rº   Y nX Y nX 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.%srW   g    €„.Ar|   z&Name clash prevented file creation: %sN)rÀ   ÚsocketÚgethostnamerb   Úintr   Úgetpidr   Ú_countr   r   r   Ústatr¡   Ú_create_carefullyÚFileExistsErrorr   )r   rÁ   Zhostnamer�   r   r   r   r   r‰   ç  s&    zMaildir._create_tmpc             C   sä   t j ƒ | j d| j krbd}x<| jD ]2}tjj| j| ƒ}|| j| krLd}|| j|< q$W |sbdS i | _xl| jD ]b}| j| }xRtj	|ƒD ]D}tjj
||ƒ}tjj|ƒrªqŠ|j| jƒd }tjj
||ƒ| j|< qŠW qpW t j ƒ | _dS )z!Update table of contents mapping.rU   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   sz   y,t jjt jj| j| j| ƒƒr*| j| S W n tk
r@   Y nX | jƒ  y
| j| S  tk
rt   td| ƒ‚Y nX dS )z=Use TOC to return subpath for given key, or raise a KeyError.zNo message with key: %sN)r   r   r�   r   r   rƒ   r&   r¬   )r   r#   r   r   r   r    #  s    
zMaildir._lookupc             C   sV   t | dƒs| jƒ | _x<y| t| jƒ S  tk
r8   dS  tk
rL   wY qX qW dS )z0Return the next message in a one-time iteration.Ú_onetime_keysN)rE   r6   rÎ   ÚnextÚStopIterationr&   )r   r   r   r   rÏ   1  s    

zMaildir.next)NT)rw   rx   ry   rz   rŽ   r   r"   r$   r'   r(   r,   r3   r/   r6   r?   r@   rI   rJ   rK   rL   r³   rµ   r¸   r¿   rÂ   rÈ   r‰   r¬   r    rÏ   r   r   r   r   r     s6   
*
	
$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 j| |||ƒ yt| jdƒ}W nn tk
rŽ } zR|jtjkr\|rPt| jdƒ}q~t| jƒ‚n"|jtjtj	fkr|t| jdƒ}n‚ W Y dd}~X nX || _
d| _d| _d| _d| _d| _d| _dS )z!Initialize a single-file mailbox.z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   A  s$    z_singlefileMailbox.__init__c             C   s8   | j ƒ  | j|ƒ| j| j< |  jd7  _d| _| jd S )z$Add message and return assigned key.rW   T)r    Ú_append_messagerƒ   rÖ   rØ   )r   r!   r   r   r   r"   X  s
    z_singlefileMailbox.addc             C   s   | j |ƒ | j|= d| _dS )z=Remove the keyed message; raise KeyError if it doesn't exist.TN)r    rƒ   r×   )r   r#   r   r   r   r$   b  s    
z_singlefileMailbox.removec             C   s$   | j |ƒ | j|ƒ| j|< d| _dS )z>Replace the keyed message; raise KeyError if it doesn't exist.TN)r    rÛ   rƒ   r×   )r   r#   r!   r   r   r   r(   h  s    
z_singlefileMailbox.__setitem__c             c   s   | j ƒ  | jjƒ E dH  dS )zReturn an iterator over keys.N)r    rƒ   r8   )r   r   r   r   r6   n  s    z_singlefileMailbox.iterkeysc             C   s   | j ƒ  || jkS )z9Return True if the keyed message exists, False otherwise.)r    rƒ   )r   r#   r   r   r   r?   s  s    z_singlefileMailbox.__contains__c             C   s   | j ƒ  t| jƒS )z*Return a count of messages in the mailbox.)r    r­   rƒ   )r   r   r   r   r@   x  s    z_singlefileMailbox.__len__c             C   s   | j st| jƒ d| _ dS )zLock the mailbox.TN)rÙ   Ú
_lock_filerÕ   )r   r   r   r   rJ   }  s    
z_singlefileMailbox.lockc             C   s   | j rt| jƒ d| _ dS )z#Unlock the mailbox if it is locked.FN)rÙ   Ú_unlock_filerÕ   )r   r   r   r   rK   ƒ  s    
z_singlefileMailbox.unlockc       
      C   sì  | j s | jrt| jƒ d| _dS | jdk	s.t‚| jjddƒ | jjƒ }|| jkrbt	d| j|f ƒ‚t
| jƒ}y¬i }| j|ƒ xŽt| jjƒ ƒD ]|}| j| \}}| jj|ƒ | j|ƒ |jƒ }x0| jjtd|| jjƒ  ƒƒ}|sàP |j|ƒ q¾W ||jƒ f||< | j|ƒ qŒW |jƒ | _W n"   |jƒ  tj|jƒ ‚ Y nX t|ƒ | jjƒ  tj| jƒj}	tj|j|	ƒ ytj|j| jƒ W n2 tk
�r°   tj| jƒ tj|j| jƒ Y nX t| jdƒ| _|| _d| _ d| _| j�rèt | jdd� dS )	z"Write any pending changes to disk.FNr   rU   z4Size of mailbox file changed (expected %i, found %i)i   zrb+)Údotlock)!r×   rØ   Ú_sync_flushrÕ   rƒ   ÚAssertionErrorra   ÚtellrÚ   r   Ú_create_temporaryr   Ú_pre_mailbox_hookÚsortedr8   Ú_pre_message_hookrS   Úminrd   Ú_post_message_hookrL   r   r$   r‹   rŒ   rÉ   Úst_modeÚchmodr˜   rË   r¤   rÙ   rÜ   )
r   Zcur_lenZnew_fileZnew_tocr#   ÚstartÚstopZ	new_startrT   Úmoder   r   r   rI   ‰  s`    







z_singlefileMailbox.flushc             C   s   dS )z,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 )z-Called before writing each message to file f.Nr   )r   r©   r   r   r   rå   Í  s    z$_singlefileMailbox._pre_message_hookc             C   s   dS )z,Called after writing each message to file f.Nr   )r   r©   r   r   r   rç   Ñ  s    z%_singlefileMailbox._post_message_hookc             C   s4   z| j ƒ  W dz| jr| jƒ  W d| jjƒ  X X dS )zFlush and close the mailbox.N)rI   rÙ   rK   rÕ   rL   )r   r   r   r   rL   Õ  s    z_singlefileMailbox.closec             C   sJ   | j dkr| jƒ  |dk	rFy
| j | S  tk
rD   td| ƒ‚Y nX dS )z'Return (start, stop) or raise KeyError.NzNo message with key: %s)rƒ   Ú_generate_tocr&   )r   r#   r   r   r   r    à  s    

z_singlefileMailbox._lookupc             C   sž   | j jddƒ | j jƒ }t| jƒdkr:| j r:| j| j ƒ y&| j| j ƒ | j|ƒ}| j	| j ƒ W n" t
k
r‚   | j j|ƒ ‚ Y nX | j jƒ  | j jƒ | _|S )z;Append message to mailbox and return (start, stop) offsets.r   rU   )rÕ   ra   rá   r­   rƒ   r×   rã   rå   Ú_install_messagerç   rŠ   ÚtruncaterI   rÚ   )r   r!   ZbeforeZoffsetsr   r   r   rÛ   ê  s    


z"_singlefileMailbox._append_message)NT)N)rw   rx   ry   rz   r   r"   r$   r(   r6   r?   r@   rJ   rK   rI   rã   rå   rç   rL   r    rÛ   r   r   r   r   rÑ   >  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j|ƒ | jjƒ jtdƒ}| jj|| jjƒ  ƒ}| j|jtdƒƒ}|j	|dd… j
dƒƒ |S )z4Return a Message representation or raise a KeyError.ó    rQ   rX   Nr   )r    rÕ   ra   rn   rb   rc   rS   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| j|ƒƒj|d�S )z3Return a string representation or raise a KeyError.)Úunixfrom)r1   r2   r3   r4   )r   r#   Úfrom_r   r   r   r5     s    z_mboxMMDF.get_stringc             C   sJ   | j |ƒ\}}| jj|ƒ |s(| jjƒ  | jj|| jjƒ  ƒ}|jtdƒS )z3Return a string representation or raise a KeyError.rQ   )r    rÕ   ra   rn   rS   rá   rb   rc   )r   r#   rø   rê   rë   rö   r   r   r   r3     s    
z_mboxMMDF.get_bytesc             C   s<   | j |ƒ\}}| jj|ƒ |s(| jjƒ  t| j| jjƒ |ƒS )z6Return a file-like representation or raise a KeyError.)r    rÕ   ra   rn   Ú_PartialFilerá   )r   r#   rø   rê   rë   r   r   r   r/     s
    
z_mboxMMDF.get_filec             C   s  d}t |tƒr| j|ƒ}t |tƒrf|jdƒrf|jdƒ}|dkr\|d|… }||d d… }q°|}d}nJt |tƒrˆ|jƒ jdƒ}d| }n(t |t	j
jƒr°|jƒ }|dk	r°|jdƒ}|dkrÎdtjtjƒ ƒjƒ  }| jjƒ }| jj|t ƒ | j|| j| jƒ | jjƒ }||fS )	z1Format a message and blindly write to self._file.Ns   From rQ   rW   rñ   r   s   From MAILER-DAEMON rZ   )r[   rg   rP   rh   ro   ÚfindÚ_mboxMMDFMessageÚget_fromrM   r1   r!   r   Úget_unixfromrÀ   ÚasctimeÚgmtimerÕ   rá   rd   rc   rv   Ú_mangle_from_)r   r!   rõ   ÚnewlineZauthorrê   rë   r   r   r   rî   &  s0    







z_mboxMMDF._install_messageN)F)F)F)
rw   rx   ry   rz   r   r,   r5   r3   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j| |||ƒ dS )zInitialize an mbox mailbox.N)r
   rò   rð   r   )r   r   r   r   r   r   r   r   L  s    zmbox.__init__c             C   s   |j tƒ dS )z,Called after writing each message to file f.N)rd   rc   )r   r©   r   r   r   rç   Q  s    zmbox._post_message_hookc             C   sì   g g  }}d}| j jdƒ x | j jƒ }| j jƒ }|jdƒr|t|ƒt|ƒk rl|rb|j|ttƒ ƒ n
|j|ƒ |j|ƒ d}q|s¦|r˜|j|ttƒ ƒ n
|j|ƒ P q|tkr´d}qd}qW tt	t
||ƒƒƒ| _t| jƒ| _| j jƒ | _dS )z0Generate key-to-(start, stop) table of contents.Fr   s   From TN)rÕ   ra   rá   rn   ro   r­   r±   rc   ÚdictÚ	enumerateÚziprƒ   rÖ   rÚ   )r   ÚstartsÚstopsZlast_was_emptyÚline_posru   r   r   r   rí   U  s0    






zmbox._generate_toc)NT)	rw   rx   ry   rz   r   re   r   rç   rí   r   r   r   r   r   C  s   
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j| |||ƒ dS )zInitialize an MMDF mailbox.N)r   rò   rð   r   )r   r   r   r   r   r   r   r   z  s    zMMDF.__init__c             C   s   |j dt ƒ dS )z-Called before writing each message to file f.s   N)rd   rc   )r   r©   r   r   r   rå     s    zMMDF._pre_message_hookc             C   s   |j td t ƒ dS )z,Called after writing each message to file f.s   N)rd   rc   )r   r©   r   r   r   rç   ƒ  s    zMMDF._post_message_hookc             C   sæ   g g  }}| j jdƒ d}xŒ|}| j jƒ }| j jƒ }|jdt ƒrž|j|ƒ xV|}| j jƒ }| j jƒ }|dt krˆ|j|ttƒ ƒ P qN|sN|j|ƒ P qNW q|sP qW tt	t
||ƒƒƒ| _t| jƒ| _| j jddƒ | j jƒ | _dS )z0Generate key-to-(start, stop) table of contents.r   s   rU   N)rÕ   ra   rn   rá   ro   rc   r±   r­   r  r  r  rƒ   rÖ   rÚ   )r   r  r  Únext_posr  ru   r   r   r   rí   ‡  s2    






zMMDF._generate_toc)NT)rw   rx   ry   rz   r   rå   rç   rí   r   r   r   r   r   w  s
   
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 j| |||ƒ tjj| jƒsj|r`tj| jdƒ tjtjtjj	| jdƒtj
tjB tjB dƒƒ n
t| jƒ‚d| _dS )zInitialize an MH instance.iÀ  z.mh_sequencesi€  FN)r   r   r   r   r�   r   r‚   rL   r¤   r   r¶   ÚO_EXCLr·   r   rÙ   )r   r   r   r   r   r   r   r   §  s    
zMH.__init__c             C   sä   | j ƒ }t|ƒdkrd}nt|ƒd }tjj| jt|ƒƒ}t|ƒ}d}zŠ| j	rVt
|ƒ zfy| j||ƒ W n: tk
r¢   | j	r†t|ƒ t|ƒ d}tj|ƒ ‚ Y nX t|tƒrº| j||ƒ W d| j	rÌt|ƒ X W d|sÞt|ƒ X |S )z$Add message and return assigned key.r   rW   FTN)r8   r­   Úmaxr   r   r   r   rg   rÊ   rÙ   rÜ   rv   rŠ   rÝ   rŒ   r$   r[   r   Ú_dump_sequences)r   r!   r8   Znew_keyr¢   r©   Úclosedr   r   r   r"   ³  s6    


zMH.addc             C   sx   t jj| jt|ƒƒ}yt|dƒ}W n> tk
r` } z"|jtjkrNt	d| ƒ‚n‚ W Y dd}~X nX |j
ƒ  t j|ƒ dS )z=Remove the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN)r   r   r   r   rg   r¤   r™   rš   rÒ   r&   rL   r$   )r   r#   r   r©   rŸ   r   r   r   r$   Õ  s    z	MH.removec             C   sÖ   t jj| jt|ƒƒ}yt|dƒ}W n> tk
r` } z"|jtjkrNt	d| ƒ‚n‚ W Y dd}~X nX zd| j
rrt|ƒ z@t jt j|t jt jB ƒƒ | j||ƒ t|tƒr°| j||ƒ W d| j
rÂt|ƒ X W dt|ƒ X dS )z>Replace the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN)r   r   r   r   rg   r¤   r™   rš   rÒ   r&   rÙ   rÜ   rL   r·   ÚO_TRUNCrv   r[   r   r  rÝ   rŒ   )r   r#   r!   r   r©   rŸ   r   r   r   r(   ã  s$    
zMH.__setitem__c              C   sì   y@| j r$ttjj| jt|ƒƒdƒ}nttjj| jt|ƒƒdƒ}W n> tk
r~ } z"|jtj	krlt
d| ƒ‚n‚ W Y dd}~X nX |�2 | j r”t|ƒ zt|ƒ}W d| j r°t|ƒ X W dQ R X x*| jƒ jƒ D ]\}}||krÊ|j|ƒ qÊW |S )z4Return a Message representation or raise a KeyError.zrb+r£   zNo message with key: %sN)rÙ   r¤   r   r   r   r   rg   r™   rš   rÒ   r&   rÜ   r   rÝ   Úget_sequencesr>   Úadd_sequence)r   r#   r©   rŸ   rª   r‹   Úkey_listr   r   r   r,   û  s&    zMH.get_messagec              C   sÄ   y@| j r$ttjj| jt|ƒƒdƒ}nttjj| jt|ƒƒdƒ}W n> tk
r~ } z"|jtj	krlt
d| ƒ‚n‚ W Y dd}~X nX |�6 | j r”t|ƒ z|jƒ jtdƒS | j r´t|ƒ X W dQ R X dS )z2Return a bytes representation or raise a KeyError.zrb+r£   zNo message with key: %sNrQ   )rÙ   r¤   r   r   r   r   rg   r™   rš   rÒ   r&   rÜ   rS   rb   rc   rÝ   )r   r#   r©   rŸ   r   r   r   r3     s    zMH.get_bytesc             C   sf   yt tjj| jt|ƒƒdƒ}W n> tk
r\ } z"|jtjkrJt	d| ƒ‚n‚ W Y dd}~X nX t
|ƒS )z6Return a file-like representation or raise a KeyError.r£   zNo message with key: %sN)r¤   r   r   r   r   rg   r™   rš   rÒ   r&   r«   )r   r#   r©   rŸ   r   r   r   r/   )  s    zMH.get_filec             C   s   t tdd„ tj| jƒD ƒƒƒS )zReturn an iterator over keys.c             s   s   | ]}|j ƒ rt|ƒV  qd S )N)ÚisdigitrÆ   )Ú.0r²   r   r   r   ú	<genexpr>6  s    zMH.iterkeys.<locals>.<genexpr>)Úiterrä   r   r¯   r   )r   r   r   r   r6   4  s    zMH.iterkeysc             C   s   t jjt jj| jt|ƒƒƒS )z9Return True if the keyed message exists, False otherwise.)r   r   r�   r   r   rg   )r   r#   r   r   r   r?   9  s    zMH.__contains__c             C   s   t t| jƒ ƒƒS )z*Return a count of messages in the mailbox.)r­   r7   r6   )r   r   r   r   r@   =  s    z
MH.__len__c             C   s2   | j s.ttjj| jdƒdƒ| _t| jƒ d| _ dS )zLock the mailbox.z.mh_sequenceszrb+TN)rÙ   r¤   r   r   r   r   rÕ   rÜ   )r   r   r   r   rJ   A  s    
zMH.lockc             C   s(   | j r$t| jƒ t| jƒ | `d| _ dS )z#Unlock the mailbox if it is locked.FN)rÙ   rÝ   rÕ   rŒ   )r   r   r   r   rK   H  s
    

z	MH.unlockc             C   s   dS )z&Write any pending changes to the disk.Nr   )r   r   r   r   rI   P  s    zMH.flushc             C   s   | j r| jƒ  dS )zFlush and close the mailbox.N)rÙ   rK   )r   r   r   r   rL   T  s    zMH.closec             C   s@   g }x6t j| jƒD ]&}t jjt jj| j|ƒƒr|j|ƒ qW |S )zReturn a list of folder names.)r   r¯   r   r   r°   r   r±   )r   rB   r²   r   r   r   r³   Y  s
    zMH.list_foldersc             C   s   t tjj| j|ƒ| jdd�S )z+Return an MH instance for the named folder.F)r   r   )r   r   r   r   r   r   )r   r´   r   r   r   rµ   a  s    zMH.get_folderc             C   s   t tjj| j|ƒ| jd�S )z:Create a folder and return an MH instance representing it.)r   )r   r   r   r   r   r   )r   r´   r   r   r   r¸   f  s    zMH.add_folderc             C   s`   t jj| j|ƒ}t j|ƒ}|dgkr:t jt jj|dƒƒ n|g krDntd| j ƒ‚t j|ƒ dS )z-Delete the named folder, which must be empty.z.mh_sequenceszFolder not empty: %sN)r   r   r   r   r¯   r$   r   r»   )r   r´   r   Zentriesr   r   r   r¿   k  s    

zMH.remove_folderc       
         s  i }t tjj| jdƒddd��ä}t| jƒ ƒ‰ xÐ|D ]È}yž|jdƒ\}}tƒ }xT|jƒ D ]H}|jƒ rr|j	t
|ƒƒ qVdd„ |jdƒD ƒ\}}	|jt||	d	 ƒƒ qVW ‡ fd
d„t|ƒD ƒ||< t|| ƒdkrÒ||= W q2 tk
rø   td|jƒ  ƒ‚Y q2X q2W W dQ R X |S )z=Return a name-to-key-list dictionary to define each sequence.z.mh_sequencesÚrÚASCII)Úencodingr{   c             s   s   | ]}t |ƒV  qd S )N)rÆ   )r  Úxr   r   r   r  „  s    z#MH.get_sequences.<locals>.<genexpr>ú-rW   c                s   g | ]}|ˆ kr|‘qS r   r   )r  r#   )Úall_keysr   r   ú
<listcomp>†  s    z$MH.get_sequences.<locals>.<listcomp>r   z"Invalid sequence specification: %sN)r¤   r   r   r   r   Úsetr8   r‘   r  r"   rÆ   rH   Úrangerä   r­   rO   r   Úrstrip)
r   Zresultsr©   ru   r‹   Úcontentsr8   Úspecrê   rë   r   )r  r   r  w  s&    

 zMH.get_sequencesc             C   s
  t tjj| jdƒddd�}zàtjtj |jtjtjB ƒƒ x¾|j	ƒ D ]²\}}t
|ƒdkrXqB|j|d ƒ d}d}xbtt|ƒƒD ]R}|d	 |kr |sÊd
}|jdƒ n*|r¼d}|jd||f ƒ n|jd| ƒ |}q|W |rê|jt|ƒd ƒ qB|jdƒ qBW W dt|ƒ X dS )z:Set sequences using the given name-to-key-list dictionary.z.mh_sequenceszr+r  )r  r   r{   NFrW   Tr  z%s %sz %sÚ
)r¤   r   r   r   r   rL   r‹   r·   r  r>   r­   rd   rä   r  rg   rŒ   )r   Ú	sequencesr©   r‹   r8   ÚprevZ
completingr#   r   r   r   Úset_sequences�  s.    zMH.set_sequencesc       	      C   sL  | j ƒ }d}g }xÎ| jƒ D ]Â}|d |krÔ|j||d fƒ y4tjtjj| jt|ƒƒtjj| jt|d ƒƒƒ W nH t	t
fk
r¸   tjtjj| jt|ƒƒtjj| jt|d ƒƒƒ Y nX tjtjj| jt|ƒƒƒ |d7 }qW |d | _t|ƒdkrúdS xB|jƒ D ]6\}}x*|D ]"\}}||k�r|||j|ƒ< �qW �qW | j|ƒ dS )z?Re-name messages to eliminate numbering gaps. Invalidates keys.r   rW   N)r  r6   r±   r   r•   r   r   r   rg   r–   r—   r˜   ÚunlinkrÖ   r­   r>   Úindexr$  )	r   r"  r#  Zchangesr#   r‹   r  Úoldr}   r   r   r   Úpack¬  s,     

zMH.packc             C   s|   |j ƒ }| j ƒ }x<|jƒ D ]0\}}||kr6|j|ƒ q||kr||j|ƒ= qW x|D ]}||krT|g||< qTW | j|ƒ dS )z;Inspect a new MHMessage and update sequences appropriately.N)r  r>   r±   r&  r$  )r   r!   r#   Zpending_sequencesZall_sequencesr‹   r  Úsequencer   r   r   r  Æ  s    
zMH._dump_sequences)NT)rw   rx   ry   rz   r   r"   r$   r(   r,   r3   r/   r6   r?   r@   rJ   rK   rI   rL   r³   rµ   r¸   r¿   r  r$  r(  r  r   r   r   r   r   ¤  s.   
"c               @   s�   e Zd ZdZedddddddhƒ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.ÚunseenÚdeletedZfiledÚansweredÚ	forwardedZeditedÚresentNTc             C   s   t j| |||ƒ i | _dS )zInitialize a Babyl mailbox.N)rÑ   r   Ú_labels)r   r   r   r   r   r   r   r   Û  s    zBabyl.__init__c             C   s(   t j| |ƒ}t|tƒr$|jƒ | j|< |S )z$Add message and return assigned key.)rÑ   r"   r[   r   Ú
get_labelsr/  )r   r!   r#   r   r   r   r"   à  s    
z	Babyl.addc             C   s"   t j| |ƒ || jkr| j|= dS )z=Remove the keyed message; raise KeyError if it doesn't exist.N)rÑ   r$   r/  )r   r#   r   r   r   r$   ç  s    
zBabyl.removec             C   s*   t j| ||ƒ t|tƒr&|jƒ | j|< dS )z>Replace the keyed message; raise KeyError if it doesn't exist.N)rÑ   r(   r[   r   r0  r/  )r   r#   r!   r   r   r   r(   í  s    
zBabyl.__setitem__c       
      C   s  | j |ƒ\}}| jj|ƒ | jjƒ  tjƒ }x4| jjƒ }|dt ksJ| rLP |j|jtdƒƒ q.W tjƒ }x0| jjƒ }|tks„| r†P |j|jtdƒƒ qlW || jj	ƒ  }|dks¶t
‚| jj|ƒ}|jtdƒ}t|jƒ | ƒ}	|	j|jƒ ƒ || jk�r|	j| j| ƒ |	S )z4Return a Message representation or raise a KeyError.s   *** EOOH ***rQ   r   )r    rÕ   ra   rn   r\   r]   rc   rd   rb   rá   rà   rS   r   rm   Úset_visibler/  Ú
set_labels)
r   r#   rê   rë   Úoriginal_headersru   Zvisible_headersÚnZbodyrª   r   r   r   r,   ó  s0    


zBabyl.get_messagec       	      C   sÄ   | j |ƒ\}}| jj|ƒ | jjƒ  tjƒ }x4| jjƒ }|dt ksJ| rLP |j|jtdƒƒ q.W x| jjƒ }|tks|| rdP qdW |j	ƒ }|| jj
ƒ  }|dks¤t‚| jj|ƒ}|jtdƒ}|| S )z3Return a string representation or raise a KeyError.s   *** EOOH ***rQ   r   )r    rÕ   ra   rn   r\   r]   rc   rd   rb   rm   rá   rà   rS   )	r   r#   rê   rë   r3  ru   Zheadersr4  rt   r   r   r   r3     s&    


zBabyl.get_bytesc             C   s   t j| j|ƒjdtƒƒS )z6Return a file-like representation or raise a KeyError.rQ   )r\   r]   r3   rb   rc   )r   r#   r   r   r   r/   %  s    zBabyl.get_filec             C   s@   | j ƒ  tƒ }x| jjƒ D ]}|j|ƒ qW |j| jƒ t|ƒS )z4Return a list of user-defined labels in the mailbox.)r    r  r/  r<   rH   Údifference_updateÚ_special_labelsr7   )r   ÚlabelsZ
label_listr   r   r   r0  )  s    zBabyl.get_labelsc             C   s>  g g  }}| j jdƒ d}g }xÒ|}| j jƒ }| j jƒ }|dt kržt|ƒt|ƒk rf|j|ttƒ ƒ |j|ƒ dd„ | j jƒ dd… jdƒD ƒ}|j|ƒ q |dks²|dt krÖt|ƒt|ƒk rî|j|ttƒ ƒ q |s |j|ttƒ ƒ P q W tt	t
||ƒƒƒ| _tt	|ƒƒ| _t| jƒ| _| j jdd	ƒ | j jƒ | _dS )
z0Generate key-to-(start, stop) table of contents.r   s   c             S   s   g | ]}|j ƒ r|j ƒ ‘qS r   )Ústrip)r  Úlabelr   r   r   r  @  s    z'Babyl._generate_toc.<locals>.<listcomp>rW   Nó   ,ó   rU   )rÕ   ra   rn   rá   rc   r­   r±   r‘   r  r  r  rƒ   r/  rÖ   rÚ   )r   r  r  r  Zlabel_listsr  ru   r7  r   r   r   rí   2  s4    



zBabyl._generate_tocc             C   sV   dt  }|dt  7 }| jƒ }dd„ |D ƒ}|ddj|ƒ t  7 }|d7 }|j|ƒ dS )	z,Called before writing the mailbox to file f.s   BABYL OPTIONS:s
   Version: 5c             s   s   | ]}|j ƒ V  qd S )N)rM   )r  r9  r   r   r   r  U  s    z*Babyl._pre_mailbox_hook.<locals>.<genexpr>s   Labels:r:  r;  N)rc   r0  r   rd   )r   r©   Zbabylr7  r   r   r   rã   P  s    zBabyl._pre_mailbox_hookc             C   s   |j dt ƒ dS )z-Called before writing each message to file f.ó   N)rd   rc   )r   r©   r   r   r   rå   Z  s    zBabyl._pre_message_hookc             C   s   |j td ƒ dS )z,Called after writing each message to file f.r;  N)rd   rc   )r   r©   r   r   r   rç   ^  s    zBabyl._post_message_hookc             C   sœ  | j jƒ }t|tƒr¼g }g }x0|jƒ D ]$}|| jkr@|j|ƒ q&|j|ƒ q&W | j jdƒ x |D ]}| j jd|jƒ  ƒ q`W | j jdƒ x$|D ]}| j jd|jƒ  d ƒ qŽW | j jt	ƒ n| j jdt	 ƒ t|t
jjƒ�r0tjƒ }t
jj|ddƒ}|j|ƒ |jdƒ x6|jƒ }| j j|jd	t	ƒƒ |d	k�s8| �r
P �q
W | j jd
t	 ƒ t|tƒ�r¼tjƒ }	t
jj|	ddƒ}
|
j|jƒ ƒ xz|	jƒ }| j j|jd	t	ƒƒ |d	k�s²| �r„P �q„W nB|jdƒ x6|jƒ }| j j|jd	t	ƒƒ |d	k�sö| �rÈP �qÈW x,|jdƒ}|�sP | j j|jd	t	ƒƒ �q W �nZt|tttjfƒ�r,t|tjƒ�rhtjdtdƒ |jƒ }t|tƒ�r~| j|ƒ}|jdƒd }|d dk�r | j j|d|… jd	t	ƒƒ | j jd
t	 ƒ | j j|d|… jd	t	ƒƒ | j j||d… jd	t	ƒƒ n(| j jd
t	 t	 ƒ | j j|jd	t	ƒƒ �n^t |dƒ�rzt |dƒ�rXtjdtdƒ |j!}|jƒ }d}x–|jƒ }|j"dƒ�rŒ|dd… d	 }n|j"dƒ�r¨|dd… d	 }| j j|jd	t	ƒƒ |d	k�sÎ| �rf|�rôd}| j jd
t	 ƒ |j|ƒ nP �qfW xŒ|jƒ }|�sP |j"dƒ�r,|dd… t	 }n:|j"dƒ�rJ|dd… t	 }n|j"d	ƒ�rf|dd… t	 }| j j|ƒ �qþW nt#dt$|ƒ ƒ‚| j jƒ }||fS )z0Write message contents and return (start, stop).ó   1s   , s   ,,ó    r:  s   1,,Fr   rQ   s   *** EOOH ***i   z8Use of StringIO input is deprecated, use BytesIO insteadrR   s   

rU   rW   Nrn   rT   zDUse of text mode files is deprecated, use a binary mode file insteadTs   
rV   zInvalid message type: %srZ   rY   rZ   rY   rZ   rZ   )%rÕ   rá   r[   r   r0  r6  r±   rd   rM   rc   r1   r!   r   r\   r]   r^   r_   r`   ra   rn   rb   Úget_visiblerS   rh   rg   ri   rj   rk   rl   rm   rP   rú   rE   rT   rf   rp   rq   )r   r!   rê   Zspecial_labelsr7  r9  Zorig_bufferZorig_generatorru   Z
vis_bufferZvis_generatorrT   Z
body_startZoriginal_posZ
first_passrë   r   r   r   rî   b  sÀ    











zBabyl._install_message)NT)rw   rx   ry   rz   Ú	frozensetr6  r   r"   r$   r(   r,   r3   r/   r0  rí   rã   rå   rç   rî   r   r   r   r   r   Õ  s    

	
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| jtj|ƒƒ t |tƒrÎ|j| ƒ nšt |tƒrP| jtj	|ƒƒ n~t |t
ƒrl| jtj|ƒƒ nbt |tjƒrŠ| jtj|ƒƒ nDt|dƒr¦| jtj|ƒƒ n(|dkr¾tjjj| ƒ ntdt|ƒ ƒ‚dS )zInitialize a Message instance.rS   NzInvalid message type: %s)r[   r1   r!   r   Ú_become_messageÚcopyÚdeepcopyÚ_explain_torh   r2   rg   Zmessage_from_stringr\   ÚTextIOWrapperZmessage_from_filerE   Zmessage_from_binary_filer   rp   rq   )r   r!   r   r   r   r   Ñ  s    



zMessage.__init__c             C   s8   t |dg ƒ}x&|jD ]}||kr|j| | j|< qW dS )z0Assume the non-format-specific state of message.Ú_type_specific_attributesN)ÚgetattrÚ__dict__)r   r!   Ztype_specificr‹   r   r   r   rA  ä  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)r[   r   rp   )r   r!   r   r   r   rD  ë  s    
zMessage._explain_to)N)rw   rx   ry   rz   r   rA  rD  r   r   r   r   r   Î  s   
c               @   s|   e Zd ZdZd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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jƒ | _tj| |ƒ dS )z%Initialize a MaildirMessage instance.r}   rˆ   N)rI  rJ  rÀ   rK  r   r   )r   r!   r   r   r   r   ø  s    
zMaildirMessage.__init__c             C   s   | j S )zReturn 'new' or 'cur'.)rI  )r   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)rI  rO   )r   r›   r   r   r   r¥     s    zMaildirMessage.set_subdirc             C   s"   | j jdƒr| j dd… S dS dS )z*Return as a string the flags that are set.z2,rU   Nrˆ   )rJ  ro   )r   r   r   r   Ú	get_flags
  s    zMaildirMessage.get_flagsc             C   s   ddj t|ƒƒ | _dS )z)Set the given flags and unset all others.z2,rˆ   N)r   rä   rJ  )r   Úflagsr   r   r   Ú	set_flags  s    zMaildirMessage.set_flagsc             C   s$   | j djt| jƒ ƒt|ƒB ƒƒ dS )z.Set the given flag(s) without changing others.rˆ   N)rN  r   r  rL  )r   Úflagr   r   r   Úadd_flag  s    zMaildirMessage.add_flagc             C   s,   | j ƒ r(| jdjt| j ƒ ƒt|ƒ ƒƒ dS )z7Unset the given string flag(s) without changing others.rˆ   N)rL  rN  r   r  )r   rO  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.)rK  )r   r   r   r   r”     s    zMaildirMessage.get_datec             C   s4   yt |ƒ| _W n  tk
r.   td| ƒ‚Y nX dS )z9Set delivery date of message, in seconds since the epoch.zcan't convert to float: %sN)ÚfloatrK  rO   rp   )r   Zdater   r   r   r§   "  s    zMaildirMessage.set_datec             C   s   | j S )z%Get the message's "info" as a string.)rJ  )r   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)r[   rg   rJ  rp   rq   )r   Úinfor   r   r   r¦   -  s    
zMaildirMessage.set_infoc             C   s¤  t |tƒr8|j| jƒ ƒ |j| jƒ ƒ |j| jƒ ƒ �nht |tƒrÄt	| jƒ ƒ}d|kr`|j
dƒ | jƒ dkrv|j
dƒ d|krˆ|j
dƒ d|krš|j
dƒ d|kr¬|j
dƒ |jd	tj| jƒ ƒƒ nÜt |tƒ�rt	| jƒ ƒ}d|krî|jd
ƒ d|k�r|jdƒ d|k�r |jdƒ nˆt |tƒ�r‚t	| jƒ ƒ}d|k�rD|jd
ƒ d|k�rX|jdƒ d|k�rl|jdƒ d|k�r |jdƒ nt |tƒ�r�ntdt|ƒ ƒ‚dS )z;Copy Maildir-specific state to message insofar as possible.ÚSÚRr~   ÚOÚTÚDÚFÚAzMAILER-DAEMONr*  ÚrepliedÚflaggedr+  r,  ÚPr-  z$Cannot convert to specified type: %sN)r[   r	   rN  rL  r¥   r�   r§   r”   rû   r  rP  ró   rÀ   rÿ   r   r  r   Ú	add_labelr   rp   rq   )r   r!   rM  r   r   r   rD  4  sN    

















zMaildirMessage._explain_to)N)rw   rx   ry   rz   rF  r   r�   r¥   rL  rN  rP  rQ  r”   r§   r�   r¦   rD  r   r   r   r   r	   ó  s   

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   | j ddƒ t|tjjƒrF|jƒ }|dk	rF|jdƒrF| j |dd… ƒ tj| |ƒ dS )z'Initialize an mboxMMDFMessage instance.zMAILER-DAEMONTNzFrom rX   )ró   r[   r1   r!   r   rý   ro   r   )r   r!   r÷   r   r   r   r   e  s    z_mboxMMDFMessage.__init__c             C   s   | j S )z Return contents of "From " line.)r_  )r   r   r   r   rü   n  s    z_mboxMMDFMessage.get_fromc             C   s4   |dk	r*|dkrt jƒ }|dt j|ƒ 7 }|| _dS )z>Set "From " line, formatting and appending time_ if specified.NTú )rÀ   rÿ   rþ   r_  )r   rø   Ztime_r   r   r   ró   r  s
    z_mboxMMDFMessage.set_fromc             C   s   | j ddƒ| j ddƒ S )z*Return as a string the flags that are set.ÚStatusrˆ   zX-Status)r+   )r   r   r   r   rL  z  s    z_mboxMMDFMessage.get_flagsc             C   sÚ   t |ƒ}d
\}}x&dD ]}||kr||7 }|j|ƒ qW x&dD ]}||kr>||7 }|j|ƒ q>W |djt|ƒƒ7 }y| jd|ƒ W n  tk
r¢   | jd|ƒ Y nX y| jd|ƒ W n  tk
rÔ   | jd|ƒ Y nX d	S )z)Set the given flags and unset all others.rˆ   rU  rV  rX  rY  rZ  ra  zX-StatusN)rˆ   rˆ   )rU  rV  )rX  rY  rZ  )r  r$   r   rä   Úreplace_headerr&   Z
add_header)r   rM  Zstatus_flagsZxstatus_flagsrO  r   r   r   rN  ~  s&    

z_mboxMMDFMessage.set_flagsc             C   s$   | j djt| jƒ ƒt|ƒB ƒƒ dS )z.Set the given flag(s) without changing others.rˆ   N)rN  r   r  rL  )r   rO  r   r   r   rP  ”  s    z_mboxMMDFMessage.add_flagc             C   s4   d| ksd| kr0| j djt| jƒ ƒt|ƒ ƒƒ dS )z7Unset the given string flag(s) without changing others.ra  zX-Statusrˆ   N)rN  r   r  rL  )r   rO  r   r   r   rQ  ˜  s    z_mboxMMDFMessage.remove_flagc             C   sÞ  t |tƒrÐt| jƒ ƒ}d|kr(|jdƒ d|kr:|jdƒ d|krL|jdƒ d|kr^|jdƒ d|krp|jdƒ |d	= |d
= dj| jƒ jƒ dd… ƒ}y|j	t
jtj|dƒƒƒ W n ttfk
rÊ   Y nX �n
t |tƒrø|j| jƒ ƒ |j| jƒ ƒ nât |tƒ�rZt| jƒ ƒ}d|k�r$|jdƒ d|k�r8|jdƒ d|k�rL|jdƒ |d	= |d
= n€t |tƒ�r¼t| jƒ ƒ}d|k�r†|jdƒ d|k�rš|jdƒ d|k�r®|jdƒ |d	= |d
= nt |tƒ�rÊntdt|ƒ ƒ‚dS )zACopy mbox- or MMDF-specific state to message insofar as possible.rV  r~   rY  rZ  rU  rT  rX  rW  Zstatuszx-statusr`  rX   Nz%a %b %d %H:%M:%S %Yr*  r[  r\  r+  r,  z$Cannot convert to specified type: %séûÿÿÿ)r[   r	   r  rL  r¥   rP  r   rü   r‘   r§   ÚcalendarZtimegmrÀ   ZstrptimerO   ÚOverflowErrorrû   rN  ró   r   r  r   r^  r   rp   rq   )r   r!   rM  Z
maybe_dater   r   r   rD  �  s^    



















z_mboxMMDFMessage._explain_to)N)N)rw   rx   ry   rz   rF  r   rü   ró   rL  rN  rP  rQ  rD  r   r   r   r   rû   `  s   
	
rû   c               @   s   e Zd ZdZdS )r
   z&Message with mbox-specific properties.N)rw   rx   ry   rz   r   r   r   r   r
   Ñ  s   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j| |ƒ dS )z!Initialize an MHMessage instance.N)rf  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)rf  )r   r   r   r   r  ß  s    zMHMessage.get_sequencesc             C   s   t |ƒ| _dS )z3Set the list of sequences that include the message.N)r7   rf  )r   r"  r   r   r   r$  ã  s    zMHMessage.set_sequencesc             C   s6   t |tƒr"|| jkr2| jj|ƒ ntdt|ƒ ƒ‚dS )z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)r[   rg   rf  r±   rp   rq   )r   r)  r   r   r   r  ç  s    

zMHMessage.add_sequencec             C   s*   y| j j|ƒ W n tk
r$   Y nX dS )zARemove sequence from the list of sequences including the message.N)rf  r$   rO   )r   r)  r   r   r   Úremove_sequenceï  s    zMHMessage.remove_sequencec             C   sJ  t |tƒrdt| jƒ ƒ}d|kr*|jdƒ n|jdƒ |jdƒ d|krP|jdƒ d|krb|jdƒ nât |tƒr¾t| jƒ ƒ}d|krŽ|jdƒ n
|jd	ƒ d|krª|jdƒ d|kr¼|jd
ƒ nˆt |tƒræx|| jƒ D ]}|j|ƒ qÒW n`t |t	ƒ�r(t| jƒ ƒ}d|k�r|j
dƒ d|k�rF|j
dƒ nt |tƒ�r6ntdt|ƒ ƒ‚dS )z6Copy MH-specific state to message insofar as possible.r*  r~   rT  r\  rY  r[  rU  ÚROrV  rZ  r,  z$Cannot convert to specified type: %sN)r[   r	   r  r  r¥   rP  rû   r   r  r   r^  r   rp   rq   )r   r!   r"  r)  r   r   r   rD  ö  s@    










zMHMessage._explain_to)N)rw   rx   ry   rz   rF  r   r  r$  r  rg  rD  r   r   r   r   r   Õ  s   
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j| |ƒ dS )z#Initialize a BabylMessage instance.N)r/  r   ri  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)r/  )r   r   r   r   r0  (  s    zBabylMessage.get_labelsc             C   s   t |ƒ| _dS )z&Set the list of labels on the message.N)r7   r/  )r   r7  r   r   r   r2  ,  s    zBabylMessage.set_labelsc             C   s6   t |tƒr"|| jkr2| jj|ƒ ntdt|ƒ ƒ‚dS )z+Add label to list of labels on the message.zlabel must be a string: %sN)r[   rg   r/  r±   rp   rq   )r   r9  r   r   r   r^  0  s    

zBabylMessage.add_labelc             C   s*   y| j j|ƒ W n tk
r$   Y nX dS )z4Remove label from the list of labels on the message.N)r/  r$   rO   )r   r9  r   r   r   Úremove_label8  s    zBabylMessage.remove_labelc             C   s
   t | jƒS )z3Return a Message representation of visible headers.)r   ri  )r   r   r   r   r?  ?  s    zBabylMessage.get_visiblec             C   s   t |ƒ| _dS )z2Set the Message representation of visible headers.N)r   ri  )r   Zvisibler   r   r   r1  C  s    zBabylMessage.set_visiblec             C   sj   x6| j jƒ D ](}|| kr,| j j|| | ƒ q| j |= qW x,dD ]$}|| kr>|| j kr>| | | j |< q>W dS )	z9Update and/or sensibly generate a set of visible headers.ÚDateÚFromúReply-ToÚToÚCCÚSubjectN)rk  rl  rm  rn  ro  rp  )ri  r8   rb  )r   Úheaderr   r   r   Úupdate_visibleG  s    
zBabylMessage.update_visiblec             C   sv  t |tƒr~t| jƒ ƒ}d|kr*|jdƒ n|jdƒ |jdƒ d|ksNd|krX|jdƒ d|krj|jdƒ d	|kr||jd
ƒ nôt |tƒrØt| jƒ ƒ}d|kr¨|jdƒ n
|jdƒ d	|krÄ|jdƒ d|krÖ|jdƒ nšt |tƒ�rt| jƒ ƒ}d|k�r|jdƒ d|k�rr|jdƒ nXt |t	ƒ�rT|j
| jƒ ƒ x<| jƒ D ]}|j|ƒ �q>W nt |tƒ�rbntdt|ƒ ƒ‚dS )z9Copy Babyl-specific state to message insofar as possible.r*  r~   rT  r-  r.  r]  r,  rU  r+  rW  rh  rV  rX  rZ  r[  z$Cannot convert to specified type: %sN)r[   r	   r  r0  r¥   rP  rû   r   r  r   r1  r?  r^  r   rp   rq   )r   r!   r7  r9  r   r   r   rD  R  sF    










zBabylMessage._explain_to)N)rw   rx   ry   rz   rF  r   r0  r2  r^  rj  r?  r1  rr  rD  r   r   r   r   r     s   
c               @   s   e Zd ZdZdS )r   z&Message with MMDF-specific properties.N)rw   rx   ry   rz   r   r   r   r   r   |  s   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dS ),r«   zA read-only wrapper of a file.Nc             C   s$   || _ |dkr|jƒ | _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jƒS )zRead bytes.)Ú_readrÕ   rS   )r   Úsizer   r   r   rS   ‹  s    z_ProxyFile.readc             C   s   | j || jjƒS )zRead bytes.)ru  rÕ   Úread1)r   rv  r   r   r   rw  �  s    z_ProxyFile.read1c             C   s   | j || jjƒS )zRead a line.)ru  rÕ   rn   )r   rv  r   r   r   rn   “  s    z_ProxyFile.readlinec             C   s>   g }x4| D ],}|j |ƒ |dk	r
|t|ƒ8 }|dkr
P q
W |S )zRead multiple lines.Nr   )r±   r­   )r   ÚsizehintrB   ru   r   r   r   Ú	readlines—  s    

z_ProxyFile.readlinesc             c   s    x| j ƒ }|sdS |V  qW dS )zIterate over lines.N)rn   )r   ru   r   r   r   r;   ¢  s
    z_ProxyFile.__iter__c             C   s   | j S )zReturn the position.)rs  )r   r   r   r   rá   ª  s    z_ProxyFile.tellr   c             C   s4   |dkr| j j| jƒ | j j||ƒ | j jƒ | _dS )zChange position.rW   N)rÕ   ra   rs  rá   )r   ÚoffsetÚwhencer   r   r   ra   ®  s    z_ProxyFile.seekc          
   C   s0   t | dƒr,zt | jdƒr"| jjƒ  W d| `X dS )zClose the file.rÕ   rL   N)rE   rÕ   rL   )r   r   r   r   rL   µ  s
    
z_ProxyFile.closec             C   s2   |dkrd}| j j| jƒ ||ƒ}| j jƒ | _|S )z"Read size bytes using read_method.NrW   rZ   )rÕ   ra   rs  rá   )r   rv  Úread_methodrB   r   r   r   ru  ¾  s    z_ProxyFile._readc             C   s   | S )z$Context management protocol support.r   )r   r   r   r   Ú	__enter__Ç  s    z_ProxyFile.__enter__c             G   s   | j ƒ  d S )N)rL   )r   Úexcr   r   r   Ú__exit__Ë  s    z_ProxyFile.__exit__c             C   s
   | j jƒ S )N)rÕ   Úreadable)r   r   r   r   r€  Î  s    z_ProxyFile.readablec             C   s
   | j jƒ S )N)rÕ   Úwritable)r   r   r   r   r�  Ñ  s    z_ProxyFile.writablec             C   s
   | j jƒ S )N)rÕ   Úseekable)r   r   r   r   r‚  Ô  s    z_ProxyFile.seekablec             C   s
   | j jƒ S )N)rÕ   rI   )r   r   r   r   rI   ×  s    z_ProxyFile.flushc             C   s&   t | dƒsdS t | jdƒsdS | jjS )NrÕ   Tr  F)rE   rÕ   r  )r   r   r   r   r  Ú  s
    
z_ProxyFile.closed)N)N)N)N)N)r   )rw   rx   ry   rz   r   rS   rw  rn   ry  r;   rá   ra   rL   ru  r}  r  r€  r�  r‚  rI   Úpropertyr  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 j| ||ƒ || _|| _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| ƒ| j S )z*Return the position with respect to start.)r«   rá   r„  )r   r   r   r   rá   ì  s    z_PartialFile.tellr   c             C   s<   |dkr| j | _d}n|dkr*| j| _d}tj| ||ƒ dS )z8Change position, possibly with respect to start or stop.r   rW   rU   N)r„  rs  r…  r«   ra   )r   rz  r{  r   r   r   ra   ð  s    z_PartialFile.seekc             C   sB   | j | j }|dkrdS |dks0|dk s0||kr4|}tj| ||ƒS )z;Read size bytes using read_method, honoring start and stop.r   rñ   N)r…  rs  r«   ru  )r   rv  r|  Z	remainingr   r   r   ru  ú  s    z_PartialFile._readc             C   s   t | dƒr| `d S )NrÕ   )rE   rÕ   )r   r   r   r   rL     s    
z_PartialFile.close)NN)r   )	rw   rx   ry   rz   r   rá   ra   ru  rL   r   r   r   r   rù   ã  s   


	rù   Tc          4   C   sž  d}�yZt rpyt j| t jt jB ƒ W nJ tk
rn } z.|jtjtjtjfkr\t	d| j
 ƒ‚n‚ W Y dd}~X nX |�r^yt| j
d ƒ}|jƒ  W n: tk
rÊ } z|jtjtjfkr¸dS ‚ W Y dd}~X nX y`ytj|j
| j
d ƒ d}W n2 ttfk
�r   tj|j
| j
d ƒ d}Y nX tj|j
ƒ W n0 tk
�r\   tj|j
ƒ t	d| j
 ƒ‚Y nX W n8   t �r|t j| t jƒ |�r’tj| j
d ƒ ‚ Y nX dS )z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNz.lockTzdot lock unavailable: %s)ÚfcntlÚlockfZLOCK_EXZLOCK_NBr™   rš   ZEAGAINrÓ   rÔ   r   r‹   râ   rL   r   r•   r–   r—   r˜   r%  rË   r$   ÚLOCK_UN)r©   rÞ   Zdotlock_donerŸ   Zpre_lockr   r   r   rÜ   
  sH    
rÜ   c             C   s8   t rt j| t jƒ tjj| jd ƒr4tj| jd ƒ dS )z*Unlock file f using lockf and dot locking.z.lockN)r†  r‡  rˆ  r   r   r�   r‹   r$   )r©   r   r   r   rÝ   4  s    rÝ   c             C   s8   t j| t jt jB t jB dƒ}z
t| dƒS t j|ƒ X dS )zCCreate a file if it doesn't exist and open for reading and writing.i¶  zrb+N)r   r¤   r¶   r	  ÚO_RDWRrL   )r   Úfdr   r   r   rÊ   ;  s    
rÊ   c             C   s$   t d| ttjƒ ƒtjƒ tjƒ 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â   C  s    râ   c             C   s$   | j ƒ  ttdƒr tj| jƒ ƒ dS )z0Ensure changes to file f are physically on disk.ÚfsyncN)rI   rE   r   r‹  Úfileno)r©   r   r   r   rß   I  s    
rß   c             C   s   t | ƒ | jƒ  dS )z:Close file f, ensuring all changes are physically on disk.N)rß   rL   )r©   r   r   r   rŒ   O  s    rŒ   c               @   s   e Zd ZdZdS )r   z"Raised for module-specific errors.N)rw   rx   ry   rz   r   r   r   r   r   U  s   c               @   s   e Zd ZdZdS )r   z:The specified mailbox does not exist and won't be created.N)rw   rx   ry   rz   r   r   r   r   r   X  s   c               @   s   e Zd ZdZdS )r   z>The specified mailbox is not empty and deletion was requested.N)rw   rx   ry   rz   r   r   r   r   r   [  s   c               @   s   e Zd ZdZdS )r   z)Another process caused an action to fail.N)rw   rx   ry   rz   r   r   r   r   r   ^  s   c               @   s   e Zd ZdZdS )r   z)A file appears to have an invalid format.N)rw   rx   ry   rz   r   r   r   r   r   a  s   )T)0rz   r   rÀ   rd  rÄ   rš   rB  rj   r1   Zemail.messageZemail.generatorr\   r-   r†  ÚImportErrorÚ__all__rc   rM   r   r   rÑ   rð   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   

 h  8 DB4-  3 z%mqH_c'
*