B °-_>3ã@sRdZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl Zddl Z ddl Z y ddl Z Wnek rˆdZ YnXddddddd d d d d ddddddgZej d¡ZGdd„dƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd „d ejjƒZGd d „d eƒZGd!d"„d"eƒZGd#d „d eƒZGd$d „d eƒZGd%d „d eƒZ Gd&d„deƒZ!Gd'd(„d(ƒZ"Gd)d*„d*e"ƒZ#d=d,d-„Z$d.d/„Z%d0d1„Z&d2d3„Z'd4d5„Z(d6d7„Z)Gd8d„de*ƒZ+Gd9d„de+ƒZ,Gd:d„de+ƒZ-Gd;d„de+ƒZ.GdzDRead/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@seZdZdZdCdd„Zdd„Zdd „Zd d „Zd d „Zdd„Z dDdd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.d/„ZdEd0d1„Zd2d3„ZdFd4d5„Zd6d7„Zd8d9„Zd:d;„Zdd?„Z!d@Z"dGdAdB„Z#dS)Hrz*A group of messages in a particular place.NTcCs tj tj |¡¡|_||_dS)zInitialize a Mailbox instance.N)ÚosÚpathÚabspathÚ expanduserÚ_pathÚ_factory)ÚselfrÚfactoryÚcreate©rú/usr/lib/python3.7/mailbox.pyÚ__init__$szMailbox.__init__cCs tdƒ‚dS)z$Add message and return assigned key.z&Method must be implemented by subclassN)ÚNotImplementedError)rÚmessagerrrÚadd)sz Mailbox.addcCs tdƒ‚dS)z=Remove the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r )rÚkeyrrrÚremove-szMailbox.removecCs| |¡dS)N)r$)rr#rrrÚ __delitem__1szMailbox.__delitem__cCs(y| |¡Wntk r"YnXdS)z'If the keyed message exists, remove it.N)r$ÚKeyError)rr#rrrÚdiscard4szMailbox.discardcCs tdƒ‚dS)z>Replace the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r )rr#r!rrrÚ __setitem__;szMailbox.__setitem__cCs$y | |¡Stk r|SXdS)z9Return the keyed message, or default if it doesn't exist.N)Ú __getitem__r&)rr#ÚdefaultrrrÚget?s z Mailbox.getc Cs6|js| |¡St | |¡¡ }| |¡SQRXdS)z=Return the keyed message; raise KeyError if it doesn't exist.N)rÚ get_messageÚ contextlibÚclosingÚget_file)rr#Úfilerrrr)Fs zMailbox.__getitem__cCs tdƒ‚dS)z4Return a Message representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr,NszMailbox.get_messagecCst | |¡¡ ¡S)zœReturn a string representation or raise a KeyError. Uses email.message.Message to create a 7bit clean string representation of the message.)ÚemailÚmessage_from_bytesÚ get_bytesÚ as_string)rr#rrrÚ get_stringRszMailbox.get_stringcCs tdƒ‚dS)z8Return a byte string representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr3YszMailbox.get_bytescCs tdƒ‚dS)z6Return a file-like representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr/]szMailbox.get_filecCs tdƒ‚dS)zReturn an iterator over keys.z&Method must be implemented by subclassN)r )rrrrÚiterkeysaszMailbox.iterkeyscCs t| ¡ƒS)zReturn a list of keys.)Úlistr6)rrrrÚkeysesz Mailbox.keysc cs@x:| ¡D].}y ||}Wntk r0w YnX|Vq WdS)z%Return an iterator over all messages.N)r6r&)rr#ÚvaluerrrÚ itervaluesis  zMailbox.itervaluescCs| ¡S)N)r:)rrrrÚ__iter__rszMailbox.__iter__cCs t| ¡ƒS)z,Return a list of messages. Memory intensive.)r7r:)rrrrÚvaluesuszMailbox.valuesc csDx>| ¡D]2}y ||}Wntk r0w YnX||fVq WdS)z.Return an iterator over (key, message) tuples.N)r6r&)rr#r9rrrÚ iteritemsys  zMailbox.iteritemscCs t| ¡ƒS)z9Return a list of (key, message) tuples. Memory intensive.)r7r=)rrrrÚitems‚sz Mailbox.itemscCs tdƒ‚dS)z9Return True if the keyed message exists, False otherwise.z&Method must be implemented by subclassN)r )rr#rrrÚ __contains__†szMailbox.__contains__cCs tdƒ‚dS)z*Return a count of messages in the mailbox.z&Method must be implemented by subclassN)r )rrrrÚ__len__ŠszMailbox.__len__cCs x| ¡D]}| |¡q WdS)zDelete all messages.N)r8r')rr#rrrÚclearŽsz Mailbox.clearcCs0y ||}Wntk r |SX| |¡|S)z3Delete the keyed message and return it, or default.)r&r')rr#r*ÚresultrrrÚpop“s   z Mailbox.popcCs*x$| ¡D]}|| |¡fSWtdƒ‚dS)z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)r6rCr&)rr#rrrÚpopitemœszMailbox.popitemc Csxt|dƒr| ¡}nt|dƒr(| ¡}n|}d}x6|D].\}}y |||<Wq6tk rbd}Yq6Xq6W|rttdƒ‚dS)z4Change the messages that correspond to certain keys.r=r>FTzNo message with key(s)N)Úhasattrr=r>r&)rÚargÚsourceZbad_keyr#r!rrrÚupdate£s     zMailbox.updatecCs tdƒ‚dS)z&Write any pending changes to the disk.z&Method must be implemented by subclassN)r )rrrrÚflush´sz Mailbox.flushcCs tdƒ‚dS)zLock the mailbox.z&Method must be implemented by subclassN)r )rrrrÚlock¸sz Mailbox.lockcCs tdƒ‚dS)z#Unlock the mailbox if it is locked.z&Method must be implemented by subclassN)r )rrrrÚunlock¼szMailbox.unlockcCs tdƒ‚dS)zFlush and close the mailbox.z&Method must be implemented by subclassN)r )rrrrÚcloseÀsz Mailbox.closecCs,y | d¡Stk r&tdƒ‚YnXdS)Nrz?String input must be ASCII-only; use bytes or a Message instead)ÚencodeÚ UnicodeErrorÚ ValueError)rr!rrrÚ_string_to_bytesÄs zMailbox._string_to_bytesFc Csþt|tjjƒrvt ¡}tj ||d¡}| |¡|  d¡|  ¡}|  dt ¡}|  |¡|jrr| t ¡sr|  t ¡n„t|tttjfƒrt|tjƒr¬t dtd¡| ¡}t|tƒrÀ| |¡}|rÐ|  dd¡}|  dt ¡}|  |¡|jrú| t ¡sú|  t ¡nôt|dƒrêt|dƒr2t d td¡|j}d }xŒ| ¡}| d ¡r^|d d …d}n| d ¡rz|d d…d}|s‚P|r¤| d¡r¤d|dd …}|  dt ¡}|  |¡|}q8W|jrú|rú| t ¡sú|  t ¡ntdt|ƒƒ‚d S)z%Dump message contents to target file.ró z8Use of StringIO input is deprecated, use BytesIO insteadés From s >From ÚreadÚbufferzDUse of text mode files is deprecated, use a binary mode file insteadNs éþÿÿÿó éÿÿÿÿsFrom s>From ézInvalid message type: %s)Ú isinstancer1r!rÚioÚBytesIOÚ generatorÚBytesGeneratorÚflattenÚseekrSÚreplaceÚlinesepÚwriteÚ_append_newlineÚendswithÚstrÚbytesÚStringIOÚwarningsÚwarnÚDeprecationWarningÚgetvaluerPrErTÚreadlineÚ startswithÚ TypeErrorÚtype) rr!ÚtargetZ mangle_from_rTÚgenÚdataZlastlineÚlinerrrÚ _dump_messageÑsZ                   zMailbox._dump_message)NT)N)N)N)F)$Ú__name__Ú __module__Ú __qualname__Ú__doc__rr"r$r%r'r(r+r)r,r5r3r/r6r8r:r;r<r=r>r?r@rArCrDrHrIrJrKrLrPrcrtrrrrr!sB       c@sÚeZdZdZdZd6dd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-Zd.d/„Zd0d1„Zd2d3„Zd4d5„ZdS)7rzA qmail-style Maildir mailbox.ú:NTcCs°t ||||¡tj |jd¡tj |jd¡tj |jd¡dœ|_tj |j¡sŽ|r„t |jd¡x*|j  ¡D]}t |d¡qnWn t |jƒ‚i|_ dddœ|_ d|_ d|_d S) zInitialize a Maildir instance.ÚtmpÚnewÚcur)rzr{r|iÀr)r|r{gš™™™™™¹?N)rrrrÚjoinrÚ_pathsÚexistsÚmkdirr<rÚ_tocÚ _toc_mtimesÚ _last_readÚ _skewfactor)rÚdirnamerrrrrrr s  zMaildir.__init__c Cs~| ¡}y| ||¡Wn*tk rB| ¡t |j¡‚YnXt|ƒt|t ƒr||  ¡}|j |  ¡}||j kr„d}nd}d}tj  |j¡ |j ¡d}tj  |j|||¡}t|t ƒrÞt |jtj  |j¡| ¡f¡yLyt |j|¡Wn(ttfk rt |j|¡YnXt |j¡WnNtk rx}z.t |j¡|jtjkrftd|ƒ‚n‚Wdd}~XYnX|S)z$Add message and return assigned key.Úr{rz$Name clash with existing message: %sN)Ú _create_tmprtÚ BaseExceptionrLrr$ÚnameÚ _sync_closerYr Ú get_subdirÚcolonÚget_inforÚbasenameÚsplitr}rÚutimeÚgetatimeÚget_dateÚlinkÚAttributeErrorÚPermissionErrorÚrenameÚOSErrorÚerrnoZEEXISTr)rr!Ztmp_fileÚsubdirÚsuffixÚuniqÚdestÚerrrr"!sB      z Maildir.addcCs t tj |j| |¡¡¡dS)z=Remove the keyed message; raise KeyError if it doesn't exist.N)rr$rr}rÚ_lookup)rr#rrrr$KszMaildir.removec Cs,y| |¡Wnttfk r&YnXdS)z'If the keyed message exists, remove it.N)r$r&ÚFileNotFoundError)rr#rrrr'OszMaildir.discardc CsÊ| |¡}| |¡}| |¡}t|tƒr.|}n|}tj |¡}|j|kr`|j| |j¡d}nd}|  |¡tj  |j |¡} tj  |j |||¡} t|tƒrºt  | tj  | ¡| ¡f¡t | | ¡dS)z>Replace the keyed message; raise KeyError if it doesn't exist.rWr†N)ržr"rYr rrr…rŒrr'r}rrr‘r’r–) rr#r!Z old_subpathZtemp_keyZ temp_subpathZdominant_subpathr™ršZtmp_pathÚnew_pathrrrr(Ws"        zMaildir.__setitem__c Cs¢| |¡}ttj |j|¡dƒ }|jr4| |¡}nt|ƒ}WdQRXtj |¡\}}|  |¡|j |kr€|  | |j ¡d¡|  tj  tj |j|¡¡¡|S)z4Return a Message representation or raise a KeyError.ÚrbNrW)ržÚopenrrr}rrr rÚ set_subdirrŒÚset_infoÚset_dateÚgetmtime)rr#ZsubpathÚfÚmsgr™r‰rrrr,rs    zMaildir.get_messagec Cs8ttj |j| |¡¡dƒ}| ¡ td¡SQRXdS)z2Return a bytes representation or raise a KeyError.r¡rQN) r¢rrr}rržrSr`ra)rr#r§rrrr3szMaildir.get_bytescCs$ttj |j| |¡¡dƒ}t|ƒS)z6Return a file-like representation or raise a KeyError.r¡)r¢rrr}rržÚ _ProxyFile)rr#r§rrrr/†szMaildir.get_filec csH| ¡x:|jD]0}y| |¡Wntk r8wYnX|VqWdS)zReturn an iterator over keys.N)Ú_refreshrržr&)rr#rrrr6‹s zMaildir.iterkeyscCs| ¡||jkS)z9Return True if the keyed message exists, False otherwise.)rªr)rr#rrrr?•szMaildir.__contains__cCs| ¡t|jƒS)z*Return a count of messages in the mailbox.)rªÚlenr)rrrrr@šszMaildir.__len__cCsdS)z"Write any pending changes to disk.Nr)rrrrrIŸsz Maildir.flushcCsdS)zLock the mailbox.Nr)rrrrrJ¥sz Maildir.lockcCsdS)z#Unlock the mailbox if it is locked.Nr)rrrrrK©szMaildir.unlockcCsdS)zFlush and close the mailbox.Nr)rrrrrL­sz Maildir.closecCs`g}xVt |j¡D]F}t|ƒdkr|ddkrtj tj |j|¡¡r| |dd…¡qW|S)zReturn a list of folder names.érÚ.N)rÚlistdirrr«rÚisdirr}Úappend)rrBÚentryrrrÚ list_folders±s zMaildir.list_folderscCs ttj |jd|¡|jddS)z/Return a Maildir instance for the named folder.r­F)rr)rrrr}rr)rÚfolderrrrÚ get_folderºszMaildir.get_foldercCs\tj |jd|¡}t||jd}tj |d¡}tj |¡sXt t |tj tj Bd¡¡|S)z>Create a folder and return a Maildir instance representing it.r­)rZ maildirfolderi¶) rrr}rrrrrLr¢ÚO_CREATÚO_WRONLY)rr³rrBZmaildirfolder_pathrrrÚ add_folderÀs zMaildir.add_foldercCs,tj |jd|¡}xTt tj |d¡¡t tj |d¡¡D](}t|ƒdksZ|ddkr>td|ƒ‚q>WxPt |¡D]B}|dkrv|dkrv|dkrvtj tj ||¡¡rvtd||fƒ‚qvWx`tj|d d D]N\}}}x |D]}t  tj ||¡¡qÜWx |D]}t  tj ||¡¡qþWqÌWt  |¡d S) z-Delete the named folder, which must be empty.r­r{r|r¬rzFolder contains message(s): %srzz%Folder contains subdirectory '%s': %sF)ÚtopdownN) rrr}rr®r«rr¯Úwalkr$Úrmdir)rr³rr±ÚrootÚdirsZfilesrrrÚ remove_folderÊs   zMaildir.remove_foldercCs\t ¡}xNt tj |jd¡¡D]4}tj |jd|¡}|tj |¡dkr t |¡q WdS)zDelete old files in "tmp".rzi@úN)Útimerr®rr}rr‘r$)rÚnowr±rrrrÚcleanÝs z Maildir.cleanr¬c CsÒt ¡}t ¡}d|kr$| dd¡}d|kr8| dd¡}dt|ƒt|ddƒt ¡tj|f}tj   |j d|¡}yt  |¡Wn@t k rÀtjd7_yt|ƒStk rºYnXYnXtd |ƒ‚d S) z=Create a file in the tmp subdirectory and open and return it.ú/z\057ryz\072z%s.M%sP%sQ%s.%sr¬g€„.Arzz&Name clash prevented file creation: %sN)r¾ÚsocketÚ gethostnamer`ÚintrÚgetpidrÚ_countrr}rÚstatrŸÚ_create_carefullyÚFileExistsErrorr)rr¿Zhostnamer›rrrrr‡çs&    zMaildir._create_tmpcCsät ¡|jd|jkrbd}x<|jD]2}tj |j|¡}||j|krLd}||j|<q$W|sbdSi|_xl|jD]b}|j|}xRt  |¡D]D}tj  ||¡}tj  |¡rªqŠ|  |j ¡d}tj  ||¡|j|<qŠWqpWt ¡|_dS)z!Update table of contents mapping.éFTNr)r¾rƒr„r‚rrr¦r~rr®r}r¯rrŒ)rZrefreshr™Úmtimerr±Úpr›rrrrªÿs&    zMaildir._refreshcCs|y,tj tj |j|j|¡¡r*|j|SWntk r@YnX| ¡y |j|Stk rvtd|ƒd‚YnXdS)z=Use TOC to return subpath for given key, or raise a KeyError.zNo message with key: %sN)rrrr}rrr&rª)rr#rrrrž#s zMaildir._lookupcCsVt|dƒs| ¡|_xReplace the keyed message; raise KeyError if it doesn't exist.TN)ržrÚrrÖ)rr#r!rrrr(hs z_singlefileMailbox.__setitem__ccs| ¡|j ¡EdHdS)zReturn an iterator over keys.N)ržrr8)rrrrr6nsz_singlefileMailbox.iterkeyscCs| ¡||jkS)z9Return True if the keyed message exists, False otherwise.)ržr)rr#rrrr?ssz_singlefileMailbox.__contains__cCs| ¡t|jƒS)z*Return a count of messages in the mailbox.)ržr«r)rrrrr@xsz_singlefileMailbox.__len__cCs|jst|jƒd|_dS)zLock the mailbox.TN)rØÚ _lock_filerÔ)rrrrrJ}s z_singlefileMailbox.lockcCs|jrt|jƒd|_dS)z#Unlock the mailbox if it is locked.FN)rØÚ _unlock_filerÔ)rrrrrKƒs z_singlefileMailbox.unlockc Csì|js |jrt|jƒd|_dS|jdk s.t‚|j dd¡|j ¡}||jkrbt d|j|fƒ‚t |j ƒ}y¬i}|  |¡xŽt |j ¡ƒD]|}|j|\}}|j |¡| |¡| ¡}x0|j td||j ¡ƒ¡}|sàP| |¡q¾W|| ¡f||<| |¡qŒW| ¡|_Wn"| ¡t |j¡‚YnXt|ƒ|j ¡t |j ¡j} t |j| ¡yt |j|j ¡Wn2tk r°t |j ¡t |j|j ¡YnXt|j dƒ|_||_d|_d|_|jrèt |jdddS) z"Write any pending changes to disk.FNrrÊz4Size of mailbox file changed (expected %i, found %i)izrb+)Údotlock)!rÖr×Ú _sync_flushrÔrÚAssertionErrorr_ÚtellrÙrÚ_create_temporaryrÚ_pre_mailbox_hookÚsortedr8Ú_pre_message_hookrSÚminrbÚ_post_message_hookrLrr$r‰rŠrÇÚst_modeÚchmodr–rÉr¢rØrÛ) rZcur_lenZnew_fileZnew_tocr#ÚstartÚstopZ new_startrTÚmoderrrrI‰s`           z_singlefileMailbox.flushcCsdS)z,Called before writing the mailbox to file f.Nr)rr§rrrrâÉsz$_singlefileMailbox._pre_mailbox_hookcCsdS)z-Called before writing each message to file f.Nr)rr§rrrräÍsz$_singlefileMailbox._pre_message_hookcCsdS)z,Called after writing each message to file f.Nr)rr§rrrræÑsz%_singlefileMailbox._post_message_hookcCs4z | ¡Wdz|jr| ¡Wd|j ¡XXdS)zFlush and close the mailbox.N)rIrØrKrÔrL)rrrrrLÕs   z_singlefileMailbox.closecCsL|jdkr| ¡|dk rHy |j|Stk rFtd|ƒd‚YnXdS)z'Return (start, stop) or raise KeyError.NzNo message with key: %s)rÚ _generate_tocr&)rr#rrrržàs  z_singlefileMailbox._lookupcCsœ|j dd¡|j ¡}t|jƒdkr8|js8| |j¡y&| |j¡| |¡}|  |j¡Wn"t k r€|j  |¡‚YnX|j  ¡|j ¡|_ |S)z;Append message to mailbox and return (start, stop) offsets.rrÊ)rÔr_ràr«rrÖrâräÚ_install_messagerærˆÚtruncaterIrÙ)rr!ZbeforeZoffsetsrrrrÚês       z"_singlefileMailbox._append_message)NT)N)rurvrwrxrr"r$r(r6r?r@rJrKrIrârärærLržrÚrrrrrÐ>s"  @ rÐc@sBeZdZdZdZdd„Zddd„Zddd „Zdd d „Zd d „Z dS)Ú _mboxMMDFzAn mbox or MMDF mailbox.TcCsp| |¡\}}|j |¡|j ¡ td¡}|j ||j ¡¡}| | td¡¡}|  |dd…  d¡¡|S)z4Return a Message representation or raise a KeyError.órQrXNr) ržrÔr_rlr`rarSràÚ_message_factoryÚset_fromÚdecode)rr#rérêÚ from_lineÚstringr¨rrrr,s z_mboxMMDF.get_messageFcCst | |¡¡j|dS)z3Return a string representation or raise a KeyError.)Úunixfrom)r1r2r3r4)rr#Úfrom_rrrr5sz_mboxMMDF.get_stringcCsJ| |¡\}}|j |¡|s(|j ¡|j ||j ¡¡}| td¡S)z3Return a string representation or raise a KeyError.rQ)ržrÔr_rlrSràr`ra)rr#r÷rérêrõrrrr3s   z_mboxMMDF.get_bytescCs<| |¡\}}|j |¡|s(|j ¡t|j|j ¡|ƒS)z6Return a file-like representation or raise a KeyError.)ržrÔr_rlÚ _PartialFilerà)rr#r÷rérêrrrr/s   z_mboxMMDF.get_filecCs d}t|tƒr| |¡}t|tƒrf| d¡rf| d¡}|dkr\|d|…}||dd…}q°|}d}nJt|tƒrˆ| ¡ d¡}d|}n(t|t j j ƒr°|  ¡}|dk r°| d¡}|dkrÎdt  t  ¡¡ ¡}|j ¡}|j |t¡| ||j|j¡|j ¡}||fS) z1Format a message and blindly write to self._file.NsFrom rQrWr¬rðrsFrom MAILER-DAEMON )rYrerPrfrmÚfindÚ_mboxMMDFMessageÚget_fromrMr1r!rÚ get_unixfromr¾ÚasctimeÚgmtimerÔràrbrartÚ _mangle_from_)rr!rôÚnewlineZauthorrérêrrrrí&s0         z_mboxMMDF._install_messageN)F)F)F) rurvrwrxrÿr,r5r3r/rírrrrrïs  rïc@s2eZdZdZdZdZd dd„Zdd„Zdd „ZdS) rzA classic mbox mailbox.TNcCst|_t ||||¡dS)zInitialize an mbox mailbox.N)r rñrïr)rrrrrrrrLsz mbox.__init__cCs| t¡dS)z,Called after writing each message to file f.N)rbra)rr§rrrræQszmbox._post_message_hookcCsìgg}}d}|j d¡x |j ¡}|j ¡}| d¡r|t|ƒt|ƒkrl|rb| |ttƒ¡n | |¡| |¡d}q|s¦|r˜| |ttƒ¡n | |¡Pq|tkr´d}qd}qWtt t ||ƒƒƒ|_ t|j ƒ|_ |j ¡|_ dS)z0Generate key-to-(start, stop) table of contents.FrsFrom TN)rÔr_ràrlrmr«r°raÚdictÚ enumerateÚziprrÕrÙ)rÚstartsÚstopsZlast_was_emptyÚline_posrsrrrrìUs0         zmbox._generate_toc)NT) rurvrwrxrÿrcrrærìrrrrrCs  c@s2eZdZdZd dd„Zdd„Zdd „Zd d „ZdS) rzAn MMDF mailbox.NTcCst|_t ||||¡dS)zInitialize an MMDF mailbox.N)r rñrïr)rrrrrrrrzsz MMDF.__init__cCs| dt¡dS)z-Called before writing each message to file f.sN)rbra)rr§rrrräszMMDF._pre_message_hookcCs| tdt¡dS)z,Called after writing each message to file f.sN)rbra)rr§rrrræƒszMMDF._post_message_hookcCsægg}}|j d¡d}xŒ|}|j ¡}|j ¡}| dt¡rž| |¡xV|}|j ¡}|j ¡}|dtkrˆ| |ttƒ¡PqN|sN| |¡PqNWq|sPqWtt t ||ƒƒƒ|_ t|j ƒ|_ |j dd¡|j ¡|_ dS)z0Generate key-to-(start, stop) table of contents.rsrÊN)rÔr_rlràrmrar°r«rrrrrÕrÙ)rrrÚnext_posrrsrrrrì‡s2          zMMDF._generate_toc)NT)rurvrwrxrrärærìrrrrrws  c@sÂeZdZdZd0dd„Zdd„Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.d/„ZdS)1rzAn MH mailbox.NTcCstt ||||¡tj |j¡sj|r`t |jd¡t t tj  |jd¡tj tj Btj Bd¡¡n t |jƒ‚d|_dS)zInitialize an MH instance.iÀz .mh_sequencesi€FN)rrrrrrr€rLr¢r}rµÚO_EXCLr¶rrØ)rrrrrrrr§s z MH.__init__cCsä| ¡}t|ƒdkrd}n t|ƒd}tj |jt|ƒ¡}t|ƒ}d}zŠ|j rVt |ƒzfy|  ||¡Wn:t k r¢|j r†t |ƒt|ƒd}t |¡‚YnXt|tƒrº| ||¡Wd|j rÌt |ƒXWd|sÞt|ƒX|S)z$Add message and return assigned key.rr¬FTN)r8r«Úmaxrrr}rrerÈrØrÛrtrˆrÜrŠr$rYr Ú_dump_sequences)rr!r8Znew_keyr r§Úclosedrrrr"³s6     zMH.addc Csxtj |jt|ƒ¡}yt|dƒ}Wn>tk r`}z |jtjkrNt d|ƒ‚n‚Wdd}~XYnX|  ¡t  |¡dS)z=Remove the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN) rrr}rrer¢r—r˜rÑr&rLr$)rr#rr§rrrrr$Õs z MH.removec CsÖtj |jt|ƒ¡}yt|dƒ}Wn>tk r`}z |jtjkrNt d|ƒ‚n‚Wdd}~XYnXzd|j rrt |ƒz@t  t |tj tjB¡¡| ||¡t|tƒr°| ||¡Wd|j rÂt|ƒXWdt|ƒXdS)z>Replace the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN)rrr}rrer¢r—r˜rÑr&rØrÛrLr¶ÚO_TRUNCrtrYr r rÜrŠ)rr#r!rr§rrrrr(ãs$   zMH.__setitem__c Csìy@|jr$ttj |jt|ƒ¡dƒ}nttj |jt|ƒ¡dƒ}Wn>tk r~}z |jtj krlt d|ƒ‚n‚Wdd}~XYnX|2|jr”t |ƒz t |ƒ}Wd|jr°t |ƒXWdQRXx*| ¡ ¡D]\}}||krÊ| |¡qÊW|S)z4Return a Message representation or raise a KeyError.zrb+r¡zNo message with key: %sN)rØr¢rrr}rrer—r˜rÑr&rÛr rÜÚ get_sequencesr>Ú add_sequence)rr#r§rr¨r‰Úkey_listrrrr,ûs&  zMH.get_messagec CsÄy@|jr$ttj |jt|ƒ¡dƒ}nttj |jt|ƒ¡dƒ}Wn>tk r~}z |jtj krlt d|ƒ‚n‚Wdd}~XYnX|6|jr”t |ƒz|  ¡  td¡S|jr´t|ƒXWdQRXdS)z2Return a bytes representation or raise a KeyError.zrb+r¡zNo message with key: %sNrQ)rØr¢rrr}rrer—r˜rÑr&rÛrSr`rarÜ)rr#r§rrrrr3s z MH.get_bytesc Csfyttj |jt|ƒ¡dƒ}Wn>tk r\}z |jtjkrJt d|ƒ‚n‚Wdd}~XYnXt |ƒS)z6Return a file-like representation or raise a KeyError.r¡zNo message with key: %sN) r¢rrr}rrer—r˜rÑr&r©)rr#r§rrrrr/)s z MH.get_filecCsttdd„t |j¡DƒƒƒS)zReturn an iterator over keys.css|]}| ¡rt|ƒVqdS)N)ÚisdigitrÄ)Ú.0r±rrrú 6szMH.iterkeys..)Úiterrãrr®r)rrrrr64sz MH.iterkeyscCstj tj |jt|ƒ¡¡S)z9Return True if the keyed message exists, False otherwise.)rrrr}rre)rr#rrrr?9szMH.__contains__cCstt| ¡ƒƒS)z*Return a count of messages in the mailbox.)r«r7r6)rrrrr@=sz MH.__len__cCs2|js.ttj |jd¡dƒ|_t|jƒd|_dS)zLock the mailbox.z .mh_sequenceszrb+TN)rØr¢rrr}rrÔrÛ)rrrrrJAs zMH.lockcCs(|jr$t|jƒt|jƒ|`d|_dS)z#Unlock the mailbox if it is locked.FN)rØrÜrÔrŠ)rrrrrKHs   z MH.unlockcCsdS)z&Write any pending changes to the disk.Nr)rrrrrIPszMH.flushcCs|jr| ¡dS)zFlush and close the mailbox.N)rØrK)rrrrrLTszMH.closecCs@g}x6t |j¡D]&}tj tj |j|¡¡r| |¡qW|S)zReturn a list of folder names.)rr®rrr¯r}r°)rrBr±rrrr²Ys zMH.list_folderscCsttj |j|¡|jddS)z+Return an MH instance for the named folder.F)rr)rrrr}rr)rr³rrrr´asz MH.get_foldercCsttj |j|¡|jdS)z:Create a folder and return an MH instance representing it.)r)rrrr}rr)rr³rrrr·fsz MH.add_foldercCs`tj |j|¡}t |¡}|dgkr:t tj |d¡¡n|gkrDntd|jƒ‚t |¡dS)z-Delete the named folder, which must be empty.z .mh_sequenceszFolder not empty: %sN)rrr}rr®r$rrº)rr³rÚentriesrrrr½ks  zMH.remove_folderc s i}ttj |jd¡dddä}t| ¡ƒ‰xÐ|D]È}yž| d¡\}}tƒ}xT| ¡D]H}| ¡rr|  t |ƒ¡qVdd„| d¡Dƒ\}} |  t || d ƒ¡qVW‡fd d „t |ƒDƒ||<t||ƒd krÒ||=Wq2tk røtd | ¡ƒ‚Yq2Xq2WWdQRX|S)z=Return a name-to-key-list dictionary to define each sequence.z .mh_sequencesÚrÚASCII)Úencodingrycss|]}t|ƒVqdS)N)rÄ)rÚxrrrr„sz#MH.get_sequences..ú-r¬csg|]}|ˆkr|‘qSrr)rr#)Úall_keysrrú †sz$MH.get_sequences..rz"Invalid sequence specification: %sN)r¢rrr}rÚsetr8rrr"rÄrHÚrangerãr«rOrÚrstrip) rZresultsr§rsr‰Úcontentsr8Úspecrérêr)rrr ws&    zMH.get_sequencescCs ttj |jd¡ddd}zàt t |jtjtjB¡¡x¾|  ¡D]²\}}t |ƒdkrXqB|  |d¡d}d}xbt t |ƒƒD]R}|d |kr |sÊd }|  d ¡n*|r¼d}|  d ||f¡n|  d |¡|}q|W|rê|  t|ƒd¡qB|  d¡qBWWdt|ƒXdS)z:Set sequences using the given name-to-key-list dictionary.z .mh_sequenceszr+r)rrryNFr¬Trz%s %sz %sÚ )r¢rrr}rrLr‰r¶r r>r«rbrãrrerŠ)rÚ sequencesr§r‰r8ÚprevZ completingr#rrrÚ set_sequencess.   zMH.set_sequencesc CsL| ¡}d}g}xÎ| ¡D]Â}|d|krÔ| ||df¡y4t tj |jt|ƒ¡tj |jt|dƒ¡¡WnHt t fk r¸t  tj |jt|ƒ¡tj |jt|dƒ¡¡YnXt  tj |jt|ƒ¡¡|d7}qW|d|_ t|ƒdkrúdSxB| ¡D]6\}}x*|D]"\}}||kr||| |¡<qWqW| |¡dS)z?Re-name messages to eliminate numbering gaps. Invalidates keys.rr¬N)r r6r°rr“rr}rrer”r•r–ÚunlinkrÕr«r>Úindexr$) rr"r#Zchangesr#r‰rÚoldr{rrrÚpack¬s,      zMH.packcCs|| ¡}| ¡}x<| ¡D]0\}}||kr6| |¡q||kr|| |¡=qWx|D]}||krT|g||<qTW| |¡dS)z;Inspect a new MHMessage and update sequences appropriately.N)r r>r°r&r$)rr!r#Zpending_sequencesZ all_sequencesr‰rÚsequencerrrr Æs  zMH._dump_sequences)NT)rurvrwrxrr"r$r(r,r3r/r6r?r@rJrKrIrLr²r´r·r½r r$r(r rrrrr¤s. "  c@seZdZdZedddddddhƒZd%d d „Zd d„Zdd„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd „Zd!d"„Zd#d$„Zd S)&rzAn Rmail-style Babyl mailbox.ÚunseenÚdeletedZfiledÚansweredÚ forwardedZeditedÚresentNTcCst ||||¡i|_dS)zInitialize a Babyl mailbox.N)rÐrÚ_labels)rrrrrrrrÛszBabyl.__init__cCs(t ||¡}t|tƒr$| ¡|j|<|S)z$Add message and return assigned key.)rÐr"rYr Ú get_labelsr/)rr!r#rrrr"às  z Babyl.addcCs"t ||¡||jkr|j|=dS)z=Remove the keyed message; raise KeyError if it doesn't exist.N)rÐr$r/)rr#rrrr$çs  z Babyl.removecCs*t |||¡t|tƒr&| ¡|j|<dS)z>Replace the keyed message; raise KeyError if it doesn't exist.N)rÐr(rYr r0r/)rr#r!rrrr(ís zBabyl.__setitem__c Cs| |¡\}}|j |¡|j ¡t ¡}x2|j ¡}|dtksH|sJP| | td¡¡q.Wt ¡}x.|j ¡}|tks€|s‚P| | td¡¡qjW||j  ¡}|dks²t ‚|j  |¡}| td¡}t |  ¡|ƒ} |  |  ¡¡||jkr|  |j|¡| S)z4Return a Message representation or raise a KeyError.s *** EOOH ***rQr)ržrÔr_rlrZr[rarbr`ràrßrSr rkÚ set_visibler/Ú set_labels) rr#rérêÚoriginal_headersrsZvisible_headersÚnZbodyr¨rrrr,ós0         zBabyl.get_messagec CsÀ| |¡\}}|j |¡|j ¡t ¡}x2|j ¡}|dtksH|sJP| | td¡¡q.Wx|j ¡}|tksx|sbPqbW|  ¡}||j  ¡}|dks t ‚|j  |¡}| td¡}||S)z3Return a string representation or raise a KeyError.s *** EOOH ***rQr) ržrÔr_rlrZr[rarbr`rkràrßrS) rr#rérêr3rsZheadersr4rrrrrr3s&        zBabyl.get_bytescCst | |¡ dt¡¡S)z6Return a file-like representation or raise a KeyError.rQ)rZr[r3r`ra)rr#rrrr/%szBabyl.get_filecCs@| ¡tƒ}x|j ¡D]}| |¡qW| |j¡t|ƒS)z4Return a list of user-defined labels in the mailbox.)ržrr/r<rHÚdifference_updateÚ_special_labelsr7)rÚlabelsZ label_listrrrr0)s  zBabyl.get_labelscCs>gg}}|j d¡d}g}xÒ|}|j ¡}|j ¡}|dtkržt|ƒt|ƒkrf| |ttƒ¡| |¡dd„|j ¡dd… d¡Dƒ}| |¡q |dks²|dtkrÖt|ƒt|ƒkrî| |ttƒ¡q |s | |ttƒ¡Pq Wtt t ||ƒƒƒ|_ tt |ƒƒ|_ t|j ƒ|_ |j dd ¡|j ¡|_dS) z0Generate key-to-(start, stop) table of contents.rs cSsg|]}| ¡r| ¡‘qSr)Ústrip)rÚlabelrrrr@sz'Babyl._generate_toc..r¬Nó,órÊ)rÔr_rlràrar«r°rrrrrr/rÕrÙ)rrrrZ label_listsrrsr7rrrrì2s4        zBabyl._generate_toccCsVdt}|dt7}| ¡}dd„|Dƒ}|dd |¡t7}|d7}| |¡dS) z,Called before writing the mailbox to file f.sBABYL OPTIONS:s Version: 5css|]}| ¡VqdS)N)rM)rr9rrrrUsz*Babyl._pre_mailbox_hook..sLabels:r:r;N)rar0r}rb)rr§Zbabylr7rrrrâPs zBabyl._pre_mailbox_hookcCs| dt¡dS)z-Called before writing each message to file f.ó N)rbra)rr§rrrräZszBabyl._pre_message_hookcCs| td¡dS)z,Called after writing each message to file f.r;N)rbra)rr§rrrræ^szBabyl._post_message_hookcCs”|j ¡}t|tƒr¼g}g}x0| ¡D]$}||jkr@| |¡q&| |¡q&W|j d¡x |D]}|j d| ¡¡q`W|j d¡x$|D]}|j d| ¡d¡qŽW|j t ¡n|j dt ¡t|t j j ƒr*t  ¡}t j |dd¡}| |¡| d¡x4| ¡}|j | d t ¡¡|d ks6|s Pq W|j d t ¡t|tƒr¸t  ¡} t j | dd¡} |  | ¡¡xv|  ¡}|j | d t ¡¡|d ks®|s‚Pq‚Wn@| d¡x4| ¡}|j | d t ¡¡|d ksð|sÄPqÄWx,| d ¡} | s P|j |  d t ¡¡qúWnXt|ttt jfƒr&t|t jƒrbt d td ¡| ¡}t|tƒrx| |¡}| d¡d} | ddkrú|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ƒrrt |dƒrRt dtd ¡|j!}| ¡} d}x”| ¡}| "d¡r†|dd…d }n| "d¡r¢|dd…d }|j | d t ¡¡|d ksÆ|s`|rìd}|j d t ¡| | ¡nPq`WxŒ| ¡}|sP| "d¡r$|dd…t }n:| "d¡rB|dd…t }n| "d ¡r^|dd…t }|j |¡qöWnt#dt$|ƒƒ‚|j ¡}||fS)z0Write message contents and return (start, stop).ó1s, s,,ó r:s1,,FrrQs *** EOOH ***iz8Use of StringIO input is deprecated, use BytesIO insteadrRs rÊrWNrlrTzDUse of text mode files is deprecated, use a binary mode file insteadTs rUrVzInvalid message type: %s)%rÔràrYr r0r6r°rbrMrar1r!rrZr[r\r]r^r_rlr`Ú get_visiblerSrfrergrhrirjrkrPrùrErTrdrnro)rr!réZspecial_labelsr7r9Z orig_bufferZorig_generatorrsZ vis_bufferZ vis_generatorrTZ body_startZ original_posZ first_passrêrrrríbsÀ                         zBabyl._install_message)NT)rurvrwrxÚ frozensetr6rr"r$r(r,r3r/r0rìrârärærírrrrrÕs      c@s*eZdZdZd dd„Zdd„Zdd„ZdS) rz0Message with mailbox-format-specific properties.NcCsÒt|tjjƒ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(|dkr¾tjj |¡ntdt|ƒƒ‚dS)zInitialize a Message instance.rSNzInvalid message type: %s)rYr1r!rÚ_become_messageÚcopyZdeepcopyÚ _explain_torfr2reZmessage_from_stringrZÚ TextIOWrapperZmessage_from_filerEZmessage_from_binary_filerrnro)rr!rrrrÑs      zMessage.__init__cCs8t|dgƒ}x&|jD]}||kr|j||j|<qWdS)z0Assume the non-format-specific state of message.Ú_type_specific_attributesN)ÚgetattrÚ__dict__)rr!Z type_specificr‰rrrrAäs  zMessage._become_messagecCst|tƒrdStdƒ‚dS)z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)rYrrn)rr!rrrrCës zMessage._explain_to)N)rurvrwrxrrArCrrrrrÎs c@s|eZdZdZdddgZddd„Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„ZdS)r z)Message with Maildir-specific properties.Ú_subdirÚ_infoÚ_dateNcCs&d|_d|_t ¡|_t ||¡dS)z%Initialize a MaildirMessage instance.r{r†N)rHrIr¾rJrr)rr!rrrrøs zMaildirMessage.__init__cCs|jS)zReturn 'new' or 'cur'.)rH)rrrrr‹ÿszMaildirMessage.get_subdircCs(|dks|dkr||_n td|ƒ‚dS)zSet subdir to 'new' or 'cur'.r{r|z!subdir must be 'new' or 'cur': %sN)rHrO)rr™rrrr£szMaildirMessage.set_subdircCs"|j d¡r|jdd…SdSdS)z*Return as a string the flags that are set.z2,rÊNr†)rIrm)rrrrÚ get_flags s zMaildirMessage.get_flagscCsdd t|ƒ¡|_dS)z)Set the given flags and unset all others.z2,r†N)r}rãrI)rÚflagsrrrÚ set_flagsszMaildirMessage.set_flagscCs$| d t| ¡ƒt|ƒB¡¡dS)z.Set the given flag(s) without changing others.r†N)rMr}rrK)rÚflagrrrÚadd_flagszMaildirMessage.add_flagcCs,| ¡r(| d t| ¡ƒt|ƒ¡¡dS)z7Unset the given string flag(s) without changing others.r†N)rKrMr}r)rrNrrrÚ remove_flagszMaildirMessage.remove_flagcCs|jS)zSet "From " line, formatting and appending time_ if specified.NTú )r¾rþrýr^)rr÷Ztime_rrrròrs z_mboxMMDFMessage.set_fromcCs| dd¡| dd¡S)z*Return as a string the flags that are set.ÚStatusr†zX-Status)r+)rrrrrKzsz_mboxMMDFMessage.get_flagscCsÚt|ƒ}d\}}x&dD]}||kr||7}| |¡qWx&dD]}||kr>||7}| |¡q>W|d t|ƒ¡7}y| d|¡Wn tk r¢| d|¡YnXy| d|¡Wn tk rÔ| d|¡YnXdS)z)Set the given flags and unset all others.)r†r†)rTrU)rWrXrYr†r`zX-StatusN)rr$r}rãÚreplace_headerr&Z add_header)rrLZ status_flagsZ xstatus_flagsrNrrrrM~s&  z_mboxMMDFMessage.set_flagscCs$| d t| ¡ƒt|ƒB¡¡dS)z.Set the given flag(s) without changing others.r†N)rMr}rrK)rrNrrrrO”sz_mboxMMDFMessage.add_flagcCs4d|ksd|kr0| d t| ¡ƒt|ƒ¡¡dS)z7Unset the given string flag(s) without changing others.r`zX-Statusr†N)rMr}rrK)rrNrrrrP˜sz_mboxMMDFMessage.remove_flagc CsÞt|tƒrÐt| ¡ƒ}d|kr(| d¡d|kr:| d¡d|krL| d¡d|kr^| d¡d|krp| d¡|d =|d =d  | ¡ ¡d d …¡}y|  t   t   |d¡¡¡Wnttfk rÊYnXn t|tƒrø| | ¡¡| | ¡¡nât|tƒrZt| ¡ƒ}d|kr$| d¡d|kr8| d¡d|krL| d¡|d =|d =n€t|tƒr¼t| ¡ƒ}d|kr†| d¡d|krš| d¡d|kr®| d¡|d =|d =nt|tƒrÊntdt|ƒƒ‚d S)zACopy mbox- or MMDF-specific state to message insofar as possible.rUr|rXrYrTrSrWrVZstatuszx-statusr_éûÿÿÿNz%a %b %d %H:%M:%S %Yr*rZr[r+r,z$Cannot convert to specified type: %s)rYr rrKr£rOr}rûrr¥ÚcalendarZtimegmr¾ZstrptimerOÚ OverflowErrorrúrMròr rr r]rrnro)rr!rLZ maybe_daterrrrCs^                          z_mboxMMDFMessage._explain_to)N)N) rurvrwrxrErrûròrKrMrOrPrCrrrrrú`s  rúc@seZdZdZdS)r z&Message with mbox-specific properties.N)rurvrwrxrrrrr Ñsc@sHeZdZdZdgZddd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dS)r z$Message with MH-specific properties.Ú _sequencesNcCsg|_t ||¡dS)z!Initialize an MHMessage instance.N)rerr)rr!rrrrÚszMHMessage.__init__cCs|jdd…S)z4Return a list of sequences that include the message.N)re)rrrrr ßszMHMessage.get_sequencescCst|ƒ|_dS)z3Set the list of sequences that include the message.N)r7re)rr"rrrr$ãszMHMessage.set_sequencescCs6t|tƒr"||jkr2|j |¡ntdt|ƒƒ‚dS)z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rYrerer°rnro)rr)rrrrçs  zMHMessage.add_sequencecCs*y|j |¡Wntk r$YnXdS)zARemove sequence from the list of sequences including the message.N)rer$rO)rr)rrrÚremove_sequenceïszMHMessage.remove_sequencecCsJt|tƒrdt| ¡ƒ}d|kr*| d¡n| d¡| d¡d|krP| d¡d|krb| d¡nât|tƒr¾t| ¡ƒ}d|krŽ| d¡n | d ¡d|krª| d¡d|kr¼| d ¡nˆt|tƒræx|| ¡D]}| |¡qÒWn`t|t ƒr(t| ¡ƒ}d|kr|  d¡d|krF|  d ¡nt|t ƒr6nt d t |ƒƒ‚d S)z6Copy MH-specific state to message insofar as possible.r*r|rSr[rXrZrTÚROrUrYr,z$Cannot convert to specified type: %sN)rYr rr r£rOrúr rr r]rrnro)rr!r"r)rrrrCös@                     zMHMessage._explain_to)N) rurvrwrxrErr r$rrfrCrrrrr Õs c@sbeZdZdZddgZddd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dS)r z'Message with Babyl-specific properties.r/Ú_visibleNcCsg|_tƒ|_t ||¡dS)z#Initialize a BabylMessage instance.N)r/rrhr)rr!rrrr"szBabylMessage.__init__cCs|jdd…S)z'Return a list of labels on the message.N)r/)rrrrr0(szBabylMessage.get_labelscCst|ƒ|_dS)z&Set the list of labels on the message.N)r7r/)rr7rrrr2,szBabylMessage.set_labelscCs6t|tƒr"||jkr2|j |¡ntdt|ƒƒ‚dS)z+Add label to list of labels on the message.zlabel must be a string: %sN)rYrer/r°rnro)rr9rrrr]0s  zBabylMessage.add_labelcCs*y|j |¡Wntk r$YnXdS)z4Remove label from the list of labels on the message.N)r/r$rO)rr9rrrÚ remove_label8szBabylMessage.remove_labelcCs t|jƒS)z3Return a Message representation of visible headers.)rrh)rrrrr??szBabylMessage.get_visiblecCst|ƒ|_dS)z2Set the Message representation of visible headers.N)rrh)rZvisiblerrrr1CszBabylMessage.set_visiblecCsjx6|j ¡D](}||kr,|j |||¡q |j|=q Wx,dD]$}||kr>||jkr>|||j|<q>WdS)z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)rhr8ra)rÚheaderrrrÚupdate_visibleGs  zBabylMessage.update_visiblecCsvt|tƒr~t| ¡ƒ}d|kr*| d¡n| d¡| d¡d|ksNd|krX| d¡d|krj| d¡d |kr|| d ¡nôt|tƒrØt| ¡ƒ}d|kr¨| d ¡n | d ¡d |krÄ| d ¡d|krÖ| d¡nšt|tƒrt| ¡ƒ}d|kr| d¡d|krr| d¡nXt|t ƒrT|  |  ¡¡x<| ¡D]}|  |¡q>Wnt|t ƒrbntdt|ƒƒ‚dS)z9Copy Babyl-specific state to message insofar as possible.r*r|rSr-r.r\r,rTr+rVrgrUrWrYrZz$Cannot convert to specified type: %sN)rYr rr0r£rOrúr rr r1r?r]rrnro)rr!r7r9rrrrCRsF                      zBabylMessage._explain_to)N)rurvrwrxrErr0r2r]rir?r1rkrCrrrrr s  c@seZdZdZdS)r z&Message with MMDF-specific properties.N)rurvrwrxrrrrr |sc@s¨eZdZdZd&dd„Zd'dd„Zd(dd„Zd)d d „Zd*d d „Zd d„Z dd„Z d+dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zed$d%„ƒZdS),r©zA read-only wrapper of a file.NcCs$||_|dkr| ¡|_n||_dS)zInitialize a _ProxyFile.N)rÔràÚ_pos)rr§Úposrrrrƒs z_ProxyFile.__init__cCs| ||jj¡S)z Read bytes.)Ú_readrÔrS)rÚsizerrrrS‹sz_ProxyFile.readcCs| ||jj¡S)z Read bytes.)rnrÔÚread1)rrorrrrpsz_ProxyFile.read1cCs| ||jj¡S)z Read a line.)rnrÔrl)rrorrrrl“sz_ProxyFile.readlinecCs>g}x4|D],}| |¡|dk r |t|ƒ8}|dkr Pq W|S)zRead multiple lines.Nr)r°r«)rÚsizehintrBrsrrrÚ readlines—s   z_ProxyFile.readlinesccs x| ¡}|sdS|VqWdS)zIterate over lines.N)rl)rrsrrrr;¢s z_ProxyFile.__iter__cCs|jS)zReturn the position.)rl)rrrrràªsz_ProxyFile.tellrcCs4|dkr|j |j¡|j ||¡|j ¡|_dS)zChange position.r¬N)rÔr_rlrà)rÚoffsetÚwhencerrrr_®sz_ProxyFile.seekcCs0t|dƒr,zt|jdƒr"|j ¡Wd|`XdS)zClose the file.rÔrLN)rErÔrL)rrrrrLµs   z_ProxyFile.closecCs2|dkr d}|j |j¡||ƒ}|j ¡|_|S)z"Read size bytes using read_method.NrW)rÔr_rlrà)rroÚ read_methodrBrrrrn¾s  z_ProxyFile._readcCs|S)z$Context management protocol support.r)rrrrÚ __enter__Çsz_ProxyFile.__enter__cGs | ¡dS)N)rL)rÚexcrrrÚ__exit__Ësz_ProxyFile.__exit__cCs |j ¡S)N)rÔÚreadable)rrrrryÎsz_ProxyFile.readablecCs |j ¡S)N)rÔÚwritable)rrrrrzÑsz_ProxyFile.writablecCs |j ¡S)N)rÔÚseekable)rrrrr{Ôsz_ProxyFile.seekablecCs |j ¡S)N)rÔrI)rrrrrI×sz_ProxyFile.flushcCs&t|dƒsdSt|jdƒsdS|jjS)NrÔTr F)rErÔr )rrrrr Ús   z_ProxyFile.closed)N)N)N)N)N)r)rurvrwrxrrSrprlrrr;ràr_rLrnrvrxryrzr{rIÚpropertyr rrrrr©€s$        r©c@s<eZdZdZddd„Zdd„Zddd „Zd d „Zd d „ZdS)røz&A read-only wrapper of part of a file.NcCst |||¡||_||_dS)zInitialize a _PartialFile.N)r©rÚ_startÚ_stop)rr§rérêrrrræsz_PartialFile.__init__cCst |¡|jS)z*Return the position with respect to start.)r©ràr})rrrrràìsz_PartialFile.tellrcCs<|dkr|j|_d}n|dkr*|j|_d}t |||¡dS)z8Change position, possibly with respect to start or stop.rr¬rÊN)r}rlr~r©r_)rrsrtrrrr_ðsz_PartialFile.seekcCsB|j|j}|dkrdS|dks0|dks0||kr4|}t |||¡S)z;Read size bytes using read_method, honoring start and stop.rrðN)r~rlr©rn)rroruZ remainingrrrrnús  z_PartialFile._readcCst|dƒr|`dS)NrÔ)rErÔ)rrrrrLs z_PartialFile.close)NN)r) rurvrwrxrràr_rnrLrrrrrøãs    røTc Csžd}yZtrpyt |tjtjB¡WnJtk rn}z,|jtjtjtjfkr\t d|j ƒ‚n‚Wdd}~XYnX|r^yt |j dƒ}|  ¡Wn:tk rÊ}z|jtjtjfkr¸dS‚Wdd}~XYnXy`yt  |j |j d¡d}Wn2ttfk rt  |j |j d¡d}YnXt  |j ¡Wn0tk r\t  |j ¡t d|j ƒ‚YnXWn8tr|t |tj¡|r’t  |j d¡‚YnXdS)z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNz.lockTzdot lock unavailable: %s)ÚfcntlÚlockfZLOCK_EXZLOCK_NBr—r˜ZEAGAINrÒrÓrr‰rárLrr“r”r•r–r%rÉr$ÚLOCK_UN)r§rÝZ dotlock_donerZpre_lockrrrrÛ sH    rÛcCs8trt |tj¡tj |jd¡r4t |jd¡dS)z*Unlock file f using lockf and dot locking.z.lockN)rr€rrrrr‰r$)r§rrrrÜ4srÜc Cs8t |tjtjBtjBd¡}z t|dƒSt |¡XdS)zCCreate a file if it doesn't exist and open for reading and writing.i¶zrb+N)rr¢rµrÚO_RDWRrL)rÚfdrrrrÈ;s rÈcCs$td|tt ¡ƒ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ÃrrÅ)rrrrráCsrácCs$| ¡ttdƒr t | ¡¡dS)z0Ensure changes to file f are physically on disk.ÚfsyncN)rIrErr„Úfileno)r§rrrrÞIs rÞcCst|ƒ| ¡dS)z:Close file f, ensuring all changes are physically on disk.N)rÞrL)r§rrrrŠOsrŠc@seZdZdZdS)rz"Raised for module-specific errors.N)rurvrwrxrrrrrUsc@seZdZdZdS)rz:The specified mailbox does not exist and won't be created.N)rurvrwrxrrrrrXsc@seZdZdZdS)rz>The specified mailbox is not empty and deletion was requested.N)rurvrwrxrrrrr[sc@seZdZdZdS)rz)Another process caused an action to fail.N)rurvrwrxrrrrr^sc@seZdZdZdS)rz)A file appears to have an invalid format.N)rurvrwrxrrrrras)T)0rxrr¾rcrÂr˜rBrhr1Z email.messageZemail.generatorrZr-rÚ ImportErrorÚ__all__rarMrrrÐrïrrrrr!rr rúr r r r r©rørÛrÜrÈrárÞrŠÚ ExceptionrrrrrrrrrÚsp     h8DB4-3z%mqH_c' *