o
     JAfÊ3 ã                   @   s>  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlZddlmZ zddlZW n eyI   dZY nw g d¢Zej d¡ZG dd„ dƒZG dd	„ d	eƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dejjƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ deƒZ!G d d!„ d!eƒZ"G d"d#„ d#eƒZ#G d$d%„ d%ƒZ$G d&d'„ d'e$ƒZ%d?d)d*„Z&d+d,„ Z'd-d.„ Z(d/d0„ Z)d1d2„ Z*d3d4„ Z+G d5d6„ d6e,ƒZ-G d7d8„ d8e-ƒZ.G d9d:„ d:e-ƒZ/G d;d<„ d<e-ƒZ0G d=d>„ d>e-ƒZ1dS )@zDRead/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.é    N)ÚGenericAlias)ÚMailboxÚMaildirÚmboxÚMHÚBabylÚMMDFÚMessageÚMaildirMessageÚmboxMessageÚ	MHMessageÚBabylMessageÚMMDFMessageÚErrorÚNoSuchMailboxErrorÚNotEmptyErrorÚExternalClashErrorÚFormatErrorÚasciic                   @   s  e Zd ZdZdCdd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dDdd„Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdDd0d1„Zd2d3„ ZdDd4d5„Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Z d>d?„ Z!d@Z"dEdAdB„Z#e$e%ƒZ&dS )Fr   z*A group of messages in a particular place.NTc                 C   s    t j t j |¡¡| _|| _dS )zInitialize a Mailbox instance.N)ÚosÚpathÚabspathÚ
expanduserÚ_pathÚ_factory©Úselfr   ÚfactoryÚcreate© r   ú/usr/lib/python3.10/mailbox.pyÚ__init__%   s   
zMailbox.__init__c                 C   ó   t dƒ‚)ú$Add message and return assigned key.ú&Method must be implemented by subclass©ÚNotImplementedError©r   Úmessager   r   r    Úadd*   ó   zMailbox.addc                 C   r"   )ú=Remove the keyed message; raise KeyError if it doesn't exist.r$   r%   ©r   Úkeyr   r   r    Úremove.   r*   zMailbox.removec                 C   s   |   |¡ d S ©N)r.   r,   r   r   r    Ú__delitem__2   s   zMailbox.__delitem__c                 C   s&   z|   |¡ W dS  ty   Y dS w ©z'If the keyed message exists, remove it.N)r.   ÚKeyErrorr,   r   r   r    Údiscard5   s
   ÿzMailbox.discardc                 C   r"   )ú>Replace the keyed message; raise KeyError if it doesn't exist.r$   r%   ©r   r-   r(   r   r   r    Ú__setitem__<   r*   zMailbox.__setitem__c                 C   s$   z|   |¡W S  ty   | Y S w )z9Return the keyed message, or default if it doesn't exist.)Ú__getitem__r2   )r   r-   Údefaultr   r   r    Úget@   s
   ÿzMailbox.getc                 C   sN   | j s|  |¡S t |  |¡¡}|   |¡W  d  ƒ S 1 s w   Y  dS )z=Return the keyed message; raise KeyError if it doesn't exist.N)r   Úget_messageÚ
contextlibÚclosingÚget_file)r   r-   Úfiler   r   r    r7   G   s
   
$ÿzMailbox.__getitem__c                 C   r"   )ú4Return a Message representation or raise a KeyError.r$   r%   r,   r   r   r    r:   O   r*   zMailbox.get_messagec                 C   s   t  |  |¡¡ ¡ S )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_stringS   s   zMailbox.get_stringc                 C   r"   )z8Return a byte string representation or raise a KeyError.r$   r%   r,   r   r   r    rC   Z   r*   zMailbox.get_bytesc                 C   r"   )ú6Return a file-like representation or raise a KeyError.r$   r%   r,   r   r   r    r=   ^   r*   zMailbox.get_filec                 C   r"   )úReturn an iterator over keys.r$   r%   ©r   r   r   r    Úiterkeysb   r*   zMailbox.iterkeysc                 C   ó   t |  ¡ ƒS )zReturn a list of keys.)ÚlistrH   rG   r   r   r    Úkeysf   ó   zMailbox.keysc              	   c   s:    |   ¡ D ]}z| | }W n	 ty   Y qw |V  qdS )z%Return an iterator over all messages.N©rH   r2   ©r   r-   Úvaluer   r   r    Ú
itervaluesj   s   €ÿûzMailbox.itervaluesc                 C   s   |   ¡ S r/   )rP   rG   r   r   r    Ú__iter__s   s   zMailbox.__iter__c                 C   rI   )z,Return a list of messages. Memory intensive.)rJ   rP   rG   r   r   r    Úvaluesv   rL   zMailbox.valuesc              	   c   s>    |   ¡ D ]}z| | }W n	 ty   Y qw ||fV  qdS )z.Return an iterator over (key, message) tuples.NrM   rN   r   r   r    Ú	iteritemsz   s   €ÿûzMailbox.iteritemsc                 C   rI   )z9Return a list of (key, message) tuples. Memory intensive.)rJ   rS   rG   r   r   r    Úitemsƒ   rL   zMailbox.itemsc                 C   r"   )ú9Return True if the keyed message exists, False otherwise.r$   r%   r,   r   r   r    Ú__contains__‡   r*   zMailbox.__contains__c                 C   r"   )ú*Return a count of messages in the mailbox.r$   r%   rG   r   r   r    Ú__len__‹   r*   zMailbox.__len__c                 C   s   |   ¡ D ]}|  |¡ qdS )zDelete all messages.N)rK   r3   r,   r   r   r    Úclear   s   ÿzMailbox.clearc                 C   s2   z| | }W n t y   | Y S w |  |¡ |S )z3Delete the keyed message and return it, or default.)r2   r3   )r   r-   r8   Úresultr   r   r    Úpop”   s   ÿ
zMailbox.popc                 C   s&   |   ¡ D ]
}||  |¡f  S tdƒ‚)z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailbox)rH   r[   r2   r,   r   r   r    Úpopitem   s   zMailbox.popitemc              	   C   sp   t |dƒr
| ¡ }nt |dƒr| ¡ }n|}d}|D ]\}}z|| |< W q ty/   d}Y qw |r6tdƒ‚dS )z4Change the messages that correspond to certain keys.rS   rT   FTzNo message with key(s)N)ÚhasattrrS   rT   r2   )r   ÚargÚsourceZbad_keyr-   r(   r   r   r    Úupdate¤   s   



ÿÿzMailbox.updatec                 C   r"   )ú&Write any pending changes to the disk.r$   r%   rG   r   r   r    Úflushµ   r*   zMailbox.flushc                 C   r"   )úLock the mailbox.r$   r%   rG   r   r   r    Úlock¹   r*   zMailbox.lockc                 C   r"   )ú#Unlock the mailbox if it is locked.r$   r%   rG   r   r   r    Úunlock½   r*   zMailbox.unlockc                 C   r"   )úFlush and close the mailbox.r$   r%   rG   r   r   r    ÚcloseÁ   r*   zMailbox.closec                 C   s$   z|  d¡W S  ty   tdƒ‚w )Nr   z?String input must be ASCII-only; use bytes or a Message instead)ÚencodeÚUnicodeErrorÚ
ValueErrorr'   r   r   r    Ú_string_to_bytesÅ   s
   ÿzMailbox._string_to_bytesFc           	      C   sü  t |tjjƒr?t ¡ }tj ||d¡}| |¡ | 	d¡ | 
¡ }| dt¡}| |¡ | jr;| t¡s=| t¡ d
S d
S d
S t |tttjfƒr‰t |tjƒrYt dtd¡ | ¡ }t |tƒrc|  |¡}|rk| dd¡}| dt¡}| |¡ | jr…| t¡s‡| t¡ d
S d
S d
S t|dƒröt|dƒrt d	td¡ |j}d
}	 | ¡ }| d¡r²|d
d… d }n| d¡r¿|d
d… d }|sÂn|rÑ| d¡rÑd|dd
…  }| dt¡}| |¡ |}q | jrð|rò| t¡sô| t¡ d
S d
S d
S d
S tdt|ƒ ƒ‚)z%Dump message contents to target file.r   ó   
ú8Use of StringIO input is deprecated, use BytesIO insteadé   s   
From s   
>From ÚreadÚbufferúDUse of text mode files is deprecated, use a binary mode file insteadNTó   
éþÿÿÿó   éÿÿÿÿó   From s   >From é   úInvalid message type: %s)Ú
isinstancerA   r(   r	   ÚioÚBytesIOÚ	generatorÚBytesGeneratorÚflattenÚseekrp   ÚreplaceÚlinesepÚwriteÚ_append_newlineÚendswithÚstrÚbytesÚStringIOÚwarningsÚwarnÚDeprecationWarningÚgetvaluerl   r]   rq   ÚreadlineÚ
startswithÚ	TypeErrorÚtype)	r   r(   ÚtargetZmangle_from_rq   ÚgenÚdataZlastlineÚliner   r   r    Ú_dump_messageÒ   sf   


þÿ


þ

ÿ


óþzMailbox._dump_message©NTr/   ©F)'Ú__name__Ú
__module__Ú__qualname__Ú__doc__r!   r)   r.   r0   r3   r6   r9   r7   r:   rD   rC   r=   rH   rK   rP   rQ   rR   rS   rT   rV   rX   rY   r[   r\   r`   rb   rd   rf   rh   rl   r„   r•   Úclassmethodr   Ú__class_getitem__r   r   r   r    r   "   sF    

		
	

6r   c                   @   sÚ   e Zd ZdZdZd6dd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ ZdS )7r   zA qmail-style Maildir mailbox.ú:NTc                 C   s¬   t  | |||¡ tj | jd¡tj | jd¡tj | jd¡dœ| _tj | j¡sE|r@t | jd¡ | j 	¡ D ]}t |d¡ q6nt
| jƒ‚i | _dddœ| _d| _d| _d	S )
zInitialize a Maildir instance.ÚtmpÚnewÚcur)rŸ   r    r¡   éÀ  r   )r¡   r    gš™™™™™¹?N)r   r!   r   r   Újoinr   Ú_pathsÚexistsÚmkdirrR   r   Ú_tocÚ_toc_mtimesÚ
_last_readÚ_skewfactor)r   Údirnamer   r   r   r   r   r    r!     s    ýÿ

zMaildir.__init__c              
   C   sf  |   ¡ }z|  ||¡ W n ty   | ¡  t |j¡ ‚ w t|ƒ t|t	ƒr;| 
¡ }| j| ¡  }|| jkr:d}nd}d}tj |j¡ | j¡d }tj | j||| ¡}t|t	ƒrlt |jtj |j¡| ¡ f¡ z'z	t |j|¡ W n ttfyŠ   t |j|¡ Y W |S w t |j¡ W |S  ty² } zt |j¡ |jtjkr­td| ƒ‚‚ d}~ww )r#   Ú r    r   z$Name clash with existing message: %sN)Ú_create_tmpr•   ÚBaseExceptionrh   r   r.   ÚnameÚ_sync_closerz   r
   Ú
get_subdirÚcolonÚget_infor   ÚbasenameÚsplitr£   r   ÚutimeÚgetatimeÚget_dateÚlinkÚAttributeErrorÚPermissionErrorÚrenameÚOSErrorÚerrnoÚEEXISTr   )r   r(   Ztmp_fileÚsubdirÚsuffixÚuniqÚdestÚer   r   r    r)   $  sR   ý

€
ÿ
õùÿ€úzMaildir.addc                 C   s    t  t j | j|  |¡¡¡ dS ©r+   N)r   r.   r   r£   r   Ú_lookupr,   r   r   r    r.   N  s    zMaildir.removec              	   C   s*   z|   |¡ W dS  ttfy   Y dS w r1   )r.   r2   ÚFileNotFoundErrorr,   r   r   r    r3   R  s
   ÿzMaildir.discardc                 C   sÊ   |   |¡}|  |¡}|   |¡}t|tƒr|}n|}tj |¡}| j|v r0| j| | j¡d  }nd}|  	|¡ tj 
| j|¡}	tj 
| j||| ¡}
t|tƒr]t |	tj |	¡| ¡ f¡ t |	|
¡ dS )r4   rv   r¬   N)rÆ   r)   rz   r
   r   r   r«   r²   rµ   r3   r£   r   r¶   r·   r¸   r¼   )r   r-   r(   Zold_subpathZtemp_keyZtemp_subpathZdominant_subpathrÀ   rÁ   Ztmp_pathÚnew_pathr   r   r    r6   Z  s$   






ÿzMaildir.__setitem__c                 C   s¶   |   |¡}ttj | j|¡dƒ}| jr|  |¡}nt|ƒ}W d  ƒ n1 s(w   Y  tj |¡\}}| 	|¡ | j
|v rJ| | | j
¡d ¡ | tj tj | j|¡¡¡ |S )r?   ÚrbNrv   )rÆ   Úopenr   r   r£   r   r   r
   rµ   Ú
set_subdirr²   Úset_infoÚset_dateÚgetmtime)r   r-   ÚsubpathÚfÚmsgrÀ   r¯   r   r   r    r:   u  s   
€ü

zMaildir.get_messagec                 C   sP   t tj | j|  |¡¡dƒ}| ¡  td¡W  d  ƒ S 1 s!w   Y  dS )ú2Return a bytes representation or raise a KeyError.rÉ   rm   N)	rÊ   r   r   r£   r   rÆ   rp   r   r‚   ©r   r-   rÐ   r   r   r    rC   „  s   $ÿzMaildir.get_bytesc                 C   s$   t tj | j|  |¡¡dƒ}t|ƒS )rE   rÉ   )rÊ   r   r   r£   r   rÆ   Ú
_ProxyFilerÓ   r   r   r    r=   ‰  s   zMaildir.get_filec              	   c   sB    |   ¡  | jD ]}z|  |¡ W n	 ty   Y qw |V  qdS ©rF   N)Ú_refreshr§   rÆ   r2   r,   r   r   r    rH   Ž  s   €
ÿûzMaildir.iterkeysc                 C   ó   |   ¡  || jv S ©rU   )rÖ   r§   r,   r   r   r    rV   ˜  ó   
zMaildir.__contains__c                 C   ó   |   ¡  t| jƒS ©rW   )rÖ   Úlenr§   rG   r   r   r    rX     rÙ   zMaildir.__len__c                 C   ó   dS )ú"Write any pending changes to disk.Nr   rG   r   r   r    rb   ¢  s   zMaildir.flushc                 C   rÝ   )rc   Nr   rG   r   r   r    rd   ¨  ó   zMaildir.lockc                 C   rÝ   )re   Nr   rG   r   r   r    rf   ¬  rß   zMaildir.unlockc                 C   rÝ   ©rg   Nr   rG   r   r   r    rh   °  rß   zMaildir.closec                 C   s\   g }t  | j¡D ]#}t|ƒdkr+|d dkr+t j t j | j|¡¡r+| |dd… ¡ q|S )úReturn a list of folder names.é   r   Ú.N)r   Úlistdirr   rÜ   r   Úisdirr£   Úappend©r   rZ   Úentryr   r   r    Úlist_folders´  s   ÿ€zMaildir.list_foldersc                 C   s    t tj | jd| ¡| jddS )z/Return a Maildir instance for the named folder.rã   F©r   r   )r   r   r   r£   r   r   ©r   Úfolderr   r   r    Ú
get_folder½  s   þzMaildir.get_folderc                 C   s\   t j | jd| ¡}t|| jd}t j |d¡}t j |¡s,t  t  |t j	t j
B d¡¡ |S )z>Create a folder and return a Maildir instance representing it.rã   ©r   Zmaildirfolderé¶  )r   r   r£   r   r   r   r¥   rh   rÊ   ÚO_CREATÚO_WRONLY)r   rì   r   rZ   Zmaildirfolder_pathr   r   r    Ú
add_folderÃ  s   ÿzMaildir.add_folderc                 C   s  t j | jd| ¡}t  t j |d¡¡t  t j |d¡¡ D ]}t|ƒdk s,|d dkr2td| ƒ‚qt  |¡D ]!}|dkrY|dkrY|dkrYt j t j ||¡¡rYtd||f ƒ‚q8t j|d	d
D ]#\}}}|D ]}t  	t j ||¡¡ qh|D ]}t  
t j ||¡¡ qwqat  
|¡ dS )ú-Delete the named folder, which must be empty.rã   r    r¡   râ   r   zFolder contains message(s): %srŸ   z%Folder contains subdirectory '%s': %sF)ÚtopdownN)r   r   r£   r   rä   rÜ   r   rå   Úwalkr.   Úrmdir)r   rì   r   rè   ÚrootÚdirsÚfilesr   r   r    Úremove_folderÍ  s,   ÿÿÿÿ€ÿzMaildir.remove_folderc                 C   sX   t   ¡ }t tj | jd¡¡D ]}tj | jd|¡}|tj |¡ dkr)t |¡ qdS )zDelete old files in "tmp".rŸ   i@ú N)Útimer   rä   r   r£   r   r·   r.   )r   Únowrè   r   r   r   r    Úcleanà  s   
€ýzMaildir.cleanrâ   c                 C   sÐ   t   ¡ }t ¡ }d|v r| dd¡}d|v r| dd¡}dt|ƒt|d d ƒt ¡ tj|f }tj	 
| jd|¡}zt |¡ W n! tya   t jd7  _zt|ƒW  Y S  ty^   Y nw Y nw td	| ƒ‚)
z=Create a file in the tmp subdirectory and open and return it.ú/z\057rž   z\072z%s.M%sP%sQ%s.%srâ   g    €„.ArŸ   z&Name clash prevented file creation: %s)rû   ÚsocketÚgethostnamer   Úintr   Úgetpidr   Ú_countr   r£   r   ÚstatrÇ   Ú_create_carefullyÚFileExistsErrorr   )r   rü   ÚhostnamerÂ   r   r   r   r    r­   ê  s0   ÿÿûÿzMaildir._create_tmpc                 C   sØ   t   ¡ | j d| j kr/d}| jD ]}tj | j| ¡}|| j| kr%d}|| j|< q|s/dS i | _| jD ]/}| j| }t 	|¡D ]"}tj 
||¡}tj |¡rQqA| | j¡d }tj 
||¡| j|< qAq5t   ¡ | _dS )z!Update table of contents mapping.é   FTNr   )rû   r©   rª   r¨   r   r   rÎ   r¤   r§   rä   r£   rå   rµ   r²   )r   ZrefreshrÀ   Úmtimer   rè   ÚprÂ   r   r   r    rÖ     s(   


ûzMaildir._refreshc                 C   st   zt j t j | j| j| ¡¡r| j| W S W n	 ty    Y nw |  ¡  z| j| W S  ty9   td| ƒd‚w )z=Use TOC to return subpath for given key, or raise a KeyError.úNo message with key: %sN)r   r   r¥   r£   r   r§   r2   rÖ   r,   r   r   r    rÆ   &  s   ÿÿÿzMaildir._lookupc                 C   sL   t | dƒs
|  ¡ | _	 z| t| jƒ W S  ty   Y dS  ty%   Y q
w )z0Return the next message in a one-time iteration.Ú_onetime_keysTN)r]   rH   r  ÚnextÚStopIterationr2   rG   r   r   r    r  4  s   

ÿzMaildir.nextr–   )r˜   r™   rš   r›   r²   r!   r)   r.   r3   r6   r:   rC   r=   rH   rV   rX   rb   rd   rf   rh   ré   rí   rò   rú   rý   r  r­   rÖ   rÆ   r  r   r   r   r    r     s8    
*
	
$r   c                   @   s”   e Zd ZdZd$dd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd%d d!„Zd"d#„ ZdS )&Ú_singlefileMailboxzA single-file mailbox.NTc              
   C   s¾   t  | |||¡ zt| jdƒ}W n7 tyG } z+|jtjkr,|r't| jdƒ}nt| jƒ‚|jtjtj	fv r<t| jdƒ}n‚ W Y d}~nd}~ww || _
d| _d| _d| _d| _d| _d| _dS )z!Initialize a single-file mailbox.úrb+zwb+rÉ   Nr   F)r   r!   rÊ   r   r½   r¾   ÚENOENTr   ÚEACCESÚEROFSÚ_filer§   Ú	_next_keyÚ_pendingÚ_pending_syncÚ_lockedÚ_file_length)r   r   r   r   rÐ   rÄ   r   r   r    r!   D  s(   
€÷

z_singlefileMailbox.__init__c                 C   s8   |   ¡  |  |¡| j| j< |  jd7  _d| _| jd S )r#   râ   T)rÆ   Ú_append_messager§   r  r  r'   r   r   r    r)   [  s
   
z_singlefileMailbox.addc                 C   s   |   |¡ | j|= d| _dS )r+   TN)rÆ   r§   r  r,   r   r   r    r.   e  s   

z_singlefileMailbox.removec                 C   s$   |   |¡ |  |¡| j|< d| _dS )r4   TN)rÆ   r  r§   r  r5   r   r   r    r6   k  s   

z_singlefileMailbox.__setitem__c                 c   s    |   ¡  | j ¡ E dH  dS rÕ   )rÆ   r§   rK   rG   r   r   r    rH   q  s   €z_singlefileMailbox.iterkeysc                 C   r×   rØ   )rÆ   r§   r,   r   r   r    rV   v  rÙ   z_singlefileMailbox.__contains__c                 C   rÚ   rÛ   )rÆ   rÜ   r§   rG   r   r   r    rX   {  rÙ   z_singlefileMailbox.__len__c                 C   s   | j st| jƒ d| _ dS dS )rc   TN)r  Ú
_lock_filer  rG   r   r   r    rd   €  ó   

þz_singlefileMailbox.lockc                 C   s   | j rt| jƒ d| _ dS dS ©re   FN)r  Ú_unlock_filer  rG   r   r   r    rf   †  r  z_singlefileMailbox.unlockc           
      C   sÐ  | j s| jrt| jƒ d| _dS | j dd¡ | j ¡ }|| jkr*td| j|f ƒ‚t| j	ƒ}zSi }|  
|¡ t| j ¡ ƒD ]=}| j| \}}| j |¡ |  |¡ | ¡ }	 | j td|| j ¡  ƒ¡}|shn| |¡ qW|| ¡ f||< |  |¡ q>| ¡ | _W n   | ¡  t |j¡ ‚ t|ƒ | j ¡  t | j	¡j}	t |j|	¡ z
t |j| j	¡ W n tyÉ   t | j	¡ t |j| j	¡ Y nw t| j	dƒ| _|| _d| _ d| _| jræt| jdd	 dS dS )
rÞ   FNr   r  z4Size of mailbox file changed (expected %i, found %i)Té   r  )Údotlock) r  r  Ú_sync_flushr  r€   Útellr  r   Ú_create_temporaryr   Ú_pre_mailbox_hookÚsortedr§   rK   Ú_pre_message_hookrp   Úminrƒ   Ú_post_message_hookrh   r   r.   r¯   r°   r  Úst_modeÚchmodr¼   r  rÊ   r  r  )
r   Zcur_lenZnew_fileZnew_tocr-   ÚstartÚstopZ	new_startrq   Úmoder   r   r    rb   Œ  sh   
	

þ



ÿ
û
þÿz_singlefileMailbox.flushc                 C   rÝ   )ú,Called before writing the mailbox to file f.Nr   ©r   rÐ   r   r   r    r$  Ì  rß   z$_singlefileMailbox._pre_mailbox_hookc                 C   rÝ   )ú-Called before writing each message to file f.Nr   r/  r   r   r    r&  Ð  rß   z$_singlefileMailbox._pre_message_hookc                 C   rÝ   ©ú,Called after writing each message to file f.Nr   r/  r   r   r    r(  Ô  rß   z%_singlefileMailbox._post_message_hookc                 C   s€   z#|   ¡  W z| jr|  ¡  W | j ¡  dS W | j ¡  dS | j ¡  w z| jr3|  ¡  W | j ¡  w W | j ¡  w | j ¡  w rà   )rb   r  rf   r  rh   rG   r   r   r    rh   Ø  s   

ýü
ýz_singlefileMailbox.closec                 C   sH   | j du r	|  ¡  |dur"z| j | W S  ty!   td| ƒd‚w dS )z'Return (start, stop) or raise KeyError.Nr  )r§   Ú_generate_tocr2   r,   r   r   r    rÆ   ã  s   
ÿýz_singlefileMailbox._lookupc                 C   s–   | j  dd¡ | j  ¡ }t| jƒdkr| js|  | j ¡ z|  | j ¡ |  |¡}|  	| j ¡ W n t
y=   | j  |¡ ‚ w | j  ¡  | j  ¡ | _|S )z;Append message to mailbox and return (start, stop) offsets.r   r  )r  r€   r"  rÜ   r§   r  r$  r&  Ú_install_messager(  r®   Útruncaterb   r  )r   r(   ÚbeforeZoffsetsr   r   r    r  í  s   

þ
z"_singlefileMailbox._append_messager–   r/   )r˜   r™   rš   r›   r!   r)   r.   r6   rH   rV   rX   rd   rf   rb   r$  r&  r(  rh   rÆ   r  r   r   r   r    r  A  s$    

@

r  c                   @   sB   e Zd ZdZdZdd„ Zddd„Zddd	„Zdd
d„Zdd„ Z	dS )Ú	_mboxMMDFzAn mbox or MMDF mailbox.Tc                 C   sp   |   |¡\}}| j |¡ | j ¡  td¡}| j || j ¡  ¡}|  | td¡¡}| 	|dd…  
d¡¡ |S )r?   ó    rm   rx   Nr   )rÆ   r  r€   r   r   r‚   rp   r"  Ú_message_factoryÚset_fromÚdecode)r   r-   r+  r,  Ú	from_lineÚstringrÑ   r   r   r    r:   	  s   z_mboxMMDF.get_messageFc                 C   s   t  |  ||¡¡j|dS )ú3Return a string representation or raise a KeyError.)Úunixfromr@   )r   r-   Úfrom_r   r   r    rD     s
   
ÿÿz_mboxMMDF.get_stringc                 C   sJ   |   |¡\}}| j |¡ |s| j ¡  | j || j ¡  ¡}| td¡S )r>  rm   )rÆ   r  r€   r   rp   r"  r   r‚   )r   r-   r@  r+  r,  r=  r   r   r    rC     s   
z_mboxMMDF.get_bytesc                 C   s<   |   |¡\}}| j |¡ |s| j ¡  t| j| j ¡ |ƒS )rE   )rÆ   r  r€   r   Ú_PartialFiler"  )r   r-   r@  r+  r,  r   r   r    r=   !  s
   
z_mboxMMDF.get_filec                 C   s  d}t |tƒr|  |¡}t |tƒr3| d¡r3| d¡}|dkr.|d|… }||d d… }n*|}d}n%t |tƒrD| ¡  d¡}d| }nt |t	j
jƒrX| ¡ }|durX| d¡}|du rgdt t ¡ ¡ ¡  }| j ¡ }| j |t ¡ |  || j| j¡ | j ¡ }||fS )	z1Format a message and blindly write to self._file.Nrw   rm   rv   râ   r8  r   s   From MAILER-DAEMON )rz   r†   rl   r‡   rŽ   ÚfindÚ_mboxMMDFMessageÚget_fromri   rA   r(   r	   Úget_unixfromrû   ÚasctimeÚgmtimer  r"  rƒ   r‚   r•   Ú_mangle_from_)r   r(   r<  ÚnewlineZauthorr+  r,  r   r   r    r4  )  s0   







z_mboxMMDF._install_messageNr—   )
r˜   r™   rš   r›   rH  r:   rD   rC   r=   r4  r   r   r   r    r7    s    



	r7  c                   @   s2   e Zd ZdZdZdZd
dd„Zdd„ Zdd	„ ZdS )r   zA classic mbox mailbox.TNc                 C   ó   t | _t | |||¡ dS )zInitialize an mbox mailbox.N)r   r9  r7  r!   r   r   r   r    r!   O  ó   zmbox.__init__c                 C   s   |  t¡ dS r1  ©rƒ   r‚   r/  r   r   r    r(  T  ó   zmbox._post_message_hookc                 C   sè   g g }}d}| j  d¡ 	 | j  ¡ }| j  ¡ }| d¡r>t|ƒt|ƒk r6|r1| |ttƒ ¡ n| |¡ | |¡ d}n|sR|rL| |ttƒ ¡ n| |¡ n
|tkrYd}nd}qtt	t
||ƒƒƒ| _t| jƒ| _| j  ¡ | _dS )ú0Generate key-to-(start, stop) table of contents.Fr   Trw   N)r  r€   r"  r   rŽ   rÜ   ræ   r‚   ÚdictÚ	enumerateÚzipr§   r  r  )r   ÚstartsÚstopsZlast_was_emptyÚline_posr”   r   r   r    r3  X  s2   






ézmbox._generate_tocr–   )	r˜   r™   rš   r›   rH  r„   r!   r(  r3  r   r   r   r    r   F  s    
r   c                   @   s2   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ ZdS )r   zAn MMDF mailbox.NTc                 C   rJ  )zInitialize an MMDF mailbox.N)r   r9  r7  r!   r   r   r   r    r!   }  rK  zMMDF.__init__c                 C   ó   |  dt ¡ dS )r0  ó   NrL  r/  r   r   r    r&  ‚  ó   zMMDF._pre_message_hookc                 C   s   |  td t ¡ dS )r2  rV  NrL  r/  r   r   r    r(  †  s   zMMDF._post_message_hookc                 C   sà   g g }}| j  d¡ d}	 |}| j  ¡ }| j  ¡ }| dt ¡rM| |¡ 	 |}| j  ¡ }| j  ¡ }|dt krC| |ttƒ ¡ n	|sK| |¡ nq'n|sPnqtt	t
||ƒƒƒ| _t| jƒ| _| j  dd¡ | j  ¡ | _dS )rN  r   TrV  r  N)r  r€   r   r"  rŽ   r‚   ræ   rÜ   rO  rP  rQ  r§   r  r  )r   rR  rS  Únext_posrT  r”   r   r   r    r3  Š  s8   






÷€
ïzMMDF._generate_tocr–   )r˜   r™   rš   r›   r!   r&  r(  r3  r   r   r   r    r   z  s    
r   c                   @   sÂ   e Zd ZdZd0dd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdS )1r   zAn MH mailbox.NTc                 C   st   t  | |||¡ tj | j¡s5|r0t | jd¡ t t tj 	| jd¡tj
tjB tjB d¡¡ nt| jƒ‚d| _dS )zInitialize an MH instance.r¢   ú.mh_sequencesi€  FN)r   r!   r   r   r¥   r   r¦   rh   rÊ   r£   rð   ÚO_EXCLrñ   r   r  r   r   r   r    r!   ª  s   ÿ

zMH.__init__c                 C   sú   |   ¡ }t|ƒdkrd}nt|ƒd }tj | jt|ƒ¡}t|ƒ}d}zQ| j	r+t
|ƒ z7z|  ||¡ W n tyN   | j	rBt|ƒ t|ƒ d}t |¡ ‚ w t|tƒrZ|  ||¡ W | j	rbt|ƒ n	| j	rkt|ƒ w w W |sst|ƒ |S |s|t|ƒ w w )r#   r   râ   FT)rK   rÜ   Úmaxr   r   r£   r   r†   r  r  r  r•   r®   r  r°   r.   rz   r   Ú_dump_sequences)r   r(   rK   Znew_keyrÈ   rÐ   Úclosedr   r   r    r)   ¶  sJ   
ù
€€ÿ
ÿ€þ
ÿzMH.addc              
   C   sl   t j | jt|ƒ¡}zt|dƒ}W n ty* } z|jtjkr%t	d| ƒ‚‚ d}~ww | 
¡  t  |¡ dS )r+   r  r  N)r   r   r£   r   r†   rÊ   r½   r¾   r  r2   rh   r.   )r   r-   r   rÐ   rÄ   r   r   r    r.   Ø  s   €üz	MH.removec              
   C   sà   t j | jt|ƒ¡}zt|dƒ}W n ty* } z|jtjkr%t	d| ƒ‚‚ d}~ww z?| j
r3t|ƒ z't  t  |t jt jB ¡¡ |  ||¡ t|tƒrR|  ||¡ W | j
rZt|ƒ n	| j
rct|ƒ w w W t|ƒ dS t|ƒ w )r4   r  r  N)r   r   r£   r   r†   rÊ   r½   r¾   r  r2   r  r  rh   rñ   ÚO_TRUNCr•   rz   r   r\  r  r°   )r   r-   r(   r   rÐ   rÄ   r   r   r    r6   æ  s4   €ü
€€ÿ
ÿ€zMH.__setitem__c              
   C   s   z | j rttj | jt|ƒ¡dƒ}nttj | jt|ƒ¡dƒ}W n ty9 } z|jtj	kr4t
d| ƒ‚‚ d}~ww |& | j rDt|ƒ zt|ƒ}W | j rQt|ƒ n	| j rZt|ƒ w w W d  ƒ n1 sew   Y  |  ¡  ¡ D ]\}}||v r}| |¡ qp|S )r?   r  rÉ   r  N)r  rÊ   r   r   r£   r   r†   r½   r¾   r  r2   r  r   r  Úget_sequencesrT   Úadd_sequence)r   r-   rÐ   rÄ   rÑ   r¯   Úkey_listr   r   r    r:   þ  s:   €€ü
€ÿ
ÿ€ú
€zMH.get_messagec              
   C   sÞ   z | j rttj | jt|ƒ¡dƒ}nttj | jt|ƒ¡dƒ}W n ty9 } z|jtj	kr4t
d| ƒ‚‚ d}~ww |) | j rDt|ƒ z| ¡  td¡W | j rTt|ƒ W  d  ƒ S | j rdt|ƒ w w 1 shw   Y  dS )rÒ   r  rÉ   r  Nrm   )r  rÊ   r   r   r£   r   r†   r½   r¾   r  r2   r  rp   r   r‚   r  ©r   r-   rÐ   rÄ   r   r   r    rC     s.   €€üù
ÿúzMH.get_bytesc              
   C   sX   zt tj | jt|ƒ¡dƒ}W t
|ƒS  ty+ } z|jtjkr&t	d| ƒ‚‚ d}~ww )rE   rÉ   r  N)rÊ   r   r   r£   r   r†   r½   r¾   r  r2   rÔ   rb  r   r   r    r=   ,  s   û€üzMH.get_filec                 C   s   t tdd„ t | j¡D ƒƒƒS )rF   c                 s   s     | ]}|  ¡ rt|ƒV  qd S r/   )Úisdigitr  )Ú.0rè   r   r   r    Ú	<genexpr>9  s   € ÿzMH.iterkeys.<locals>.<genexpr>)Úiterr%  r   rä   r   rG   r   r   r    rH   7  s   zMH.iterkeysc                 C   s   t j t j | jt|ƒ¡¡S rØ   )r   r   r¥   r£   r   r†   r,   r   r   r    rV   <  s   zMH.__contains__c                 C   s   t t|  ¡ ƒƒS rÛ   )rÜ   rJ   rH   rG   r   r   r    rX   @  ó   z
MH.__len__c                 C   s6   | j sttj | jd¡dƒ| _t| jƒ d| _ dS dS )rc   rY  r  TN)r  rÊ   r   r   r£   r   r  r  rG   r   r   r    rd   D  s
   

ýzMH.lockc                 C   s,   | j rt| jƒ t| jƒ | `d| _ dS dS r  )r  r  r  r°   rG   r   r   r    rf   K  s   


üz	MH.unlockc                 C   rÝ   )ra   Nr   rG   r   r   r    rb   S  rß   zMH.flushc                 C   s   | j r	|  ¡  dS dS rà   )r  rf   rG   r   r   r    rh   W  s   ÿzMH.closec                 C   s<   g }t  | j¡D ]}t j t j | j|¡¡r| |¡ q|S )rá   )r   rä   r   r   rå   r£   ræ   rç   r   r   r    ré   \  s   
€zMH.list_foldersc                 C   s   t tj | j|¡| jddS )z+Return an MH instance for the named folder.Frê   ©r   r   r   r£   r   r   rë   r   r   r    rí   d  s   ÿzMH.get_folderc                 C   s   t tj | j|¡| jdS )z:Create a folder and return an MH instance representing it.rî   rh  rë   r   r   r    rò   i  s   ÿzMH.add_folderc                 C   s`   t j | j|¡}t  |¡}|dgkrt  t j |d¡¡ n|g kr"ntd| j ƒ‚t  |¡ dS )ró   rY  zFolder not empty: %sN)r   r   r£   r   rä   r.   r   rö   )r   rì   r   Úentriesr   r   r    rú   n  s   

zMH.remove_folderc           
   
      s  i }t tj | jd¡dddp}t|  ¡ ƒ‰ |D ]^}zM| d¡\}}tƒ }| ¡ D ]$}| ¡ r7| 	t
|ƒ¡ q)dd„ | d¡D ƒ\}}	| t||	d	 ƒ¡ q)‡ fd
d„t|ƒD ƒ||< t|| ƒdkrf||= W q tyv   td| ¡  ƒ‚w W d  ƒ |S 1 s‚w   Y  |S )z=Return a name-to-key-list dictionary to define each sequence.rY  ÚrÚASCII©Úencodingrž   c                 s   s    | ]}t |ƒV  qd S r/   )r  )rd  Úxr   r   r    re  ‡  ó   € z#MH.get_sequences.<locals>.<genexpr>ú-râ   c                    s   g | ]}|ˆ v r|‘qS r   r   )rd  r-   ©Zall_keysr   r    Ú
<listcomp>‰  s    ÿz$MH.get_sequences.<locals>.<listcomp>r   z"Invalid sequence specification: %sN)rÊ   r   r   r£   r   ÚsetrK   rµ   rc  r)   r  r`   Úranger%  rÜ   rk   r   Úrstrip)
r   ÚresultsrÐ   r”   r¯   ÚcontentsrK   Úspecr+  r,  r   rq  r    r_  z  s4   €ÿÿò
þízMH.get_sequencesc                 C   s  t tj | jd¡ddd}zqt t  |jtjtjB ¡¡ | 	¡ D ]W\}}t
|ƒdkr+q | |d ¡ d}d}tt|ƒƒD ])}|d	 |krN|sMd
}| d¡ n|r\d}| d||f ¡ n| d| ¡ |}q<|rr| t|ƒd ¡ q | d¡ q W t|ƒ dS t|ƒ w )z:Set sequences using the given name-to-key-list dictionary.rY  zr+rk  rl  r   rž   NFrâ   Trp  z%s %sz %sÚ
)rÊ   r   r   r£   r   rh   r¯   rñ   r^  rT   rÜ   rƒ   r%  rs  r†   r°   )r   Ú	sequencesrÐ   r¯   rK   ÚprevZ
completingr-   r   r   r    Úset_sequences’  s2   
€ìzMH.set_sequencesc           	      C   s8  |   ¡ }d}g }|  ¡ D ]`}|d |krh| ||d f¡ zt tj | jt|ƒ¡tj | jt|d ƒ¡¡ W n# t	t
fyZ   t tj | jt|ƒ¡tj | jt|d ƒ¡¡ Y nw t tj | jt|ƒ¡¡ |d7 }q|d | _t|ƒdkrzdS | ¡ D ]\}}|D ]\}}||v r“||| |¡< q„q~|  |¡ dS )z?Re-name messages to eliminate numbering gaps. Invalidates keys.r   râ   N)r_  rH   ræ   r   r¹   r   r£   r   r†   rº   r»   r¼   Úunlinkr  rÜ   rT   Úindexr|  )	r   rz  r{  Zchangesr-   r¯   ra  Úoldr    r   r   r    Úpack¯  s6   ÿÿÿ

€þzMH.packc                 C   st   |  ¡ }|   ¡ }| ¡ D ]\}}||v r| |¡ q||v r$|| |¡= q|D ]}||vr2|g||< q'|  |¡ dS )z;Inspect a new MHMessage and update sequences appropriately.N)r_  rT   ræ   r~  r|  )r   r(   r-   Zpending_sequencesZall_sequencesr¯   ra  Úsequencer   r   r    r\  É  s   €
€zMH._dump_sequencesr–   )r˜   r™   rš   r›   r!   r)   r.   r6   r:   rC   r=   rH   rV   rX   rd   rf   rb   rh   ré   rí   rò   rú   r_  r|  r€  r\  r   r   r   r    r   §  s0    
"r   c                   @   s†   e Zd ZdZeh d£ƒZddd„Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS ) r   zAn Rmail-style Babyl mailbox.>   ÚdeletedZeditedZfiledÚresentÚansweredÚunseenÚ	forwardedNTc                 C   s   t  | |||¡ i | _dS )zInitialize a Babyl mailbox.N)r  r!   Ú_labelsr   r   r   r    r!   Þ  s   
zBabyl.__init__c                 C   s(   t  | |¡}t|tƒr| ¡ | j|< |S )r#   )r  r)   rz   r   Ú
get_labelsr‡  )r   r(   r-   r   r   r    r)   ã  s   
z	Babyl.addc                 C   s&   t  | |¡ || jv r| j|= dS dS rÅ   )r  r.   r‡  r,   r   r   r    r.   ê  s   
ÿzBabyl.removec                 C   s.   t  | ||¡ t|tƒr| ¡ | j|< dS dS )r4   N)r  r6   rz   r   rˆ  r‡  r5   r   r   r    r6   ð  s   
ÿzBabyl.__setitem__c           
      C   sö   |   |¡\}}| j |¡ | j ¡  t ¡ }	 | j ¡ }|dt ks$|s%n
| | td¡¡ qt ¡ }	 | j ¡ }|tks?|s@n
| | td¡¡ q4|| j 	¡  }| j 
|¡}| td¡}t| ¡ | ƒ}	|	 | ¡ ¡ || jv ry|	 | j| ¡ |	S )r?   Tó   *** EOOH ***rm   )rÆ   r  r€   r   r{   r|   r‚   rƒ   r   r"  rp   r   rŒ   Úset_visibler‡  Ú
set_labels)
r   r-   r+  r,  Úoriginal_headersr”   Zvisible_headersÚnÚbodyrÑ   r   r   r    r:   ö  s2   

ü
ü
zBabyl.get_messagec           	      C   s°   |   |¡\}}| j |¡ | j ¡  t ¡ }	 | j ¡ }|dt ks$|s%n
| | td¡¡ q	 | j ¡ }|tks;|s<nq0| 	¡ }|| j 
¡  }| j |¡}| td¡}|| S )r>  Tr‰  rm   )rÆ   r  r€   r   r{   r|   r‚   rƒ   r   rŒ   r"  rp   )	r   r-   r+  r,  rŒ  r”   Zheadersr  r“   r   r   r    rC     s(   

ü
ýzBabyl.get_bytesc                 C   s   t  |  |¡ dt¡¡S )rE   rm   )r{   r|   rC   r   r‚   r,   r   r   r    r=   (  ó   zBabyl.get_filec                 C   s<   |   ¡  tƒ }| j ¡ D ]}| |¡ q| | j¡ t|ƒS )z4Return a list of user-defined labels in the mailbox.)rÆ   rs  r‡  rR   r`   Údifference_updateÚ_special_labelsrJ   )r   ÚlabelsZ
label_listr   r   r    rˆ  ,  s   zBabyl.get_labelsc                 C   s<  g g }}| j  d¡ d}g }	 |}| j  ¡ }| j  ¡ }|dt krOt|ƒt|ƒk r3| |ttƒ ¡ | |¡ dd„ | j  ¡ dd…  d¡D ƒ}| |¡ n(|d	ksY|d	t krkt|ƒt|ƒk rj| |ttƒ ¡ n|sw| |ttƒ ¡ nqtt	t
||ƒƒƒ| _tt	|ƒƒ| _t| jƒ| _| j  dd
¡ | j  ¡ | _dS )rN  r   Ts   c                 S   s   g | ]
}|  ¡ r|  ¡ ‘qS r   )Ústrip©rd  Úlabelr   r   r    rr  C  s    þz'Babyl._generate_toc.<locals>.<listcomp>râ   Nó   ,ó   r  )r  r€   r   r"  r‚   rÜ   ræ   rµ   rO  rP  rQ  r§   r‡  r  r  )r   rR  rS  rX  Zlabel_listsrT  r”   r’  r   r   r    r3  5  s:   



ÿ€ïzBabyl._generate_tocc                 C   sV   dt  }|dt  7 }|  ¡ }dd„ |D ƒ}|dd |¡ t  7 }|d7 }| |¡ dS )	r.  s   BABYL OPTIONS:s
   Version: 5c                 s   s    | ]}|  ¡ V  qd S r/   )ri   r”  r   r   r    re  X  ro  z*Babyl._pre_mailbox_hook.<locals>.<genexpr>s   Labels:r–  r—  N)r‚   rˆ  r£   rƒ   )r   rÐ   Zbabylr’  r   r   r    r$  S  s   zBabyl._pre_mailbox_hookc                 C   rU  )r0  ó   NrL  r/  r   r   r    r&  ]  rW  zBabyl._pre_message_hookc                 C   s   |  td ¡ dS )r2  r—  NrL  r/  r   r   r    r(  a  rW  zBabyl._post_message_hookc                 C   s`  | j  ¡ }t|tƒrXg }g }| ¡ D ]}|| jv r| |¡ q| |¡ q| j  d¡ |D ]}| j  d| ¡  ¡ q-| j  d¡ |D ]}| j  d| ¡  d ¡ qB| j  t	¡ n| j  dt	 ¡ t|t
jjƒrþt ¡ }t
j |dd¡}| |¡ | d¡ 	 | ¡ }| j  | d
t	¡¡ |d
ks’|s“nq~| j  dt	 ¡ t|tƒrÌt ¡ }	t
j |	dd¡}
|
 | ¡ ¡ 	 |	 ¡ }| j  | d
t	¡¡ |d
ksÉ|sÊnqµn| d¡ 	 | ¡ }| j  | d
t	¡¡ |d
ksæ|sçnqÒ	 | d¡}|sñn| j  | d
t	¡¡ qén)t|tttjfƒr{t|tjƒrt dtd¡ | ¡ }t|tƒr%|  |¡}| d¡d }|d dkrf| j  |d|…  d
t	¡¡ | j  dt	 ¡ | j  |d|…  d
t	¡¡ | j  ||d…  d
t	¡¡ nÁ| j  dt	 t	 ¡ | j  | d
t	¡¡ n¬t |dƒrt |dƒr‘t dtd¡ |j!}| ¡ }d	}	 | ¡ }| "d¡r«|dd… d
 }n| "d¡r¹|dd… d
 }| j  | d
t	¡¡ |d
ksË|sß|rÞd}| j  dt	 ¡ | |¡ nnq˜	 | ¡ }|sên4| "d¡rù|dd… t	 }n| "d¡r|dd… t	 }n| "d
¡r|dd… t	 }| j  |¡ qânt#dt$|ƒ ƒ‚| j  ¡ }||fS )z0Write message contents and return (start, stop).ó   1s   , s   ,,ó    r–  s   1,,Fr   Trm   r‰  r  rn   ro   s   

r  rv   Nr   rq   rr   rs   rt   ru   ry   )%r  r"  rz   r   rˆ  r‘  ræ   rƒ   ri   r‚   rA   r(   r	   r{   r|   r}   r~   r   r€   r   r   Úget_visiblerp   r‡   r†   rˆ   r‰   rŠ   r‹   rŒ   rl   rB  r]   rq   r…   r   r   )r   r(   r+  Zspecial_labelsr’  r•  Zorig_bufferZorig_generatorr”   Z
vis_bufferZvis_generatorrq   Z
body_startZoriginal_posZ
first_passr,  r   r   r    r4  e  sÖ   




ü
ü
ü
üÿ
ÿòõ

zBabyl._install_messager–   )r˜   r™   rš   r›   Ú	frozensetr‘  r!   r)   r.   r6   r:   rC   r=   rˆ  r3  r$  r&  r(  r4  r   r   r   r    r   Ø  s     
	
r   c                   @   s*   e Zd ZdZd	dd„Zdd„ Zdd„ ZdS )
r	   z0Message with mailbox-format-specific properties.Nc                 C   sÞ   t |tjjƒr|  t |¡¡ t |tƒr| | ¡ dS dS t |tƒr,|  t 	|¡¡ dS t |t
ƒr;|  t |¡¡ dS t |tjƒrK|  t |¡¡ dS t|dƒrZ|  t |¡¡ dS |du rgtjj | ¡ dS tdt|ƒ ƒ‚)zInitialize a Message instance.rp   Nry   )rz   rA   r(   r	   Ú_become_messageÚcopyÚdeepcopyÚ_explain_tor‡   rB   r†   Zmessage_from_stringr{   ÚTextIOWrapperZmessage_from_filer]   Zmessage_from_binary_filer!   r   r   r'   r   r   r    r!   Ô  s    
ÿ


zMessage.__init__c                 C   s4   t |dg ƒ}|jD ]}||vr|j| | j|< q	dS )z0Assume the non-format-specific state of message.Ú_type_specific_attributesN)ÚgetattrÚ__dict__)r   r(   Ztype_specificr¯   r   r   r    r  ç  s   
€þzMessage._become_messagec                 C   s   t |tƒrdS tdƒ‚)z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)rz   r	   r   r'   r   r   r    r   î  s   
zMessage._explain_tor/   )r˜   r™   rš   r›   r!   r  r   r   r   r   r    r	   Ñ  s
    
r	   c                   @   sz   e Zd ZdZg d¢Zddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )r
   z)Message with Maildir-specific properties.)Ú_subdirÚ_infoÚ_dateNc                 C   s&   d| _ d| _t ¡ | _t | |¡ dS )z%Initialize a MaildirMessage instance.r    r¬   N)r¥  r¦  rû   r§  r	   r!   r'   r   r   r    r!   û  s   
zMaildirMessage.__init__c                 C   ó   | j S )zReturn 'new' or 'cur'.)r¥  rG   r   r   r    r±     ó   zMaildirMessage.get_subdirc                 C   s&   |dks|dkr|| _ dS td| ƒ‚)zSet subdir to 'new' or 'cur'.r    r¡   z!subdir must be 'new' or 'cur': %sN)r¥  rk   )r   rÀ   r   r   r    rË     s   
zMaildirMessage.set_subdirc                 C   s   | j  d¡r| j dd… S dS )ú*Return as a string the flags that are set.ú2,r  Nr¬   )r¦  rŽ   rG   r   r   r    Ú	get_flags  s   zMaildirMessage.get_flagsc                 C   s   dd  t|ƒ¡ | _dS )ú)Set the given flags and unset all others.r«  r¬   N)r£   r%  r¦  )r   Úflagsr   r   r    Ú	set_flags  r  zMaildirMessage.set_flagsc                 C   ó$   |   d t|  ¡ ƒt|ƒB ¡¡ dS ©z.Set the given flag(s) without changing others.r¬   N©r¯  r£   rs  r¬  ©r   Úflagr   r   r    Úadd_flag  ó   $zMaildirMessage.add_flagc                 C   s0   |   ¡ r|  d t|   ¡ ƒt|ƒ ¡¡ dS dS )ú7Unset the given string flag(s) without changing others.r¬   N)r¬  r¯  r£   rs  r³  r   r   r    Úremove_flag  s   $ÿzMaildirMessage.remove_flagc                 C   r¨  )z<Return delivery date of message, in seconds since the epoch.)r§  rG   r   r   r    r¸   !  r©  zMaildirMessage.get_datec                 C   s.   zt |ƒ| _W dS  ty   td| ƒd‚w )z9Set delivery date of message, in seconds since the epoch.zcan't convert to float: %sN)Úfloatr§  rk   r   )r   Údater   r   r    rÍ   %  s
   ÿzMaildirMessage.set_datec                 C   r¨  )z%Get the message's "info" as a string.)r¦  rG   r   r   r    r³   ,  r©  zMaildirMessage.get_infoc                 C   s$   t |tƒr
|| _dS tdt|ƒ ƒ‚)z Set the message's "info" string.zinfo must be a string: %sN)rz   r†   r¦  r   r   )r   Úinfor   r   r    rÌ   0  s   

zMaildirMessage.set_infoc                 C   sž  t |tƒr| |  ¡ ¡ | |  ¡ ¡ | |  ¡ ¡ dS t |tƒrct	|  ¡ ƒ}d|v r0| 
d¡ |  ¡ dkr;| 
d¡ d|v rD| 
d¡ d|v rM| 
d¡ d|v rV| 
d¡ | d	t |  ¡ ¡¡ dS t |tƒrt	|  ¡ ƒ}d|vrw| d
¡ d|v r€| d¡ d|v r‹| d¡ dS dS t |tƒrÀt	|  ¡ ƒ}d|vr¡| d
¡ d|v rª| d¡ d|v r³| d¡ d|v r¾| d¡ dS dS t |tƒrÇdS tdt|ƒ ƒ‚)z;Copy Maildir-specific state to message insofar as possible.ÚSÚRr¡   ÚOÚTÚDÚFÚAúMAILER-DAEMONr…  ÚrepliedÚflaggedr‚  r„  ÚPr†  ú$Cannot convert to specified type: %sN)rz   r
   r¯  r¬  rË   r±   rÍ   r¸   rC  rs  rµ  r:  rû   rG  r   r`  r   Ú	add_labelr	   r   r   )r   r(   r®  r   r   r    r   7  sT   









ÿ



ÿ
ÿzMaildirMessage._explain_tor/   )r˜   r™   rš   r›   r¢  r!   r±   rË   r¬  r¯  rµ  r¸  r¸   rÍ   r³   rÌ   r   r   r   r   r    r
   ö  s    
r
   c                   @   sZ   e Zd ZdZdgZddd„Zdd„ Zddd	„Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )rC  z/Message with mbox- or MMDF-specific properties.Ú_fromNc                 C   sV   |   dd¡ t|tjjƒr#| ¡ }|dur#| d¡r#|   |dd… ¡ t | |¡ dS )z'Initialize an mboxMMDFMessage instance.rÃ  TNzFrom rx   )r:  rz   rA   r(   r	   rE  rŽ   r!   )r   r(   r?  r   r   r    r!   h  s   z_mboxMMDFMessage.__init__c                 C   r¨  )z Return contents of "From " line.)rÉ  rG   r   r   r    rD  q  r©  z_mboxMMDFMessage.get_fromc                 C   s4   |dur|du rt  ¡ }|dt  |¡ 7 }|| _dS )z>Set "From " line, formatting and appending time_ if specified.NTú )rû   rG  rF  rÉ  )r   r@  Ztime_r   r   r    r:  u  s
   
z_mboxMMDFMessage.set_fromc                 C   s   |   dd¡|   dd¡ S )rª  ÚStatusr¬   úX-Status)r9   rG   r   r   r    r¬  }  r  z_mboxMMDFMessage.get_flagsc                 C   sÎ   t |ƒ}d\}}dD ]}||v r||7 }| |¡ q
dD ]}||v r+||7 }| |¡ q|d t|ƒ¡7 }z|  d|¡ W n tyL   |  d|¡ Y nw z	|  d|¡ W dS  tyf   |  d|¡ Y dS w )r­  )r¬   r¬   )r½  r¾  )rÀ  rÁ  rÂ  r¬   rË  rÌ  N)rs  r.   r£   r%  Úreplace_headerr2   Z
add_header)r   r®  Zstatus_flagsZxstatus_flagsr´  r   r   r    r¯    s.   
€
€ÿÿz_mboxMMDFMessage.set_flagsc                 C   r°  r±  r²  r³  r   r   r    rµ  —  r¶  z_mboxMMDFMessage.add_flagc                 C   s8   d| v sd| v r|   d t|  ¡ ƒt|ƒ ¡¡ dS dS )r·  rË  rÌ  r¬   Nr²  r³  r   r   r    r¸  ›  s   $ÿz_mboxMMDFMessage.remove_flagc              	   C   sÎ  t |tƒrgt|  ¡ ƒ}d|v r| d¡ d|v r| d¡ d|v r&| d¡ d|v r/| d¡ d|v r8| d¡ |d	= |d
= d |  ¡  ¡ dd… ¡}z| 	t
 t |d¡¡¡ W dS  ttfyf   Y dS w t |tƒr|| |  ¡ ¡ | |  ¡ ¡ dS t |tƒrªt|  ¡ ƒ}d|vr| d¡ d|v r™| d¡ d|v r¢| d¡ |d	= |d
= dS t |tƒrØt|  ¡ ƒ}d|vr¾| d¡ d|v rÇ| d¡ d|v rÐ| d¡ |d	= |d
= dS t |tƒrßdS tdt|ƒ ƒ‚)zACopy mbox- or MMDF-specific state to message insofar as possible.r¾  r¡   rÁ  rÂ  r½  r¼  rÀ  r¿  Ústatuszx-statusrÊ  éûÿÿÿNz%a %b %d %H:%M:%S %Yr…  rÄ  rÅ  r‚  r„  rÇ  )rz   r
   rs  r¬  rË   rµ  r£   rD  rµ   rÍ   ÚcalendarZtimegmrû   Ústrptimerk   ÚOverflowErrorrC  r¯  r:  r   r`  r   rÈ  r	   r   r   )r   r(   r®  Z
maybe_dater   r   r    r      sd   





ÿÿ











ÿz_mboxMMDFMessage._explain_tor/   )r˜   r™   rš   r›   r¢  r!   rD  r:  r¬  r¯  rµ  r¸  r   r   r   r   r    rC  c  s    
	
rC  c                   @   ó   e Zd ZdZdS )r   z&Message with mbox-specific properties.N©r˜   r™   rš   r›   r   r   r   r    r   Ô  ó    r   c                   @   sH   e Zd ZdZdgZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )r   z$Message with MH-specific properties.Ú
_sequencesNc                 C   s   g | _ t | |¡ dS )z!Initialize an MHMessage instance.N)rÖ  r	   r!   r'   r   r   r    r!   Ý  s   zMHMessage.__init__c                 C   ó   | j dd… S )z4Return a list of sequences that include the message.N)rÖ  rG   r   r   r    r_  â  rM  zMHMessage.get_sequencesc                 C   ó   t |ƒ| _dS )z3Set the list of sequences that include the message.N)rJ   rÖ  )r   rz  r   r   r    r|  æ  rM  zMHMessage.set_sequencesc                 C   ó8   t |tƒr|| jvr| j |¡ dS dS tdt|ƒ ƒ‚)z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rz   r†   rÖ  ræ   r   r   ©r   r  r   r   r    r`  ê  ó
   

ÿzMHMessage.add_sequencec                 C   ó(   z	| j  |¡ W dS  ty   Y dS w )zARemove sequence from the list of sequences including the message.N)rÖ  r.   rk   rÚ  r   r   r    Úremove_sequenceò  ó
   ÿzMHMessage.remove_sequencec                 C   sP  t |tƒr5t|  ¡ ƒ}d|v r| d¡ n
| d¡ | d¡ d|v r(| d¡ d|v r3| d¡ dS dS t |tƒret|  ¡ ƒ}d|vrJ| d¡ n| d	¡ d|v rX| d¡ d|v rc| d
¡ dS dS t |tƒrx|  ¡ D ]}| |¡ qndS t |t	ƒr™t|  ¡ ƒ}d|v rŒ| 
d¡ d|v r—| 
d¡ dS dS t |tƒr dS tdt|ƒ ƒ‚)z6Copy MH-specific state to message insofar as possible.r…  r¡   r¼  rÅ  rÁ  rÄ  r½  ÚROr¾  rÂ  r„  rÇ  N)rz   r
   rs  r_  rË   rµ  rC  r   r`  r   rÈ  r	   r   r   )r   r(   rz  r  r   r   r    r   ù  sJ   



ÿ


ÿ
ÿ

ÿ
ÿzMHMessage._explain_tor/   )r˜   r™   rš   r›   r¢  r!   r_  r|  r`  rÝ  r   r   r   r   r    r   Ø  s    
r   c                   @   sb   e Zd ZdZddgZddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )r   z'Message with Babyl-specific properties.r‡  Ú_visibleNc                 C   s   g | _ tƒ | _t | |¡ dS )z#Initialize a BabylMessage instance.N)r‡  r	   rà  r!   r'   r   r   r    r!   %  s   zBabylMessage.__init__c                 C   r×  )z'Return a list of labels on the message.N)r‡  rG   r   r   r    rˆ  +  rM  zBabylMessage.get_labelsc                 C   rØ  )z&Set the list of labels on the message.N)rJ   r‡  )r   r’  r   r   r    r‹  /  rM  zBabylMessage.set_labelsc                 C   rÙ  )z+Add label to list of labels on the message.zlabel must be a string: %sN)rz   r†   r‡  ræ   r   r   ©r   r•  r   r   r    rÈ  3  rÛ  zBabylMessage.add_labelc                 C   rÜ  )z4Remove label from the list of labels on the message.N)r‡  r.   rk   rá  r   r   r    Úremove_label;  rÞ  zBabylMessage.remove_labelc                 C   s
   t | jƒS )z3Return a Message representation of visible headers.©r	   rà  rG   r   r   r    r›  B  s   
zBabylMessage.get_visiblec                 C   rØ  )z2Set the Message representation of visible headers.Nrã  )r   Zvisibler   r   r    rŠ  F  rM  zBabylMessage.set_visiblec                 C   sb   | j  ¡ D ]}|| v r| j  || | ¡ q| j |= qdD ]}|| v r.|| j vr.| | | j |< qdS )z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)rà  rK   rÍ  )r   Úheaderr   r   r    Úupdate_visibleJ  s   
€þzBabylMessage.update_visiblec                 C   sx  t |tƒrBt|  ¡ ƒ}d|v r| d¡ n
| d¡ | d¡ d|v s'd|v r,| d¡ d|v r5| d¡ d	|v r@| d
¡ dS dS t |tƒrrt|  ¡ ƒ}d|vrW| d¡ n| d¡ d	|v re| d¡ d|v rp| d¡ dS dS t |tƒr“t|  ¡ ƒ}d|v r†| d¡ d|v r‘| d¡ dS dS t |t	ƒr­| 
|  ¡ ¡ |  ¡ D ]}| |¡ q£dS t |tƒr´dS tdt|ƒ ƒ‚)z9Copy Babyl-specific state to message insofar as possible.r…  r¡   r¼  r†  rƒ  rÆ  r„  r½  r‚  r¿  rß  r¾  rÀ  rÂ  rÄ  rÇ  N)rz   r
   rs  rˆ  rË   rµ  rC  r   r`  r   rŠ  r›  rÈ  r	   r   r   )r   r(   r’  r•  r   r   r    r   U  sP   




ÿ


ÿ

ÿ
ÿ
ÿzBabylMessage._explain_tor/   )r˜   r™   rš   r›   r¢  r!   rˆ  r‹  rÈ  râ  r›  rŠ  rå  r   r   r   r   r    r      s    
r   c                   @   rÓ  )r   z&Message with MMDF-specific properties.NrÔ  r   r   r   r    r     rÕ  r   c                   @   s°   e Zd ZdZd&dd„Zd&dd„Zd&dd„Zd&d	d
„Zd&dd„Zdd„ Z	dd„ Z
d'dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zed$d%„ ƒZeeƒZdS )(rÔ   zA read-only wrapper of a file.Nc                 C   s&   || _ |du r| ¡ | _dS || _dS )zInitialize a _ProxyFile.N)r  r"  Ú_pos)r   rÐ   Úposr   r   r    r!   †  s   
z_ProxyFile.__init__c                 C   ó   |   || jj¡S ©zRead bytes.)Ú_readr  rp   ©r   Úsizer   r   r    rp   Ž  rg  z_ProxyFile.readc                 C   rè  ré  )rê  r  Úread1rë  r   r   r    rí  ’  rg  z_ProxyFile.read1c                 C   rè  )zRead a line.)rê  r  r   rë  r   r   r    r   –  rg  z_ProxyFile.readlinec                 C   s>   g }| D ]}|  |¡ |dur|t|ƒ8 }|dkr |S q|S )zRead multiple lines.Nr   )ræ   rÜ   )r   ÚsizehintrZ   r”   r   r   r    Ú	readlinesš  s   
€ z_ProxyFile.readlinesc                 c   s    	 |   ¡ }|s
dS |V  q)zIterate over lines.TN)r   )r   r”   r   r   r    rQ   ¥  s   €üz_ProxyFile.__iter__c                 C   r¨  )zReturn the position.)ræ  rG   r   r   r    r"  ­  r©  z_ProxyFile.tellr   c                 C   s4   |dkr| j  | j¡ | j  ||¡ | j  ¡ | _dS )zChange position.râ   N©r  r€   ræ  r"  ©r   ÚoffsetÚwhencer   r   r    r€   ±  s   z_ProxyFile.seekc                 C   s@   t | dƒrzt | jdƒr| j ¡  W | `dS W | `dS | `w dS )zClose the file.r  rh   N)r]   r  rh   rG   r   r   r    rh   ¸  s   
ýûz_ProxyFile.closec                 C   s2   |du rd}| j  | j¡ ||ƒ}| j  ¡ | _|S )z"Read size bytes using read_method.Nrv   rð  )r   rì  Úread_methodrZ   r   r   r    rê  Á  s   z_ProxyFile._readc                 C   s   | S )z$Context management protocol support.r   rG   r   r   r    Ú	__enter__Ê  rß   z_ProxyFile.__enter__c                 G   s   |   ¡  d S r/   )rh   )r   Úexcr   r   r    Ú__exit__Î  s   z_ProxyFile.__exit__c                 C   ó
   | j  ¡ S r/   )r  ÚreadablerG   r   r   r    rù  Ñ  ó   
z_ProxyFile.readablec                 C   rø  r/   )r  ÚwritablerG   r   r   r    rû  Ô  rú  z_ProxyFile.writablec                 C   rø  r/   )r  ÚseekablerG   r   r   r    rü  ×  rú  z_ProxyFile.seekablec                 C   rø  r/   )r  rb   rG   r   r   r    rb   Ú  rú  z_ProxyFile.flushc                 C   s&   t | dƒsdS t | jdƒsdS | jjS )Nr  Tr]  F)r]   r  r]  rG   r   r   r    r]  Ý  s
   
z_ProxyFile.closedr/   ©r   )r˜   r™   rš   r›   r!   rp   rí  r   rï  rQ   r"  r€   rh   rê  rõ  r÷  rù  rû  rü  rb   Úpropertyr]  rœ   r   r   r   r   r   r    rÔ   ƒ  s*    





		
rÔ   c                   @   s<   e Zd ZdZddd„Zdd„ Zddd	„Zd
d„ Zdd„ ZdS )rA  z&A read-only wrapper of part of a file.Nc                 C   s   t  | ||¡ || _|| _dS )zInitialize a _PartialFile.N)rÔ   r!   Ú_startÚ_stop)r   rÐ   r+  r,  r   r   r    r!   ë  s   
z_PartialFile.__init__c                 C   s   t  | ¡| j S )z*Return the position with respect to start.)rÔ   r"  rÿ  rG   r   r   r    r"  ñ  rg  z_PartialFile.tellr   c                 C   s<   |dkr| j | _d}n
|dkr| j| _d}t | ||¡ dS )z8Change position, possibly with respect to start or stop.r   râ   r  N)rÿ  ræ  r   rÔ   r€   rñ  r   r   r    r€   õ  s   z_PartialFile.seekc                 C   sB   | j | j }|dkrdS |du s|dk s||kr|}t | ||¡S )z;Read size bytes using read_method, honoring start and stop.r   r8  N)r   ræ  rÔ   rê  )r   rì  rô  Ú	remainingr   r   r    rê  ÿ  s   z_PartialFile._readc                 C   s   t | dƒr	| `d S d S )Nr  )r]   r  rG   r   r   r    rh     s   
ÿz_PartialFile.close)NNrý  )	r˜   r™   rš   r›   r!   r"  r€   rê  rh   r   r   r   r    rA  è  s    


	rA  Tc              
   C   s„  d}z¨t r1zt  | t jt jB ¡ W n ty0 } z|jtjtjtjfv r+t	d| j
 ƒ‚‚ d}~ww |r¨zt| j
d ƒ}| ¡  W n ty^ } z|jtjtjfv rYW Y d}~W dS ‚ d}~ww z4zt |j
| j
d ¡ d}W n ttfy…   t |j
| j
d ¡ d}Y nw t |j
¡ W W dS W W dS  ty§   t |j
¡ t	d| j
 ƒ‚w W dS    t r·t  | t j¡ |rÁt | j
d ¡ ‚ )z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNú.lockTzdot lock unavailable: %s)ÚfcntlÚlockfÚLOCK_EXÚLOCK_NBr½   r¾   ÚEAGAINr  r  r   r¯   r#  rh   r   r¹   rº   r»   r¼   r}  r  r.   ÚLOCK_UN)rÐ   r   Zdotlock_donerÄ   Zpre_lockr   r   r    r    s\   ÿ€û€üþþÿþîr  c                 C   s<   t r	t  | t j¡ tj | jd ¡rt | jd ¡ dS dS )z*Unlock file f using lockf and dot locking.r  N)r  r  r  r   r   r¥   r¯   r.   ©rÐ   r   r   r    r  9  s
   ÿr  c              	   C   s@   t  | t jt jB t jB d¡}zt| dƒW t  |¡ S t  |¡ w )zCCreate a file if it doesn't exist and open for reading and writing.rï   r  )r   rÊ   rð   rZ  ÚO_RDWRrh   )r   Úfdr   r   r    r  @  s   
r  c                 C   s$   t d| tt ¡ ƒt ¡ t ¡ f ƒS )zBCreate a temp file based on path and open for reading and writing.z%s.%s.%s.%s)r  r  rû   rÿ   r   r   r  )r   r   r   r    r#  H  s   þr#  c                 C   s(   |   ¡  ttdƒrt |  ¡ ¡ dS dS )z0Ensure changes to file f are physically on disk.ÚfsyncN)rb   r]   r   r  Úfilenor	  r   r   r    r!  N  s   
ÿr!  c                 C   s   t | ƒ |  ¡  dS )z:Close file f, ensuring all changes are physically on disk.N)r!  rh   r	  r   r   r    r°   T  s   r°   c                   @   rÓ  )r   z"Raised for module-specific errors.NrÔ  r   r   r   r    r   Z  rÕ  r   c                   @   rÓ  )r   z:The specified mailbox does not exist and won't be created.NrÔ  r   r   r   r    r   ]  rÕ  r   c                   @   rÓ  )r   z>The specified mailbox is not empty and deletion was requested.NrÔ  r   r   r   r    r   `  rÕ  r   c                   @   rÓ  )r   z)Another process caused an action to fail.NrÔ  r   r   r   r    r   c  rÕ  r   c                   @   rÓ  )r   z)A file appears to have an invalid format.NrÔ  r   r   r   r    r   f  rÕ  r   )T)2r›   r   rû   rÐ  rÿ   r¾   rž  r‰   rA   Zemail.messageZemail.generatorr{   r;   Útypesr   r  ÚImportErrorÚ__all__r‚   ri   r   r   r  r7  r   r   r   r   r(   r	   r
   rC  r   r   r   r   rÔ   rA  r  r  r  r#  r!  r°   Ú	Exceptionr   r   r   r   r   r   r   r   r    Ú<module>   sp    ÿ j  8 DB4-  3 z%mqH_e
'*