U
    ”¼pdE3 ã                   @   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z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 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 t j |¡¡| _|| _dS )zInitialize a Mailbox instance.N)ÚosÚpathÚabspathÚ
expanduserÚ_pathÚ_factory©Úselfr   ÚfactoryÚcreate© r   ú/usr/lib/python3.8/mailbox.pyÚ__init__$   s    zMailbox.__init__c                 C   s   t dƒ‚dS )ú$Add message and return assigned key.ú&Method must be implemented by subclassN©ÚNotImplementedError©r   Úmessager   r   r   Úadd)   s    zMailbox.addc                 C   s   t dƒ‚dS )ú=Remove the keyed message; raise KeyError if it doesn't exist.r"   Nr#   ©r   Úkeyr   r   r   Úremove-   s    zMailbox.removec                 C   s   |   |¡ d S ©N)r+   r)   r   r   r   Ú__delitem__1   s    zMailbox.__delitem__c                 C   s(   z|   |¡ W n tk
r"   Y nX dS ©z'If the keyed message exists, remove it.N)r+   ÚKeyErrorr)   r   r   r   Údiscard4   s    zMailbox.discardc                 C   s   t dƒ‚dS )ú>Replace the keyed message; raise KeyError if it doesn't exist.r"   Nr#   ©r   r*   r&   r   r   r   Ú__setitem__;   s    zMailbox.__setitem__c                 C   s*   z|   |¡W S  tk
r$   | Y 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   sB   | j s|  |¡S t |  |¡¡}|   |¡W  5 Q R £ 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   r4   F   s    
zMailbox.__getitem__c                 C   s   t dƒ‚dS )ú4Return a Message representation or raise a KeyError.r"   Nr#   r)   r   r   r   r7   N   s    zMailbox.get_messagec                 C   s   t  |  |¡¡ ¡ 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_bytesZ	as_stringr)   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.r"   Nr#   r)   r   r   r   r@   Y   s    zMailbox.get_bytesc                 C   s   t dƒ‚dS )ú6Return a file-like representation or raise a KeyError.r"   Nr#   r)   r   r   r   r:   ]   s    zMailbox.get_filec                 C   s   t dƒ‚dS )úReturn an iterator over keys.r"   Nr#   ©r   r   r   r   Úiterkeysa   s    zMailbox.iterkeysc                 C   s   t |  ¡ ƒS )zReturn a list of keys.)ÚlistrE   rD   r   r   r   Úkeyse   s    zMailbox.keysc              	   c   s>   |   ¡ D ]0}z| | }W n tk
r0   Y qY nX |V  qdS )z%Return an iterator over all messages.N©rE   r/   ©r   r*   Úvaluer   r   r   Ú
itervaluesi   s    
zMailbox.itervaluesc                 C   s   |   ¡ S r,   )rK   rD   r   r   r   Ú__iter__r   s    zMailbox.__iter__c                 C   s   t |  ¡ ƒS )z,Return a list of messages. Memory intensive.)rF   rK   rD   r   r   r   Úvaluesu   s    zMailbox.valuesc              	   c   sB   |   ¡ D ]4}z| | }W n tk
r0   Y qY nX ||fV  qdS )z.Return an iterator over (key, message) tuples.NrH   rI   r   r   r   Ú	iteritemsy   s    
zMailbox.iteritemsc                 C   s   t |  ¡ ƒS )z9Return a list of (key, message) tuples. Memory intensive.)rF   rN   rD   r   r   r   Úitems‚   s    zMailbox.itemsc                 C   s   t dƒ‚dS )ú9Return True if the keyed message exists, False otherwise.r"   Nr#   r)   r   r   r   Ú__contains__†   s    zMailbox.__contains__c                 C   s   t dƒ‚dS )ú*Return a count of messages in the mailbox.r"   Nr#   rD   r   r   r   Ú__len__Š   s    zMailbox.__len__c                 C   s   |   ¡ D ]}|  |¡ qdS )zDelete all messages.N)rG   r0   r)   r   r   r   ÚclearŽ   s    zMailbox.clearc                 C   s4   z| | }W n t k
r$   | Y S X |  |¡ |S )z3Delete the keyed message and return it, or default.)r/   r0   )r   r*   r5   Úresultr   r   r   Úpop“   s    

zMailbox.popc                 C   s*   |   ¡ D ]}||  |¡f  S tdƒ‚dS )z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)rE   rV   r/   r)   r   r   r   Úpopitemœ   s    zMailbox.popitemc              	   C   st   t |dƒr| ¡ }nt |dƒr(| ¡ }n|}d}|D ].\}}z|| |< W q4 tk
r`   d}Y q4X q4|rptdƒ‚dS )z4Change the messages that correspond to certain keys.rN   rO   FTzNo message with key(s)N)ÚhasattrrN   rO   r/   )r   ÚargÚsourceZbad_keyr*   r&   r   r   r   Úupdate£   s    



zMailbox.updatec                 C   s   t dƒ‚dS )ú&Write any pending changes to the disk.r"   Nr#   rD   r   r   r   Úflush´   s    zMailbox.flushc                 C   s   t dƒ‚dS )úLock the mailbox.r"   Nr#   rD   r   r   r   Úlock¸   s    zMailbox.lockc                 C   s   t dƒ‚dS )ú#Unlock the mailbox if it is locked.r"   Nr#   rD   r   r   r   Úunlock¼   s    zMailbox.unlockc                 C   s   t dƒ‚dS )úFlush and close the mailbox.r"   Nr#   rD   r   r   r   ÚcloseÀ   s    zMailbox.closec                 C   s.   z|  d¡W 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Ú
ValueErrorr%   r   r   r   Ú_string_to_bytesÄ   s    zMailbox._string_to_bytesFc           	      C   sü  t |tjjƒrvt ¡ }tj ||d¡}| |¡ | 	d¡ | 
¡ }| dt¡}| |¡ | jrr| t¡sr| t¡ n‚t |tttjfƒrt |tjƒr¬t dtd¡ | ¡ }t |tƒrÀ|  |¡}|rÐ| dd¡}| dt¡}| |¡ | jrø| t¡sø| t¡ nòt|dƒrèt|dƒr2t d	td¡ |j}d
}| ¡ }| d¡r\|d
d… d }n| d¡rx|d
d… d }|s‚qÂ|r¤| d¡r¤d|dd
…  }| dt¡}| |¡ |}q6| jrø|rø| t¡sø| t¡ ntdt|ƒ ƒ‚d
S )z%Dump message contents to target file.r   ó   
ú8Use of StringIO input is deprecated, use BytesIO insteadé   s   
From s   
>From ÚreadÚbufferúDUse of text mode files is deprecated, use a binary mode file insteadNó   
éþÿÿÿó   éÿÿÿÿó   From s   >From é   úInvalid message type: %s)Ú
isinstancer>   r&   r   ÚioÚBytesIOÚ	generatorÚBytesGeneratorÚflattenÚseekrk   ÚreplaceÚlinesepÚwriteÚ_append_newlineÚendswithÚstrÚbytesÚStringIOÚwarningsÚwarnÚDeprecationWarningÚgetvaluerg   rX   rl   ÚreadlineÚ
startswithÚ	TypeErrorÚtype)	r   r&   ÚtargetZmangle_from_rl   ÚgenÚdataZlastlineÚliner   r   r   Ú_dump_messageÑ   s`    


 ÿ


 ÿ
zMailbox._dump_message)NT)N)N)N)F)$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r'   r+   r-   r0   r3   r6   r4   r7   rA   r@   r:   rE   rG   rK   rL   rM   rN   rO   rQ   rS   rT   rV   rW   r[   r]   r_   ra   rc   rg   r   r   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  | |||¡ tj | jd¡tj | jd¡tj | jd¡dœ| _tj | j¡sŠ|r€t | jd¡ | j 	¡ D ]}t |d¡ qln
t
| jƒ‚i | _dddœ| _d| _d| _d	S )
zInitialize a Maildir instance.ÚtmpÚnewÚcur)r–   r—   r˜   éÀ  r   )r˜   r—   gš™™™™™¹?N)r   r    r   r   Újoinr   Ú_pathsÚexistsÚmkdirrM   r   Ú_tocÚ_toc_mtimesÚ
_last_readÚ_skewfactor)r   Údirnamer   r   r   r   r   r   r      s    ý
zMaildir.__init__c              
   C   s~  |   ¡ }z|  ||¡ W n* tk
rB   | ¡  t |j¡ ‚ Y nX t|ƒ t|t	ƒr|| 
¡ }| j| ¡  }|| jkr„d}nd}d}tj |j¡ | j¡d }tj | j||| ¡}t|t	ƒrÞt |jtj |j¡| ¡ f¡ zLzt |j|¡ W n( ttfk
r   t |j|¡ Y nX t |j¡ W nN tk
rx } z.t |j¡ |jtjkrftd| ƒ‚n‚ W 5 d}~X Y nX |S )r!   Ú r—   r   z$Name clash with existing message: %sN)Ú_create_tmpr   ÚBaseExceptionrc   r   r+   ÚnameÚ_sync_closeru   r	   Ú
get_subdirÚcolonÚget_infor   ÚbasenameÚsplitrš   r   ÚutimeÚgetatimeÚget_dateÚlinkÚAttributeErrorÚPermissionErrorÚrenameÚOSErrorÚerrnoZEEXISTr   )r   r&   Ztmp_fileÚsubdirÚsuffixÚuniqÚdestÚer   r   r   r'   !  sF    


ÿÿzMaildir.addc                 C   s    t  t j | j|  |¡¡¡ dS ©r(   N)r   r+   r   rš   r   Ú_lookupr)   r   r   r   r+   K  s    zMaildir.removec              	   C   s,   z|   |¡ W n ttfk
r&   Y nX dS r.   )r+   r/   ÚFileNotFoundErrorr)   r   r   r   r0   O  s    zMaildir.discardc                 C   sÊ   |   |¡}|  |¡}|   |¡}t|tƒr.|}n|}tj |¡}| j|kr`| j| | j¡d  }nd}|  	|¡ tj 
| j|¡}	tj 
| j||| ¡}
t|tƒrºt |	tj |	¡| ¡ f¡ t |	|
¡ dS )r1   rq   r£   N)r¼   r'   ru   r	   r   r   r¢   r©   r¬   r0   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   r3   W  s$    






ÿzMaildir.__setitem__c              	   C   s¢   |   |¡}ttj | j|¡dƒ }| jr4|  |¡}nt|ƒ}W 5 Q R X tj |¡\}}| 	|¡ | j
|kr€| | | j
¡d ¡ | tj tj | j|¡¡¡ |S )r<   Úrbrq   )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   r7   r  s    


zMaildir.get_messagec              
   C   sD   t tj | j|  |¡¡dƒ}| ¡  td¡W  5 Q R £ S Q R X dS )ú2Return a bytes representation or raise a KeyError.r¿   rh   N)	rÀ   r   r   rš   r   r¼   rk   r|   r}   ©r   r*   rÅ   r   r   r   r@     s    zMaildir.get_bytesc                 C   s$   t tj | j|  |¡¡dƒ}t|ƒS )rB   r¿   )rÀ   r   r   rš   r   r¼   Ú
_ProxyFilerÈ   r   r   r   r:   †  s    zMaildir.get_filec              	   c   sF   |   ¡  | jD ]2}z|  |¡ W n tk
r8   Y qY nX |V  qdS ©rC   N)Ú_refreshrž   r¼   r/   r)   r   r   r   rE   ‹  s    

zMaildir.iterkeysc                 C   s   |   ¡  || jkS ©rP   )rË   rž   r)   r   r   r   rQ   •  s    zMaildir.__contains__c                 C   s   |   ¡  t| jƒS ©rR   )rË   Úlenrž   rD   r   r   r   rS   š  s    zMaildir.__len__c                 C   s   dS )ú"Write any pending changes to disk.Nr   rD   r   r   r   r]   Ÿ  s    zMaildir.flushc                 C   s   dS )r^   Nr   rD   r   r   r   r_   ¥  s    zMaildir.lockc                 C   s   dS )r`   Nr   rD   r   r   r   ra   ©  s    zMaildir.unlockc                 C   s   dS ©rb   Nr   rD   r   r   r   rc   ­  s    zMaildir.closec                 C   s\   g }t  | j¡D ]F}t|ƒdkr|d dkrt j t j | j|¡¡r| |dd… ¡ q|S )úReturn a list of folder names.é   r   Ú.N)r   Úlistdirr   rÎ   r   Úisdirrš   Úappend©r   rU   Úentryr   r   r   Úlist_folders±  s    ÿzMaildir.list_foldersc                 C   s    t tj | jd| ¡| jddS )z/Return a Maildir instance for the named folder.rÓ   F©r   r   )r   r   r   rš   r   r   ©r   Úfolderr   r   r   Ú
get_folderº  s    þzMaildir.get_folderc                 C   s\   t j | jd| ¡}t|| jd}t j |d¡}t j |¡sXt  t  |t j	t j
B d¡¡ |S )z>Create a folder and return a Maildir instance representing it.rÓ   ©r   Zmaildirfolderé¶  )r   r   rš   r   r   r   rœ   rc   rÀ   ÚO_CREATÚO_WRONLY)r   rÜ   r   rU   Zmaildirfolder_pathr   r   r   Ú
add_folderÀ  s    ÿzMaildir.add_folderc                 C   s  t j | jd| ¡}t  t j |d¡¡t  t j |d¡¡ D ](}t|ƒdk sX|d dkr<td| ƒ‚q<t  |¡D ]B}|dkrp|dkrp|dkrpt j t j ||¡¡rptd||f ƒ‚qpt j|d	d
D ]F\}}}|D ]}t  	t j ||¡¡ qÐ|D ]}t  
t j ||¡¡ qîqÂt  
|¡ dS )ú-Delete the named folder, which must be empty.rÓ   r—   r˜   rÒ   r   zFolder contains message(s): %sr–   z%Folder contains subdirectory '%s': %sF)ÚtopdownN)r   r   rš   r   rÔ   rÎ   r   rÕ   Úwalkr+   Úrmdir)r   rÜ   r   rØ   ÚrootÚdirsÚfilesr   r   r   Úremove_folderÊ  s&    ÿÿÿzMaildir.remove_folderc                 C   sX   t   ¡ }t tj | jd¡¡D ]4}tj | jd|¡}|tj |¡ dkrt |¡ qdS )zDelete old files in "tmp".r–   i@ú N)Útimer   rÔ   r   rš   r   r®   r+   )r   ÚnowrØ   r   r   r   r   ÚcleanÝ  s
    zMaildir.cleanrÒ   c                 C   sØ   t   ¡ }t ¡ }d|kr$| dd¡}d|kr8| dd¡}dt|ƒt|d d ƒt ¡ tj|f }tj	 
| jd|¡}zt |¡ W nF tk
rÆ   t jd7  _zt|ƒW  Y 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.%srÒ   g    €„.Ar–   z&Name clash prevented file creation: %sN)rë   ÚsocketÚgethostnamer|   Ú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 d| j kr^d}| jD ]2}tj | j| ¡}|| j| krJd}|| j|< q"|s^dS i | _| jD ]^}| j| }t 	|¡D ]D}tj 
||¡}tj |¡r¢q‚| | j¡d }tj 
||¡| j|< q‚qjt   ¡ | _dS )z!Update table of contents mapping.é   FTNr   )rë   r    r¡   rŸ   r   r   rÄ   r›   rž   rÔ   rš   rÕ   r¬   r©   )r   Zrefreshr¶   Úmtimer   rØ   Úpr¸   r   r   r   rË   ÿ  s&    


zMaildir._refreshc                 C   s€   z.t j t j | j| j| ¡¡r,| j| W S W n tk
rB   Y nX |  ¡  z| j| W S  tk
rz   td| ƒd‚Y nX dS )z=Use TOC to return subpath for given key, or raise a KeyError.úNo message with key: %sN)r   r   rœ   rš   r   rž   r/   rË   r)   r   r   r   r¼   #  s    zMaildir._lookupc                 C   sX   t | dƒs|  ¡ | _z| t| jƒ W S  tk
r:   Y dS  tk
rP   Y qY qX qdS )z0Return the next message in a one-time iteration.Ú_onetime_keysN)rX   rE   rû   ÚnextÚStopIterationr/   rD   r   r   r   rü   1  s    

zMaildir.next)NT)r‘   r’   r“   r”   r©   r    r'   r+   r0   r3   r7   r@   r:   rE   rQ   rS   r]   r_   ra   rc   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  | |||¡ zt| jdƒ}W nn tk
rŽ } zP|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 5 d}~X Y nX || _
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    A  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'   X  s
    z_singlefileMailbox.addc                 C   s   |   |¡ | j|= d| _dS )r(   TN)r¼   rž   r  r)   r   r   r   r+   b  s    
z_singlefileMailbox.removec                 C   s$   |   |¡ |  |¡| j|< d| _dS )r1   TN)r¼   r	  rž   r  r2   r   r   r   r3   h  s    
z_singlefileMailbox.__setitem__c                 c   s   |   ¡  | j ¡ E dH  dS rÊ   )r¼   rž   rG   rD   r   r   r   rE   n  s    z_singlefileMailbox.iterkeysc                 C   s   |   ¡  || jkS rÌ   )r¼   rž   r)   r   r   r   rQ   s  s    z_singlefileMailbox.__contains__c                 C   s   |   ¡  t| jƒS rÍ   )r¼   rÎ   rž   rD   r   r   r   rS   x  s    z_singlefileMailbox.__len__c                 C   s   | j st| jƒ d| _ dS )r^   TN)r  Ú
_lock_filer  rD   r   r   r   r_   }  s    
z_singlefileMailbox.lockc                 C   s   | j rt| jƒ d| _ dS ©r`   FN)r  Ú_unlock_filer  rD   r   r   r   ra   ƒ  s    
z_singlefileMailbox.unlockc           
      C   sä  | j s | jrt| jƒ d| _dS | jdk	s.t‚| j dd¡ | j ¡ }|| jkrbt	d| j|f ƒ‚t
| jƒ}z¤i }|  |¡ t| j ¡ ƒD ]x}| j| \}}| j |¡ |  |¡ | ¡ }| j td|| j ¡  ƒ¡}|sÜqè| |¡ qº|| ¡ f||< |  |¡ qŠ| ¡ | _W n"   | ¡  t |j¡ ‚ Y nX t|ƒ | j ¡  t | j¡j}	t |j|	¡ zt |j| j¡ W n2 tk
r¨   t | j¡ t |j| j¡ Y nX t| jdƒ| _|| _d| _ d| _| jràt | jdd dS )	rÏ   FNr   r÷   z4Size of mailbox file changed (expected %i, found %i)é   rÿ   )Údotlock)!r  r  Ú_sync_flushr  rž   ÚAssertionErrorr{   Útellr  r   Ú_create_temporaryr   Ú_pre_mailbox_hookÚsortedrG   Ú_pre_message_hookrk   Úminr~   Ú_post_message_hookrc   r   r+   r¦   r§   rô   Úst_modeÚchmodr³   rö   rÀ   r  r
  )
r   Zcur_lenZnew_fileZnew_tocr*   ÚstartÚstopZ	new_startrl   Úmoder   r   r   r]   ‰  sb    


þ



ÿ
z_singlefileMailbox.flushc                 C   s   dS )ú,Called before writing the mailbox to file f.Nr   ©r   rÅ   r   r   r   r  É  s    z$_singlefileMailbox._pre_mailbox_hookc                 C   s   dS )ú-Called before writing each message to file f.Nr   r  r   r   r   r  Í  s    z$_singlefileMailbox._pre_message_hookc                 C   s   dS ©ú,Called after writing each message to file f.Nr   r  r   r   r   r  Ñ  s    z%_singlefileMailbox._post_message_hookc                 C   s4   z|  ¡  W 5 z| jr|  ¡  W 5 | j  ¡  X X dS rÐ   )r  rc   r  ra   r]   rD   r   r   r   rc   Õ  s    z_singlefileMailbox.closec                 C   sN   | j dkr|  ¡  |dk	rJz| j | W S  tk
rH   td| ƒd‚Y nX dS )z'Return (start, stop) or raise KeyError.Nrú   )rž   Ú_generate_tocr/   r)   r   r   r   r¼   à  s    
z_singlefileMailbox._lookupc                 C   sœ   | j  dd¡ | j  ¡ }t| jƒdkr8| js8|  | j ¡ z&|  | j ¡ |  |¡}|  	| j ¡ W n" t
k
r€   | j  |¡ ‚ Y nX | j  ¡  | j  ¡ | _|S )z;Append message to mailbox and return (start, stop) offsets.r   r÷   )r  r{   r  rÎ   rž   r  r  r  Ú_install_messager  r¥   Útruncater]   r  )r   r&   ZbeforeZoffsetsr   r   r   r	  ê  s    


z"_singlefileMailbox._append_message)NT)N)r‘   r’   r“   r”   r    r'   r+   r3   rE   rQ   rS   r_   ra   r]   r  r  r  rc   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 ¡  td¡}| j || j ¡  ¡}|  | td¡¡}| 	|dd…  
d¡¡ |S )r<   ó    rh   rs   Nr   )r¼   r  r{   rˆ   r|   r}   rk   r  Ú_message_factoryÚset_fromÚdecode)r   r*   r  r  Ú	from_lineÚstringrÆ   r   r   r   r7     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   rA     s
    
ÿÿz_mboxMMDF.get_stringc                 C   sJ   |   |¡\}}| j |¡ |s(| j ¡  | j || j ¡  ¡}| td¡S )r,  rh   )r¼   r  r{   rˆ   rk   r  r|   r}   )r   r*   r.  r  r  r+  r   r   r   r@     s    
z_mboxMMDF.get_bytesc                 C   s<   |   |¡\}}| j |¡ |s(| j ¡  t| j| j ¡ |ƒS )rB   )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ƒrf| d¡rf| d¡}|dkr\|d|… }||d d… }q°|}d}nJt |tƒrˆ| ¡  d¡}d| }n(t |t	j
jƒr°| ¡ }|dk	r°| d¡}|dkrÎdt t ¡ ¡ ¡  }| j ¡ }| j |t ¡ |  || j| j¡ | j ¡ }||fS )	z1Format a message and blindly write to self._file.Nrr   rh   rq   rÒ   r&  r   s   From MAILER-DAEMON )ru   r   rg   r‚   r‰   ÚfindÚ_mboxMMDFMessageÚget_fromrd   r>   r&   r   Úget_unixfromrë   ÚasctimeÚgmtimer  r  r~   r}   r   Ú_mangle_from_)r   r&   r*  ÚnewlineZauthorr  r  r   r   r   r#  &  s0    







z_mboxMMDF._install_messageN)F)F)F)
r‘   r’   r“   r”   r6  r7   rA   r@   r:   r#  r   r   r   r   r%    s   


	
r%  c                   @   s2   e Zd ZdZdZdZd
dd„Zdd„ Zdd	„ ZdS )r   zA classic mbox mailbox.TNc                 C   s   t | _t | |||¡ dS )zInitialize an mbox mailbox.N)r
   r'  r%  r    r   r   r   r   r    L  s    zmbox.__init__c                 C   s   |  t¡ dS r   ©r~   r}   r  r   r   r   r  Q  s    zmbox._post_message_hookc                 C   sè   g g  }}d}| j  d¡ | j  ¡ }| j  ¡ }| d¡rzt|ƒt|ƒk rj|r`| |ttƒ ¡ n
| |¡ | |¡ d}q|s¤|r–| |ttƒ ¡ q¸| |¡ q¸q|tkr²d}qd}qtt	t
||ƒƒƒ| _t| jƒ| _| j  ¡ | _dS )ú0Generate key-to-(start, stop) table of contents.Fr   rr   TN)r  r{   r  rˆ   r‰   rÎ   rÖ   r}   ÚdictÚ	enumerateÚziprž   r  r  )r   ÚstartsÚstopsZlast_was_emptyÚline_posr   r   r   r   r"  U  s.    






zmbox._generate_toc)NT)	r‘   r’   r“   r”   r6  r   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 | |||¡ dS )zInitialize an MMDF mailbox.N)r   r'  r%  r    r   r   r   r   r    z  s    zMMDF.__init__c                 C   s   |  dt ¡ dS )r  ó   Nr8  r  r   r   r   r    s    zMMDF._pre_message_hookc                 C   s   |  td t ¡ dS )r!  r@  Nr8  r  r   r   r   r  ƒ  s    zMMDF._post_message_hookc                 C   sÞ   g g  }}| j  d¡ d}|}| j  ¡ }| j  ¡ }| dt ¡r˜| |¡ |}| j  ¡ }| j  ¡ }|dt kr„| |ttƒ ¡ qžqJ|sJ| |¡ qžqJq|sq qtt	t
||ƒƒƒ| _t| jƒ| _| j  dd¡ | j  ¡ | _dS )r9  r   r@  r÷   N)r  r{   rˆ   r  r‰   r}   rÖ   rÎ   r:  r;  r<  rž   r  r  )r   r=  r>  Únext_posr?  r   r   r   r   r"  ‡  s.    






zMMDF._generate_toc)NT)r‘   r’   r“   r”   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  | |||¡ tj | j¡sj|r`t | jd¡ t t tj 	| jd¡tj
tjB tjB d¡¡ n
t| jƒ‚d| _dS )zInitialize an MH instance.r™   ú.mh_sequencesi€  FN)r   r    r   r   rœ   r   r   rc   rÀ   rš   rà   ÚO_EXCLrá   r   r  r   r   r   r   r    §  s     ÿ
zMH.__init__c                 C   sä   |   ¡ }t|ƒdkrd}nt|ƒd }tj | jt|ƒ¡}t|ƒ}d}zŠ| j
rVt|ƒ zfz|  ||¡ W n: tk
r¢   | j
r†t|ƒ t	|ƒ d}t |¡ ‚ Y nX t|tƒrº|  ||¡ W 5 | j
rÌt|ƒ X W 5 |sÞt	|ƒ X |S )r!   r   rÒ   FT)rG   rÎ   Úmaxr   r   rš   r   r   rõ   r§   r  r
  r  r   r¥   r+   ru   r   Ú_dump_sequences)r   r&   rG   Znew_keyr¾   rÅ   Úclosedr   r   r   r'   ³  s6    


zMH.addc              
   C   sx   t j | jt|ƒ¡}zt|dƒ}W n> tk
r` } z |jtjkrNt	d| ƒ‚n‚ W 5 d}~X Y nX | 
¡  t  |¡ dS )r(   rÿ   rú   N)r   r   rš   r   r   rÀ   r´   rµ   r   r/   rc   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k
r` } z |jtjkrNt	d| ƒ‚n‚ W 5 d}~X Y nX zd| jrrt|ƒ z@t  t  |t jt jB ¡¡ |  ||¡ t|tƒr°|  ||¡ W 5 | jrÂt|ƒ X W 5 t
|ƒ X dS )r1   rÿ   rú   N)r   r   rš   r   r   rÀ   r´   rµ   r   r/   r§   r  r
  r  rc   rá   ÚO_TRUNCr   ru   r   rE  )r   r*   r&   r   rÅ   rº   r   r   r   r3   ã  s$    
zMH.__setitem__c              
   C   sè   z@| j r$ttj | jt|ƒ¡dƒ}nttj | jt|ƒ¡dƒ}W n> tk
r~ } z |jtj	krlt
d| ƒ‚n‚ W 5 d}~X Y nX |2 | j r”t|ƒ zt|ƒ}W 5 | j r°t|ƒ X W 5 Q R X |  ¡  ¡ D ]\}}||krÈ| |¡ qÈ|S )r<   rÿ   r¿   rú   N)r  rÀ   r   r   rš   r   r   r´   rµ   r   r/   r
  r  r   Úget_sequencesrO   Úadd_sequence)r   r*   rÅ   rº   rÆ   r¦   Úkey_listr   r   r   r7   û  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k
r~ } z |jtj	krlt
d| ƒ‚n‚ W 5 d}~X Y nX |F | j r”t|ƒ z | ¡  td¡W ¢W  5 Q R £ S | j rÄt|ƒ X W 5 Q R X dS )rÇ   rÿ   r¿   rú   Nrh   )r  rÀ   r   r   rš   r   r   r´   rµ   r   r/   r
  r  rk   r|   r}   ©r   r*   rÅ   rº   r   r   r   r@     s     zMH.get_bytesc              
   C   sf   zt tj | jt|ƒ¡dƒ}W n> tk
r\ } z |jtjkrJt	d| ƒ‚n‚ W 5 d}~X Y nX t
|ƒS )rB   r¿   rú   N)rÀ   r   r   rš   r   r   r´   rµ   r   r/   rÉ   rK  r   r   r   r:   )  s    zMH.get_filec                 C   s   t tdd„ t | j¡D ƒƒƒS )rC   c                 s   s   | ]}|  ¡ rt|ƒV  qd S r,   )Úisdigitrñ   )Ú.0rØ   r   r   r   Ú	<genexpr>6  s    ÿzMH.iterkeys.<locals>.<genexpr>)Úiterr  r   rÔ   r   rD   r   r   r   rE   4  s    zMH.iterkeysc                 C   s   t j t j | jt|ƒ¡¡S rÌ   )r   r   rœ   rš   r   r   r)   r   r   r   rQ   9  s    zMH.__contains__c                 C   s   t t|  ¡ ƒƒS rÍ   )rÎ   rF   rE   rD   r   r   r   rS   =  s    z
MH.__len__c                 C   s2   | j s.ttj | jd¡dƒ| _t| jƒ d| _ dS )r^   rB  rÿ   TN)r  rÀ   r   r   rš   r   r  r
  rD   r   r   r   r_   A  s    
zMH.lockc                 C   s(   | j r$t| jƒ t| jƒ | `d| _ dS r  )r  r  r  r§   rD   r   r   r   ra   H  s
    

z	MH.unlockc                 C   s   dS )r\   Nr   rD   r   r   r   r]   P  s    zMH.flushc                 C   s   | j r|  ¡  dS rÐ   )r  ra   rD   r   r   r   rc   T  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Ù   Y  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Ý   a  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Þ   rP  rÛ   r   r   r   râ   f  s    ÿzMH.add_folderc                 C   s`   t j | j|¡}t  |¡}|dgkr:t  t j |d¡¡ n|g krDntd| j ƒ‚t  |¡ dS )rã   rB  zFolder not empty: %sN)r   r   rš   r   rÔ   r+   r   ræ   )r   rÜ   r   Úentriesr   r   r   rê   k  s    

zMH.remove_folderc           
   
      s  i }t tj | jd¡dddÜ}t|  ¡ ƒ‰ |D ]Ä}zš| d¡\}}tƒ }| ¡ D ]H}| ¡ rn| 	t
|ƒ¡ qRdd„ | d¡D ƒ\}}	| t||	d	 ƒ¡ qR‡ fd
d„t|ƒD ƒ||< t|| ƒdkrÌ||= W q0 tk
rò   td| ¡  ƒ‚Y q0X q0W 5 Q R X |S )z=Return a name-to-key-list dictionary to define each sequence.rB  ÚrÚASCII©Úencodingr•   c                 s   s   | ]}t |ƒV  qd S r,   )rñ   )rM  Úxr   r   r   rN  „  s     z#MH.get_sequences.<locals>.<genexpr>ú-rÒ   c                    s   g | ]}|ˆ kr|‘qS r   r   )rM  r*   ©Zall_keysr   r   Ú
<listcomp>†  s    ÿz$MH.get_sequences.<locals>.<listcomp>r   z"Invalid sequence specification: %s)rÀ   r   r   rš   r   ÚsetrG   r¬   rL  r'   rñ   r[   Úranger  rÎ   rf   r   Úrstrip)
r   ZresultsrÅ   r   r¦   ÚcontentsrG   Úspecr  r  r   rX  r   rH  w  s(    
ÿzMH.get_sequencesc                 C   s  t tj | jd¡ddd}zØt t  |jtjtj	B ¡¡ | 
¡ D ]®\}}t|ƒdkrVq@| |d ¡ d}d}tt|ƒƒD ]R}|d	 |krœ|sÆd
}| d¡ n*|r¸d}| d||f ¡ n| d| ¡ |}qx|rä| t|ƒd ¡ q@| d¡ q@W 5 t|ƒ X dS )z:Set sequences using the given name-to-key-list dictionary.rB  zr+rS  rT  r   r•   NFrÒ   TrW  z%s %sz %sÚ
)rÀ   r   r   rš   r   r§   rc   r¦   rá   rG  rO   rÎ   r~   r  rZ  r   )r   Ú	sequencesrÅ   r¦   rG   ÚprevZ
completingr*   r   r   r   Úset_sequences  s.    zMH.set_sequencesc           	      C   s>  |   ¡ }d}g }|  ¡ D ]Â}|d |krÒ| ||d f¡ z4t tj | jt|ƒ¡tj | jt|d ƒ¡¡ W nH t	t
fk
r¶   t tj | jt|ƒ¡tj | jt|d ƒ¡¡ Y nX t tj | jt|ƒ¡¡ |d7 }q|d | _t|ƒdkrödS | ¡ D ]0\}}|D ]"\}}||kr
||| |¡< q
qþ|  |¡ dS )z?Re-name messages to eliminate numbering gaps. Invalidates keys.r   rÒ   N)rH  rE   rÖ   r   r°   r   rš   r   r   r±   r²   r³   Úunlinkr  rÎ   rO   Úindexrb  )	r   r`  ra  Zchangesr*   r¦   rJ  Úoldr—   r   r   r   Úpack¬  s0    ÿÿ



zMH.packc                 C   st   |  ¡ }|   ¡ }| ¡ D ]0\}}||kr4| |¡ q||kr|| |¡= q|D ]}||krN|g||< qN|  |¡ dS )z;Inspect a new MHMessage and update sequences appropriately.N)rH  rO   rÖ   rd  rb  )r   r&   r*   Zpending_sequencesZall_sequencesr¦   rJ  Úsequencer   r   r   rE  Æ  s    zMH._dump_sequences)NT)r‘   r’   r“   r”   r    r'   r+   r3   r7   r@   r:   rE   rQ   rS   r_   ra   r]   rc   rÙ   rÝ   râ   rê   rH  rb  rf  rE  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  | |||¡ 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'   ru   r   Ú
get_labelsrm  )r   r&   r*   r   r   r   r'   à  s    
z	Babyl.addc                 C   s"   t  | |¡ || jkr| j|= dS r»   )rþ   r+   rm  r)   r   r   r   r+   ç  s    
zBabyl.removec                 C   s*   t  | ||¡ t|tƒr&| ¡ | j|< dS )r1   N)rþ   r3   ru   r   rn  rm  r2   r   r   r   r3   í  s    
zBabyl.__setitem__c           
      C   sþ   |   |¡\}}| j |¡ | j ¡  t ¡ }| j ¡ }|dt ks\|sHq\| | td¡¡ q,t ¡ }| j ¡ }|tks|s|q| | td¡¡ qd|| j 	¡  }|dksªt
‚| j |¡}| td¡}t| ¡ | ƒ}	|	 | ¡ ¡ || jkrú|	 | j| ¡ |	S )r<   ó   *** EOOH ***rh   r   )r¼   r  r{   rˆ   rv   rw   r}   r~   r|   r  r  rk   r   r‡   Úset_visiblerm  Ú
set_labels)
r   r*   r  r  Úoriginal_headersr   Zvisible_headersÚnZbodyrÆ   r   r   r   r7   ó  s,    



zBabyl.get_messagec           	      C   s¸   |   |¡\}}| j |¡ | j ¡  t ¡ }| j ¡ }|dt ks\|sHq\| | td¡¡ q,| j ¡ }|tksv|s\qvq\| 	¡ }|| j 
¡  }|dks˜t‚| j |¡}| td¡}|| S )r,  ro  rh   r   )r¼   r  r{   rˆ   rv   rw   r}   r~   r|   r‡   r  r  rk   )	r   r*   r  r  rr  r   Zheadersrs  rŽ   r   r   r   r@     s"    


zBabyl.get_bytesc                 C   s   t  |  |¡ dt¡¡S )rB   rh   )rv   rw   r@   r|   r}   r)   r   r   r   r:   %  s    zBabyl.get_filec                 C   s<   |   ¡  tƒ }| j ¡ D ]}| |¡ q| | j¡ t|ƒS )z4Return a list of user-defined labels in the mailbox.)r¼   rZ  rm  rM   r[   Údifference_updateÚ_special_labelsrF   )r   ÚlabelsZ
label_listr   r   r   rn  )  s    zBabyl.get_labelsc                 C   s:  g g  }}| j  d¡ d}g }|}| j  ¡ }| j  ¡ }|dt krœt|ƒt|ƒk rd| |ttƒ ¡ | |¡ dd„ | j  ¡ dd…  d¡D ƒ}| |¡ q|dks°|dt krÔt|ƒt|ƒk rì| |ttƒ ¡ q|s| |ttƒ ¡ qîqtt	t
||ƒƒƒ| _tt	|ƒƒ| _t| jƒ| _| j  dd	¡ | j  ¡ | _dS )
r9  r   s   c                 S   s   g | ]}|  ¡ r|  ¡ ‘qS r   )Ústrip©rM  Úlabelr   r   r   rY  @  s    þz'Babyl._generate_toc.<locals>.<listcomp>rÒ   Nó   ,ó   r÷   )r  r{   rˆ   r  r}   rÎ   rÖ   r¬   r:  r;  r<  rž   rm  r  r  )r   r=  r>  rA  Zlabel_listsr?  r   rv  r   r   r   r"  2  s4    



ÿzBabyl._generate_tocc                 C   sV   dt  }|dt  7 }|  ¡ }dd„ |D ƒ}|dd |¡ t  7 }|d7 }| |¡ dS )	r  s   BABYL OPTIONS:s
   Version: 5c                 s   s   | ]}|  ¡ V  qd S r,   )rd   rx  r   r   r   rN  U  s     z*Babyl._pre_mailbox_hook.<locals>.<genexpr>s   Labels:rz  r{  N)r}   rn  rš   r~   )r   rÅ   Zbabylrv  r   r   r   r  P  s    zBabyl._pre_mailbox_hookc                 C   s   |  dt ¡ dS )r  ó   Nr8  r  r   r   r   r  Z  s    zBabyl._pre_message_hookc                 C   s   |  td ¡ dS )r!  r{  Nr8  r  r   r   r   r  ^  s    zBabyl._post_message_hookc                 C   sx  | j  ¡ }t|tƒr°g }g }| ¡ D ]$}|| jkr>| |¡ q$| |¡ q$| j  d¡ |D ]}| j  d| ¡  ¡ qZ| j  d¡ |D ]}| j  d| ¡  d ¡ q„| j  t	¡ n| j  dt	 ¡ t|t
jjƒrt ¡ }t
j |dd¡}| |¡ | d¡ | ¡ }| j  | d	t	¡¡ |d	ks,|süq,qü| j  d
t	 ¡ t|tƒr¤t ¡ }	t
j |	dd¡}
|
 | ¡ ¡ |	 ¡ }| j  | d	t	¡¡ |d	ks¢|snqâqnn>| d¡ | ¡ }| j  | d	t	¡¡ |d	ksâ|s®qâq®| d¡}|söqf| j  | d	t	¡¡ qânTt|tttjfƒrt|tjƒrJt dtd¡ | ¡ }t|tƒr`|  |¡}| d¡d }|d dkrâ| j  |d|…  d	t	¡¡ | j  d
t	 ¡ | j  |d|…  d	t	¡¡ | j  ||d…  d	t	¡¡ n(| j  d
t	 t	 ¡ | j  | d	t	¡¡ nXt |dƒrVt |dƒr:t dtd¡ |j!}| ¡ }d}| ¡ }| "d¡rl|dd… d	 }n| "d¡rˆ|dd… d	 }| j  | d	t	¡¡ |d	ks¬|sF|rÚd}| j  d
t	 ¡ | |¡ nqÚqF| ¡ }|sìqf| "d¡r
|dd… t	 }n:| "d¡r(|dd… t	 }n| "d	¡rD|dd… t	 }| j  |¡ qÚnt#dt$|ƒ ƒ‚| j  ¡ }||fS )z0Write message contents and return (start, stop).ó   1s   , s   ,,ó    rz  s   1,,Fr   rh   ro  r  ri   rj   s   

r÷   rq   Nrˆ   rl   rm   Trn   ro   rp   rt   )%r  r  ru   r   rn  ru  rÖ   r~   rd   r}   r>   r&   r   rv   rw   rx   ry   rz   r{   rˆ   r|   Úget_visiblerk   r‚   r   rƒ   r„   r…   r†   r‡   rg   r0  rX   rl   r€   rŠ   r‹   )r   r&   r  Zspecial_labelsrv  ry  Zorig_bufferZorig_generatorr   Z
vis_bufferZvis_generatorrl   Z
body_startZoriginal_posZ
first_passr  r   r   r   r#  b  s¼    







 ÿ
 ÿ
zBabyl._install_message)NT)r‘   r’   r“   r”   Ú	frozensetru  r    r'   r+   r3   r7   r@   r:   rn  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|  t |¡¡ t |tƒrÎ| | ¡ nšt |tƒrP|  t 	|¡¡ n~t |t
ƒrl|  t |¡¡ nbt |tjƒrŠ|  t |¡¡ nDt|dƒr¦|  t |¡¡ n(|dkr¾tjj | ¡ ntdt|ƒ ƒ‚dS )zInitialize a Message instance.rk   Nrt   )ru   r>   r&   r   Ú_become_messageÚcopyZdeepcopyÚ_explain_tor‚   r?   r   Zmessage_from_stringrv   ÚTextIOWrapperZmessage_from_filerX   Zmessage_from_binary_filer    rŠ   r‹   r%   r   r   r   r    Ñ  s    



zMessage.__init__c                 C   s4   t |dg ƒ}|jD ]}||kr|j| | j|< qdS )z0Assume the non-format-specific state of message.Ú_type_specific_attributesN)ÚgetattrÚ__dict__)r   r&   Ztype_specificr¦   r   r   r   r  ä  s    
zMessage._become_messagec                 C   s   t |tƒrdS tdƒ‚dS )z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)ru   r   rŠ   r%   r   r   r   rƒ  ë  s    
zMessage._explain_to)N)r‘   r’   r“   r”   r    r  rƒ  r   r   r   r   r   Î  s   
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 ¡ | _t | |¡ dS )z%Initialize a MaildirMessage instance.r—   r£   N)rˆ  r‰  rë   rŠ  r   r    r%   r   r   r   r    ø  s    
zMaildirMessage.__init__c                 C   s   | j S )zReturn 'new' or 'cur'.)rˆ  rD   r   r   r   r¨   ÿ  s    zMaildirMessage.get_subdirc                 C   s(   |dks|dkr|| _ ntd| ƒ‚dS )zSet subdir to 'new' or 'cur'.r—   r˜   z!subdir must be 'new' or 'cur': %sN)rˆ  rf   )r   r¶   r   r   r   rÁ     s    zMaildirMessage.set_subdirc                 C   s"   | j  d¡r| j dd… S dS dS )ú*Return as a string the flags that are set.ú2,r÷   Nr£   )r‰  r‰   rD   r   r   r   Ú	get_flags
  s    zMaildirMessage.get_flagsc                 C   s   dd  t|ƒ¡ | _dS )ú)Set the given flags and unset all others.rŒ  r£   N)rš   r  r‰  )r   Úflagsr   r   r   Ú	set_flags  s    zMaildirMessage.set_flagsc                 C   s$   |   d t|  ¡ ƒt|ƒB ¡¡ dS ©z.Set the given flag(s) without changing others.r£   N©r  rš   rZ  r  ©r   Úflagr   r   r   Úadd_flag  s    zMaildirMessage.add_flagc                 C   s,   |   ¡ r(|  d t|   ¡ ƒt|ƒ ¡¡ dS )ú7Unset the given string flag(s) without changing others.r£   N)r  r  rš   rZ  r“  r   r   r   Úremove_flag  s    zMaildirMessage.remove_flagc                 C   s   | j S )z<Return delivery date of message, in seconds since the epoch.)rŠ  rD   r   r   r   r¯     s    zMaildirMessage.get_datec                 C   s6   zt |ƒ| _W n" tk
r0   td| ƒd‚Y nX dS )z9Set delivery date of message, in seconds since the epoch.zcan't convert to float: %sN)ÚfloatrŠ  rf   rŠ   )r   Údater   r   r   rÃ   "  s    zMaildirMessage.set_datec                 C   s   | j S )z%Get the message's "info" as a string.)r‰  rD   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)ru   r   r‰  rŠ   r‹   )r   Úinfor   r   r   rÂ   -  s    
zMaildirMessage.set_infoc                 C   s¤  t |tƒr8| |  ¡ ¡ | |  ¡ ¡ | |  ¡ ¡ nht |tƒrÄt	|  ¡ ƒ}d|kr`| 
d¡ |  ¡ dkrv| 
d¡ d|krˆ| 
d¡ d|krš| 
d¡ d|kr¬| 
d¡ | d	t |  ¡ ¡¡ nÜt |tƒrt	|  ¡ ƒ}d|krî| d
¡ d|kr| d¡ d|kr | d¡ nˆt |tƒr‚t	|  ¡ ƒ}d|krD| d
¡ d|krX| d¡ d|krl| d¡ d|kr | d¡ nt |tƒrntdt|ƒ ƒ‚dS )z;Copy Maildir-specific state to message insofar as possible.ÚSÚRr˜   ÚOÚTÚDÚFÚAúMAILER-DAEMONrh  ÚrepliedÚflaggedri  rj  ÚPrk  ú$Cannot convert to specified type: %sN)ru   r	   r  r  rÁ   r¨   rÃ   r¯   r1  rZ  r•  r(  rë   r5  r   rI  r   Ú	add_labelr   rŠ   r‹   )r   r&   r  r   r   r   rƒ  4  sP    

















ÿzMaildirMessage._explain_to)N)r‘   r’   r“   r”   r…  r    r¨   rÁ   r  r  r•  r—  r¯   rÃ   rª   rÂ   rƒ  r   r   r   r   r	   ó  s   

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 )r1  z/Message with mbox- or MMDF-specific properties.Ú_fromNc                 C   sV   |   dd¡ t|tjjƒrF| ¡ }|dk	rF| d¡rF|   |dd… ¡ t | |¡ dS )z'Initialize an mboxMMDFMessage instance.r¢  TNzFrom rs   )r(  ru   r>   r&   r   r3  r‰   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¨  rD   r   r   r   r2  n  s    z_mboxMMDFMessage.get_fromc                 C   s4   |dk	r*|dkrt  ¡ }|dt  |¡ 7 }|| _dS )z>Set "From " line, formatting and appending time_ if specified.NTú )rë   r5  r4  r¨  )r   r.  Ztime_r   r   r   r(  r  s
    z_mboxMMDFMessage.set_fromc                 C   s   |   dd¡|   dd¡ S )r‹  ÚStatusr£   úX-Status)r6   rD   r   r   r   r  z  s    z_mboxMMDFMessage.get_flagsc                 C   sÒ   t |ƒ}d\}}dD ]}||kr||7 }| |¡ qdD ]}||kr8||7 }| |¡ q8|d t|ƒ¡7 }z|  d|¡ W n  tk
rš   |  d|¡ Y nX z|  d|¡ W n  tk
rÌ   |  d|¡ Y nX dS )rŽ  )r£   r£   )rœ  r  )rŸ  r   r¡  r£   rª  r«  N)rZ  r+   rš   r  Úreplace_headerr/   Z
add_header)r   r  Zstatus_flagsZxstatus_flagsr”  r   r   r   r  ~  s&    z_mboxMMDFMessage.set_flagsc                 C   s$   |   d t|  ¡ ƒt|ƒB ¡¡ dS r‘  r’  r“  r   r   r   r•  ”  s    z_mboxMMDFMessage.add_flagc                 C   s4   d| ksd| kr0|   d t|  ¡ ƒt|ƒ ¡¡ dS )r–  rª  r«  r£   Nr’  r“  r   r   r   r—  ˜  s    z_mboxMMDFMessage.remove_flagc              	   C   sÞ  t |tƒrÐt|  ¡ ƒ}d|kr(| d¡ d|kr:| d¡ d|krL| d¡ d|kr^| d¡ d|krp| d¡ |d	= |d
= d |  ¡  ¡ dd… ¡}z| 	t
 t |d¡¡¡ W n ttfk
rÊ   Y nX n
t |tƒrø| |  ¡ ¡ | |  ¡ ¡ nât |tƒrZt|  ¡ ƒ}d|kr$| d¡ d|kr8| d¡ d|krL| d¡ |d	= |d
= n€t |tƒr¼t|  ¡ ƒ}d|kr†| d¡ d|krš| d¡ d|kr®| d¡ |d	= |d
= nt |tƒrÊntdt|ƒ ƒ‚dS )zACopy mbox- or MMDF-specific state to message insofar as possible.r  r˜   r   r¡  rœ  r›  rŸ  rž  Zstatuszx-statusr©  éûÿÿÿNz%a %b %d %H:%M:%S %Yrh  r£  r¤  ri  rj  r¦  )ru   r	   rZ  r  rÁ   r•  rš   r2  r¬   rÃ   ÚcalendarZtimegmrë   Ústrptimerf   ÚOverflowErrorr1  r  r(  r   rI  r   r§  r   rŠ   r‹   )r   r&   r  Z
maybe_dater   r   r   rƒ    sb    





ÿ













ÿz_mboxMMDFMessage._explain_to)N)N)r‘   r’   r“   r”   r…  r    r2  r(  r  r  r•  r—  rƒ  r   r   r   r   r1  `  s   
	
r1  c                   @   s   e Zd ZdZdS )r
   z&Message with mbox-specific properties.N©r‘   r’   r“   r”   r   r   r   r   r
   Ñ  s   c                   @   sH   e Zd ZdZdgZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )r   z$Message with MH-specific properties.Ú
_sequencesNc                 C   s   g | _ t | |¡ dS )z!Initialize an MHMessage instance.N)r²  r   r    r%   r   r   r   r    Ú  s    zMHMessage.__init__c                 C   s   | j dd… S )z4Return a list of sequences that include the message.N)r²  rD   r   r   r   rH  ß  s    zMHMessage.get_sequencesc                 C   s   t |ƒ| _dS )z3Set the list of sequences that include the message.N)rF   r²  )r   r`  r   r   r   rb  ã  s    zMHMessage.set_sequencesc                 C   s6   t |tƒr"|| jkr2| j |¡ ntdt|ƒ ƒ‚dS )z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)ru   r   r²  rÖ   rŠ   r‹   ©r   rg  r   r   r   rI  ç  s    

zMHMessage.add_sequencec                 C   s*   z| j  |¡ W n tk
r$   Y nX dS )zARemove sequence from the list of sequences including the message.N)r²  r+   rf   r³  r   r   r   Úremove_sequenceï  s    zMHMessage.remove_sequencec                 C   sF  t |tƒrdt|  ¡ ƒ}d|kr*| d¡ n| d¡ | d¡ d|krP| d¡ d|krb| d¡ nÞt |tƒr¾t|  ¡ ƒ}d|krŽ| d¡ n
| d	¡ d|krª| d¡ d|kr¼| d
¡ n„t |tƒrâ|  ¡ D ]}| |¡ qÐn`t |t	ƒr$t|  ¡ ƒ}d|kr| 
d¡ d|krB| 
d¡ nt |tƒr2ntdt|ƒ ƒ‚dS )z6Copy MH-specific state to message insofar as possible.rh  r˜   r›  r¤  r   r£  rœ  ÚROr  r¡  rj  r¦  N)ru   r	   rZ  rH  rÁ   r•  r1  r   rI  r   r§  r   rŠ   r‹   )r   r&   r`  rg  r   r   r   rƒ  ö  sB    










ÿzMHMessage._explain_to)N)r‘   r’   r“   r”   r…  r    rH  rb  rI  r´  rƒ  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.rm  Ú_visibleNc                 C   s   g | _ tƒ | _t | |¡ dS )z#Initialize a BabylMessage instance.N)rm  r   r¶  r    r%   r   r   r   r    "  s    zBabylMessage.__init__c                 C   s   | j dd… S )z'Return a list of labels on the message.N)rm  rD   r   r   r   rn  (  s    zBabylMessage.get_labelsc                 C   s   t |ƒ| _dS )z&Set the list of labels on the message.N)rF   rm  )r   rv  r   r   r   rq  ,  s    zBabylMessage.set_labelsc                 C   s6   t |tƒr"|| jkr2| j |¡ ntdt|ƒ ƒ‚dS )z+Add label to list of labels on the message.zlabel must be a string: %sN)ru   r   rm  rÖ   rŠ   r‹   ©r   ry  r   r   r   r§  0  s    

zBabylMessage.add_labelc                 C   s*   z| j  |¡ W n tk
r$   Y nX dS )z4Remove label from the list of labels on the message.N)rm  r+   rf   r·  r   r   r   Úremove_label8  s    zBabylMessage.remove_labelc                 C   s
   t | jƒS )z3Return a Message representation of visible headers.©r   r¶  rD   r   r   r   r  ?  s    zBabylMessage.get_visiblec                 C   s   t |ƒ| _dS )z2Set the Message representation of visible headers.Nr¹  )r   Zvisibler   r   r   rp  C  s    zBabylMessage.set_visiblec                 C   sb   | j  ¡ D ](}|| kr*| j  || | ¡ q
| j |= q
dD ]$}|| kr8|| j kr8| | | j |< q8dS )z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)r¶  rG   r¬  )r   Úheaderr   r   r   Úupdate_visibleG  s    
zBabylMessage.update_visiblec                 C   sr  t |tƒr~t|  ¡ ƒ}d|kr*| d¡ n| d¡ | d¡ d|ksNd|krX| d¡ d|krj| d¡ d	|kr|| d
¡ nðt |tƒrØt|  ¡ ƒ}d|kr¨| d¡ n
| d¡ d	|krÄ| d¡ d|krÖ| d¡ n–t |tƒrt|  ¡ ƒ}d|kr| d¡ d|krn| d¡ nTt |t	ƒrP| 
|  ¡ ¡ |  ¡ D ]}| |¡ q<nt |tƒr^ntdt|ƒ ƒ‚dS )z9Copy Babyl-specific state to message insofar as possible.rh  r˜   r›  rk  rl  r¥  rj  rœ  ri  rž  rµ  r  rŸ  r¡  r£  r¦  N)ru   r	   rZ  rn  rÁ   r•  r1  r   rI  r   rp  r  r§  r   rŠ   r‹   )r   r&   rv  ry  r   r   r   rƒ  R  sH    










ÿzBabylMessage._explain_to)N)r‘   r’   r“   r”   r…  r    rn  rq  r§  r¸  r  rp  r»  rƒ  r   r   r   r   r     s   
c                   @   s   e Zd ZdZdS )r   z&Message with MMDF-specific properties.Nr±  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| ¡ | _n|| _dS )zInitialize a _ProxyFile.N)r  r  Ú_pos)r   rÅ   Úposr   r   r   r    ƒ  s    z_ProxyFile.__init__c                 C   s   |   || jj¡S ©zRead bytes.)Ú_readr  rk   ©r   Úsizer   r   r   rk   ‹  s    z_ProxyFile.readc                 C   s   |   || jj¡S r¾  )r¿  r  Úread1rÀ  r   r   r   rÂ    s    z_ProxyFile.read1c                 C   s   |   || jj¡S )zRead a line.)r¿  r  rˆ   rÀ  r   r   r   rˆ   “  s    z_ProxyFile.readlinec                 C   s<   g }| D ].}|  |¡ |dk	r|t|ƒ8 }|dkr q8q|S )zRead multiple lines.Nr   )rÖ   rÎ   )r   ÚsizehintrU   r   r   r   r   Ú	readlines—  s    
z_ProxyFile.readlinesc                 c   s   |   ¡ }|sdS |V  q dS )zIterate over lines.N)rˆ   )r   r   r   r   r   rL   ¢  s    z_ProxyFile.__iter__c                 C   s   | j S )zReturn the position.)r¼  rD   r   r   r   r  ª  s    z_ProxyFile.tellr   c                 C   s4   |dkr| j  | j¡ | j  ||¡ | j  ¡ | _dS )zChange position.rÒ   N©r  r{   r¼  r  ©r   ÚoffsetÚwhencer   r   r   r{   ®  s    z_ProxyFile.seekc                 C   s0   t | dƒr,zt | jdƒr"| j ¡  W 5 | `X dS )zClose the file.r  rc   N)rX   r  rc   rD   r   r   r   rc   µ  s
    
z_ProxyFile.closec                 C   s2   |dkrd}| j  | j¡ ||ƒ}| j  ¡ | _|S )z"Read size bytes using read_method.Nrq   rÅ  )r   rÁ  Úread_methodrU   r   r   r   r¿  ¾  s    z_ProxyFile._readc                 C   s   | S )z$Context management protocol support.r   rD   r   r   r   Ú	__enter__Ç  s    z_ProxyFile.__enter__c                 G   s   |   ¡  d S r,   )rc   )r   Úexcr   r   r   Ú__exit__Ë  s    z_ProxyFile.__exit__c                 C   s
   | j  ¡ S r,   )r  ÚreadablerD   r   r   r   rÍ  Î  s    z_ProxyFile.readablec                 C   s
   | j  ¡ S r,   )r  ÚwritablerD   r   r   r   rÎ  Ñ  s    z_ProxyFile.writablec                 C   s
   | j  ¡ S r,   )r  ÚseekablerD   r   r   r   rÏ  Ô  s    z_ProxyFile.seekablec                 C   s
   | j  ¡ S r,   )r  r]   rD   r   r   r   r]   ×  s    z_ProxyFile.flushc                 C   s&   t | dƒsdS t | jdƒsdS | jjS )Nr  TrF  F)rX   r  rF  rD   r   r   r   rF  Ú  s
    
z_ProxyFile.closed)N)N)N)N)N)r   )r‘   r’   r“   r”   r    rk   rÂ  rˆ   rÄ  rL   r  r{   rc   r¿  rÊ  rÌ  rÍ  rÎ  rÏ  r]   ÚpropertyrF  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Ñ  rD   r   r   r   r  ì  s    z_PartialFile.tellr   c                 C   s<   |dkr| j | _d}n|dkr*| j| _d}t | ||¡ dS )z8Change position, possibly with respect to start or stop.r   rÒ   r÷   N)rÑ  r¼  rÒ  rÉ   r{   rÆ  r   r   r   r{   ð  s    z_PartialFile.seekc                 C   sB   | j | j }|dkrdS |dks0|dk s0||kr4|}t | ||¡S )z;Read size bytes using read_method, honoring start and stop.r   r&  N)rÒ  r¼  rÉ   r¿  )r   rÁ  rÉ  Z	remainingr   r   r   r¿  ú  s    z_PartialFile._readc                 C   s   t | dƒr| `d S )Nr  )rX   r  rD   r   r   r   rc     s    
z_PartialFile.close)NN)r   )	r‘   r’   r“   r”   r    r  r{   r¿  rc   r   r   r   r   r/  ã  s   


	r/  Tc              
   C   s¦  d}zbt rpzt  | 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 5 d}~X Y nX |rfzt| j
d ƒ}| ¡  W nB tk
rÒ } z$|jtjtjfkrÀW Y ¢W dS ‚ W 5 d}~X Y nX z`zt |j
| j
d ¡ d}W n2 ttfk
r$   t |j
| j
d ¡ d}Y nX t |j
¡ W n0 tk
rd   t |j
¡ t	d| j
 ƒ‚Y nX W n8   t r„t  | t j¡ |ršt | j
d ¡ ‚ Y nX dS )z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNú.lockTzdot lock unavailable: %s)ÚfcntlÚlockfZLOCK_EXZLOCK_NBr´   rµ   ZEAGAINr  r  r   r¦   r  rc   r   r°   r±   r²   r³   rc  rö   r+   ÚLOCK_UN)rÅ   r  Zdotlock_donerº   Zpre_lockr   r   r   r
  
  sL    ÿ
ÿr
  c                 C   s8   t rt  | t j¡ tj | jd ¡r4t | jd ¡ dS )z*Unlock file f using lockf and dot locking.rÓ  N)rÔ  rÕ  rÖ  r   r   rœ   r¦   r+   ©rÅ   r   r   r   r  4  s    r  c              	   C   s<   t  | t jt jB t jB d¡}zt| dƒW ¢S t  |¡ X dS )zCCreate a file if it doesn't exist and open for reading and writing.rß   rÿ   N)r   rÀ   rà   rC  ÚO_RDWRrc   )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  C  s    þr  c                 C   s$   |   ¡  ttdƒr t |  ¡ ¡ dS )z0Ensure changes to file f are physically on disk.ÚfsyncN)r]   rX   r   rÚ  Úfilenor×  r   r   r   r  I  s    
r  c                 C   s   t | ƒ |  ¡  dS )z:Close file f, ensuring all changes are physically on disk.N)r  rc   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.Nr±  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.Nr±  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.Nr±  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.Nr±  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.Nr±  r   r   r   r   r   a  s   )T)0r”   r   rë   r®  rï   rµ   r‚  r„   r>   Zemail.messageZemail.generatorrv   r8   rÔ  ÚImportErrorÚ__all__r}   rd   r   r   rþ   r%  r   r   r   r   r&   r   r	   r1  r
   r   r   r   rÉ   r/  r
  r  rõ   r  r  r§   Ú	Exceptionr   r   r   r   r   r   r   r   r   Ú<module>   s‚   
        ý h  8 DB4-  3 z%mqH_c'
*