YfR2@s0dZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl Zddl Z ddl Z yddl Z Wnek rdZ YnXddddddd d d d d dg ZejjdZGdddZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdd d ejjZGdd d eZGdddeZGdd d eZGdd d eZGd d d eZ Gd!ddeZ!Gd"d#d#Z"Gd$d%d%e"Z#d&d'd(Z$d)d*Z%d+d,Z&d-d.Z'd/d0Z(d1d2Z)Gd3d4d4e*Z+Gd5d6d6e+Z,Gd7d8d8e+Z-Gd9d:d:e+Z.Gd;d<d<e+Z/dS)=zDRead/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.NMailboxMaildirmboxMHBabylMMDFMessageMaildirMessage mboxMessage MHMessage BabylMessage MMDFMessageasciic@seZdZdZddddZddZdd Zd d Zd d ZddZ dddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zdd0d1Zd2d3Zdd4d5Zd6d7Zd8d9Zd:d;Zd<d=Z d>d?Z!d@Z"d@dAdBZ#dS)Crz*A group of messages in a particular place.NTcCs.tjjtjj||_||_dS)zInitialize a Mailbox instance.N)ospathabspath expanduser_path_factory)selfrfactorycreater,/opt/alt/python35/lib64/python3.5/mailbox.py__init__#s!zMailbox.__init__cCstddS)z$Add message and return assigned key.z&Method must be implemented by subclassN)NotImplementedError)rmessagerrradd(sz Mailbox.addcCstddS)z=Remove the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r)rkeyrrrremove,szMailbox.removecCs|j|dS)N)r)rrrrr __delitem__0szMailbox.__delitem__c Cs*y|j|Wntk r%YnXdS)z'If the keyed message exists, remove it.N)rKeyError)rrrrrdiscard3s zMailbox.discardcCstddS)z>Replace the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r)rrrrrr __setitem__:szMailbox.__setitem__c Cs.y|j|SWntk r)|SYnXdS)z9Return the keyed message, or default if it doesn't exist.N) __getitem__r!)rrdefaultrrrget>s z Mailbox.getc CsI|js|j|Stj|j|}|j|SWdQRXdS)z=Return the keyed message; raise KeyError if it doesn't exist.N)r get_message contextlibclosingget_file)rrfilerrrr$Es  zMailbox.__getitem__cCstddS)z4Return a Message representation or raise a KeyError.z&Method must be implemented by subclassN)r)rrrrrr'MszMailbox.get_messagecCstj|j|jS)zReturn a string representation or raise a KeyError. Uses email.message.Message to create a 7bit clean string representation of the message.)emailmessage_from_bytes get_bytes as_string)rrrrr get_stringQszMailbox.get_stringcCstddS)z8Return a byte string representation or raise a KeyError.z&Method must be implemented by subclassN)r)rrrrrr.XszMailbox.get_bytescCstddS)z6Return a file-like representation or raise a KeyError.z&Method must be implemented by subclassN)r)rrrrrr*\szMailbox.get_filecCstddS)zReturn an iterator over keys.z&Method must be implemented by subclassN)r)rrrriterkeys`szMailbox.iterkeyscCst|jS)zReturn a list of keys.)listr1)rrrrkeysdsz Mailbox.keysc csFx?|jD]1}y||}Wntk r8w YnX|Vq WdS)z%Return an iterator over all messages.N)r1r!)rrvaluerrr itervalueshs  zMailbox.itervaluescCs |jS)N)r5)rrrr__iter__qszMailbox.__iter__cCst|jS)z,Return a list of messages. Memory intensive.)r2r5)rrrrvaluestszMailbox.valuesc csLxE|jD]7}y||}Wntk r8w YnX||fVq WdS)z.Return an iterator over (key, message) tuples.N)r1r!)rrr4rrr iteritemsxs  zMailbox.iteritemscCst|jS)z9Return a list of (key, message) tuples. Memory intensive.)r2r8)rrrritemssz Mailbox.itemscCstddS)z9Return True if the keyed message exists, False otherwise.z&Method must be implemented by subclassN)r)rrrrr __contains__szMailbox.__contains__cCstddS)z*Return a count of messages in the mailbox.z&Method must be implemented by subclassN)r)rrrr__len__szMailbox.__len__cCs(x!|jD]}|j|q WdS)zDelete all messages.N)r3r")rrrrrclearsz Mailbox.clearc Cs8y||}Wntk r&|SYnX|j||S)z3Delete the keyed message and return it, or default.)r!r")rrr%resultrrrpops    z Mailbox.popcCs7x0|jD]}||j|fSWtddS)z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)r1r>r!)rrrrrpopitemszMailbox.popitemc Cst|dr|j}n$t|dr<|j}n|}d}x=|D]5\}}y|||From readbufferzDUse of text mode files is deprecated, use a binary mode file insteadNs s sFrom s>From zInvalid message type: %s) isinstancer,rrioBytesIO generatorBytesGeneratorflattenseekrMreplacelinesepwrite_append_newlineendswithstrbytesStringIOwarningswarnDeprecationWarninggetvaluerKr@rNreadline startswith TypeErrortype) rrtargetZ mangle_from_rNgendataZlastlinelinerrr _dump_messagesZ               zMailbox._dump_message)$__name__ __module__ __qualname____doc__rrrr r"r#r&r$r'r0r.r*r1r3r5r6r7r8r9r:r;r<r>r?rCrDrErFrGrKr^rorrrrr sB                         c@sHeZdZdZdZddddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zd)d*Zd+d,Zd-Zd.d/Zd0d1Zd2d3Zd4d5ZdS)6rzA qmail-style Maildir mailbox.:NTcCstj||||dtjj|jddtjj|jddtjj|jdi|_tjj|js|rtj|jdx9|jj D]}tj|dqWnt |ji|_ ddddi|_ d|_ d|_dS)zInitialize a Maildir instance.tmpnewcurirg?N)rrrrjoinr_pathsexistsmkdirr7NoSuchMailboxError_toc _toc_mtimes _last_read _skewfactor)rdirnamerrrrrrr s!  zMaildir.__init__cCs|j}y|j||Wn/tk rQ|jtj|jYnXt|t|t r|j }|j |j }||j krd}n d}d}tj j|jj|j d}tj j|j|||}t|t r/tj|jtj j|j|jfyLttdrgtj|j|tj|jntj|j|Wn]tk r}z=tj|j|jtjkrtd|nWYdd}~XnX|S)z$Add message and return assigned key.rvrlinkz$Name clash with existing message: %sN) _create_tmpro BaseExceptionrGrrname _sync_closerTr get_subdircolonget_inforbasenamesplitrxrutimegetatimeget_dater@rrenameOSErrorerrnoZEEXISTExternalClashError)rrZtmp_filesubdirsuffixuniqdesterrrr s@      % " z Maildir.addcCs,tjtjj|j|j|dS)z=Remove the keyed message; raise KeyError if it doesn't exist.N)rrrrxr_lookup)rrrrrrIszMaildir.removec Cs0y|j|Wnttfk r+YnXdS)z'If the keyed message exists, remove it.N)rr!FileNotFoundError)rrrrrr"MszMaildir.discardc Cs!|j|}|j|}|j|}t|trE|}n|}tjj|}|j|kr|j|j|jd}nd}|j |tjj |j |} tjj |j |||} t|tr tj | tjj | |jftj| | dS)z>Replace the keyed message; raise KeyError if it doesn't exist.rPrNrS)rrrTr rrrrrr"rxrrrrr) rrrZ old_subpathZtemp_keyZ temp_subpathZdominant_subpathrrZtmp_pathnew_pathrrrr#Us"    zMaildir.__setitem__c Cs|j|}ttjj|j|d.}|jrN|j|}n t|}WdQRXtjj|\}}|j ||j |kr|j |j|j d|j tjj tjj|j||S)z4Return a Message representation or raise a KeyError.rbNrPrS)ropenrrrxrrr r set_subdirrset_infoset_dategetmtime)rrZsubpathfmsgrrrrrr'ps$  +zMaildir.get_messagec CsNttjj|j|j|d}|jjtdSWdQRXdS)z2Return a bytes representation or raise a KeyError.rs N) rrrrxrrrMr[r\)rrrrrrr.s-zMaildir.get_bytescCs4ttjj|j|j|d}t|S)z6Return a file-like representation or raise a KeyError.r)rrrrxrr _ProxyFile)rrrrrrr*s*zMaildir.get_filec csP|jx?|jD]4}y|j|Wntk rBwYnX|VqWdS)zReturn an iterator over keys.N)_refreshr}rr!)rrrrrr1s  zMaildir.iterkeyscCs|j||jkS)z9Return True if the keyed message exists, False otherwise.)rr})rrrrrr:s zMaildir.__contains__cCs|jt|jS)z*Return a count of messages in the mailbox.)rlenr})rrrrr;s zMaildir.__len__cCsdS)z"Write any pending changes to disk.Nr)rrrrrDsz Maildir.flushcCsdS)zLock the mailbox.Nr)rrrrrEsz Maildir.lockcCsdS)z#Unlock the mailbox if it is locked.Nr)rrrrrFszMaildir.unlockcCsdS)zFlush and close the mailbox.Nr)rrrrrGsz Maildir.closecCsg}xwtj|jD]c}t|dkr|ddkrtjjtjj|j|r|j|ddqW|S)zReturn a list of folder names.rPr.N)rlistdirrrrisdirrxappend)rr=entryrrr list_folderss "$zMaildir.list_folderscCs/ttjj|jd|d|jddS)z/Return a Maildir instance for the named folder.rrrF)rrrrxrr)rfolderrrr get_folders zMaildir.get_foldercCstjj|jd|}t|d|j}tjj|d}tjj|s~tjtj|tj tj Bd|S)z>Create a folder and return a Maildir instance representing it.rrZ maildirfolderi) rrrxrrrrzrGrO_CREATO_WRONLY)rrrr=Zmaildirfolder_pathrrr add_folders zMaildir.add_foldercCstjj|jd|}xttjtjj|dtjtjj|dD]8}t|dks|ddkrWtd|qWWxrtj|D]a}|dkr|dkr|dkrtjjtjj||rtd||fqWxtj|d d D]i\}}}x*|D]"}tj tjj||q4Wx*|D]"}tj tjj||qaWqWtj |d S) z-Delete the named folder, which must be empty.rrvrwrPrzFolder contains message(s): %sruz%Folder contains subdirectory '%s': %stopdownFN) rrrxrrr NotEmptyErrorrwalkrrmdir)rrrrrootdirsfilesrrr remove_folders #"$!%   $zMaildir.remove_foldercCstj}xmtjtjj|jdD]J}tjj|jd|}|tjj|dkr.tj|q.WdS)zDelete old files in "tmp".rui@N)timerrrrxrrr)rnowrrrrrcleans  (z Maildir.cleanrPcCstj}tj}d|kr6|jdd}d|krT|jdd}dt|t|ddtjtj|f}tj j |j d|}ytj |WnDt k rtjd7_yt|SWntk rYnXYnXtd |d S) z=Create a file in the tmp subdirectory and open and return it./z\057rtz\072z%s.M%sP%sQ%s.%srPg.Aruz&Name clash prevented file creation: %sN)rsocket gethostnamer[intrgetpidr_countrrxrstatr_create_carefullyFileExistsErrorr)rrZhostnamerrrrrrs&    &   zMaildir._create_tmpcCs6tj|jd|jkrd}xP|jD]E}tjj|j|}||j|krhd}||j|Replace the keyed message; raise KeyError if it doesn't exist.TN)rrr}r)rrrrrrr#fs z_singlefileMailbox.__setitem__ccs |j|jjEdHdS)zReturn an iterator over keys.N)rr}r3)rrrrr1ls z_singlefileMailbox.iterkeyscCs|j||jkS)z9Return True if the keyed message exists, False otherwise.)rr})rrrrrr:qs z_singlefileMailbox.__contains__cCs|jt|jS)z*Return a count of messages in the mailbox.)rrr})rrrrr;vs z_singlefileMailbox.__len__cCs#|jst|jd|_dS)zLock the mailbox.TN)r _lock_filer)rrrrrE{s  z_singlefileMailbox.lockcCs#|jrt|jd|_dS)z#Unlock the mailbox if it is locked.FN)r _unlock_filer)rrrrrFs  z_singlefileMailbox.unlockc Cs|js,|jr(t|jd|_dS|jdk sAt|jjdd|jj}||jkrt d|j|ft |j }yi}|j |xt |jjD]}|j|\}}|jj||j||j}x@|jjtd||jj}|s:P|j|q W||jf||<|j|qW|j|_Wn%|jtj|jYnXt||jjtj|j j} tj|j| ytj|j|j Wn8tk r=tj|j tj|j|j YnXt|j d|_||_d|_d|_|jrt |jdddS) z"Write any pending changes to disk.FNrrOz4Size of mailbox file changed (expected %i, found %i)izrb+dotlock)!rr _sync_flushrr}AssertionErrorrZtellrr_create_temporaryr_pre_mailbox_hooksortedr3_pre_message_hookrMminr]_post_message_hookrGrrrrrst_modechmodrrrrr) rZcur_lenZnew_fileZnew_tocrstartstopZ new_startrNmoderrrrDs`               z_singlefileMailbox.flushcCsdS)z,Called before writing the mailbox to file f.Nr)rrrrrrsz$_singlefileMailbox._pre_mailbox_hookcCsdS)z-Called before writing each message to file f.Nr)rrrrrrsz$_singlefileMailbox._pre_message_hookcCsdS)z,Called after writing each message to file f.Nr)rrrrrrsz%_singlefileMailbox._post_message_hookcCs>z|jWdz|jr'|jWd|jjXXdS)zFlush and close the mailbox.N)rDrrFrrG)rrrrrGs  z_singlefileMailbox.closec Cs]|jdkr|j|dk rYy|j|SWn"tk rXtd|YnXdS)z'Return (start, stop) or raise KeyError.NzNo message with key: %s)r} _generate_tocr!)rrrrrrs   z_singlefileMailbox._lookupc Cs|jjdd|jj}t|jdkrQ|j rQ|j|jy3|j|j|j|}|j |jWn%t k r|jj |YnX|jj |jj|_ |S)z;Append message to mailbox and return (start, stop) offsets.rrO)rrZrrr}rrr_install_messagerrtruncaterDr)rrZbeforeZoffsetsrrrrs  z"_singlefileMailbox._append_message)rprqrrrsrrrr#r1r:r;rErFrDrrrrGrrrrrrr<s"         @     rc@saeZdZdZdZddZdddZddd Zdd d Zd d Z dS) _mboxMMDFzAn mbox or MMDF mailbox.TcCs|j|\}}|jj||jjjtd}|jj||jj}|j|jtd}|j |ddj d|S)z4Return a Message representation or raise a KeyError.s rQNr) rrrZrgr[r\rMr_message_factoryset_fromdecode)rrrr from_linestringrrrrr's z_mboxMMDF.get_messageFcCs"tj|j|jd|S)z3Return a string representation or raise a KeyError.unixfrom)r,r-r.r/)rrfrom_rrrr0sz_mboxMMDF.get_stringcCsg|j|\}}|jj||s8|jj|jj||jj}|jtdS)z3Return a string representation or raise a KeyError.s )rrrZrgrMrr[r\)rrrrrrrrrr.s  z_mboxMMDF.get_bytescCsT|j|\}}|jj||s8|jjt|j|jj|S)z6Return a file-like representation or raise a KeyError.)rrrZrg _PartialFiler)rrrrrrrrr*s  z_mboxMMDF.get_filecCsd}t|tr$|j|}t|tr|jdr|jd}|dkr|d|}||dd}q|}d}nmt|tr|jjd}d|}n<t|t j j r|j }|dk r|jd}|dkr+dt jt jj}|jj}|jj|t|j||j|j|jj}||fS) z1Format a message and blindly write to self._file.NsFrom s rPrrsFrom MAILER-DAEMON rS)rTr`rKrarhfind_mboxMMDFMessageget_fromrHr,rr get_unixfromrasctimegmtimerrr]r\ro _mangle_from_)rrrnewlineZauthorrrrrrr$s0      z_mboxMMDF._install_messageN) rprqrrrsrr'r0r.r*rrrrrrs   rc@sLeZdZdZdZdZddddZddZdd ZdS) rzA classic mbox mailbox.TNcCs#t|_tj||||dS)zInitialize an mbox mailbox.N)r rrr)rrrrrrrrJs z mbox.__init__cCs|jtdS)z,Called after writing each message to file f.N)r]r\)rrrrrrOszmbox._post_message_hookcCsJgg}}d}|jjdx|jj}|jj}|jdrt|t|kr|r|j|ttn |j||j|d}q&|s|r|j|ttn |j|Pq&|tkrd}q&d}q&Wtt t |||_ t|j |_ |jj|_ dS)z0Generate key-to-(start, stop) table of contents.FrsFrom TN)rrZrrgrhrrr\dict enumeratezipr}rr)rstartsstopsZlast_was_emptyline_posrnrrrrSs0        zmbox._generate_toc) rprqrrrsrr^rrrrrrrrAs  c@sLeZdZdZddddZddZdd Zd d ZdS) rzAn MMDF mailbox.NTcCs#t|_tj||||dS)zInitialize an MMDF mailbox.N)r rrr)rrrrrrrrxs z MMDF.__init__cCs|jdtdS)z-Called before writing each message to file f.sN)r]r\)rrrrrr}szMMDF._pre_message_hookcCs|jtdtdS)z,Called after writing each message to file f.sN)r]r\)rrrrrrszMMDF._post_message_hookcCs;gg}}|jjdd}x|}|jj}|jj}|jdtr|j|xq|}|jj}|jj}|dtkr|j|ttPqm|sm|j|PqmWq&|s&Pq&Wtt t |||_ t|j |_ |jjdd|jj|_ dS)z0Generate key-to-(start, stop) table of contents.rsrON)rrZrgrrhr\rrrrrr}rr)rrrnext_posrrnrrrrs2   zMMDF._generate_toc)rprqrrrsrrrrrrrrrus   c@s$eZdZdZddddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/ZdS)0rzAn MH mailbox.NTcCstj||||tjj|js|rtj|jdtjtjtjj |jdtj tj Btj Bdnt |jd|_dS)zInitialize an MH instance.iz .mh_sequencesiFN)rrrrrzrr{rGrrxrO_EXCLrr|r)rrrrrrrrs!!z MH.__init__cCs,|j}t|dkr'd}nt|d}tjj|jt|}t|}d}z|j r}t |zy|j ||WnEt k r|j rt |t|d}tj|YnXt|tr|j||Wd|j rt |XWd|s't|X|S)z$Add message and return assigned key.rrPFTN)r3rmaxrrrxrr`rrrrorrrrrTr _dump_sequences)rrr3Znew_keyrrclosedrrrrs6            zMH.addcCstjj|jt|}yt|d}WnMtk r}z-|jtjkrkt d|nWYdd}~XnX|j tj |dS)z=Remove the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN) rrrxrr`rrrrr!rGr)rrrrrrrrrs z MH.removecCstjj|jt|}yt|d}WnMtk r}z-|jtjkrkt d|nWYdd}~XnXz|j rt |zVtj tj|tj tjB|j||t|tr|j||Wd|j rt|XWdt|XdS)z>Replace the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN)rrrxrr`rrrrr!rrrGrO_TRUNCrorTr rrr)rrrrrrrrrr#s$  # zMH.__setitem__c Cs6y^|jr6ttjj|jt|d}n'ttjj|jt|d}WnMtk r}z-|jtj krt d|nWYdd}~XnX|?|jrt |zt |}Wd|jrt |XWdQRXx9|jjD]%\}}||kr |j|q W|S)z4Return a Message representation or raise a KeyError.zrb+rzNo message with key: %sN)rrrrrxrr`rrrr!rr r get_sequencesr9 add_sequence)rrrrrrkey_listrrrr's& *+    zMH.get_messagec Csy^|jr6ttjj|jt|d}n'ttjj|jt|d}WnMtk r}z-|jtj krt d|nWYdd}~XnX|I|jrt |z|j j tdSWd|jrt|XWdQRXdS)z2Return a bytes representation or raise a KeyError.zrb+rzNo message with key: %sNs )rrrrrxrr`rrrr!rrMr[r\r)rrrrrrrr.s *+   z MH.get_bytescCsy+ttjj|jt|d}WnMtk rz}z-|jtjkret d|nWYdd}~XnXt |S)z6Return a file-like representation or raise a KeyError.rzNo message with key: %sN) rrrrxrr`rrrr!r)rrrrrrrr*'s+z MH.get_filecCs)ttddtj|jDS)zReturn an iterator over keys.css'|]}|jrt|VqdS)N)isdigitr).0rrrr 4szMH.iterkeys..)iterrrrr)rrrrr12sz MH.iterkeyscCs(tjjtjj|jt|S)z9Return True if the keyed message exists, False otherwise.)rrrzrxrr`)rrrrrr:7szMH.__contains__cCstt|jS)z*Return a count of messages in the mailbox.)rr2r1)rrrrr;;sz MH.__len__cCsG|jsCttjj|jdd|_t|jd|_dS)zLock the mailbox.z .mh_sequenceszrb+TN)rrrrrxrrr)rrrrrE?s $ zMH.lockcCs6|jr2t|jt|j|`d|_dS)z#Unlock the mailbox if it is locked.FN)rrrr)rrrrrFFs    z MH.unlockcCsdS)z&Write any pending changes to the disk.Nr)rrrrrDNszMH.flushcCs|jr|jdS)zFlush and close the mailbox.N)rrF)rrrrrGRs zMH.closecCsXg}xKtj|jD]7}tjjtjj|j|r|j|qW|S)zReturn a list of folder names.)rrrrrrxr)rr=rrrrrWs $zMH.list_folderscCs+ttjj|j|d|jddS)z+Return an MH instance for the named folder.rrF)rrrrxrr)rrrrrr_sz MH.get_foldercCs%ttjj|j|d|jS)z:Create a folder and return an MH instance representing it.r)rrrrxrr)rrrrrrdsz MH.add_foldercCstjj|j|}tj|}|dgkrUtjtjj|dn"|gkrdntd|jtj|dS)z-Delete the named folder, which must be empty.z .mh_sequenceszFolder not empty: %sN)rrrxrrrrr)rrrentriesrrrris zMH.remove_folderc s`i}ttjj|jdddd,}t|jx|D]}y|jd\}}t}xr|jD]d}|jr|j t |q}dd|jdD\}} |j t || d q}Wfd d t |D||.-rPcs"g|]}|kr|qSrr)r r)all_keysrr s z$MH.get_sequences..rz"Invalid sequence specification: %sN)rrrrxrsetr3rr rrrCrangerrrJ FormatErrorrstrip) rZresultsrrnrcontentsr3specrrr)rrrus&*   "#   zMH.get_sequencesc Csettjj|jdddd}z,tjtj|jtjtjBx|j D]\}}t |dkr~q]|j |dd}d}xt t |D]o}|d |kr|sd }|j d n7|rd}|j d ||fn|j d ||}qW|rA|j t|dq]|j dq]WWdt|XdS)z:Set sequences using the given name-to-key-list dictionary.z .mh_sequenceszr+rrrrtNFrPTrz%s %sz %s )rrrrxrrGrrrr9rr]rrr`r)r sequencesrrr3prevZ completingrrrr set_sequencess.'& zMH.set_sequencesc Cs|j}d}g}x|jD]}|d|kr|j||dfttdrtjtjj|jt |tjj|jt |dtj tjj|jt |nDtj tjj|jt |tjj|jt |d|d7}q%W|d|_ t |dkrBdSxP|jD]B\}}x3|D]+\}}||krb|||j|Replace the keyed message; raise KeyError if it doesn't exist.N)rr#rTr r,r+)rrrrrrr#szBabyl.__setitem__c Csm|j|\}}|jj||jjtj}xD|jj}|dtksg| rhP|j|jtdqAWtj}x@|jj}|tks| rP|j|jtdqW||jj }|dkst |jj |}|jtd}t |j |} | j|j ||jkri| j|j|| S)z4Return a Message representation or raise a KeyError.s *** EOOH ***s r)rrrZrgrUrVr\r]r[rrrMr rf set_visibler+ set_labels) rrrroriginal_headersrnZvisible_headersnZbodyrrrrr's0   zBabyl.get_messagec Cs |j|\}}|jj||jjtj}xD|jj}|dtksg| rhP|j|jtdqAWx'|jj}|tks| rPqW|j }||jj }|dkst |jj |}|jtd}||S)z3Return a string representation or raise a KeyError.s *** EOOH ***s r) rrrZrgrUrVr\r]r[rfrrrM) rrrrr/rnZheadersr0rmrrrr. s&   zBabyl.get_bytescCs"tj|j|jdtS)z6Return a file-like representation or raise a KeyError.s )rUrVr.r[r\)rrrrrr*"szBabyl.get_filecCsT|jt}x$|jjD]}|j|q#W|j|jt|S)z4Return a list of user-defined labels in the mailbox.)rrr+r7rCdifference_update_special_labelsr2)rlabelsZ label_listrrrr,&s   zBabyl.get_labelscCsgg}}|jjdd}g}x|}|jj}|jj}|dtkrt|t|kr|j|tt|j|dd|jjddjdD}|j|q,|dks|dtkr)t|t|krG|j|ttq,|s,|j|ttPq,Wtt t |||_ tt ||_ t|j |_ |jjdd |jj|_dS) z0Generate key-to-(start, stop) table of contents.rs cSs(g|]}|jr|jqSr)strip)r labelrrrr=s z'Babyl._generate_toc..rPN,srO)rrZrgrr\rrrrrrr}r+rr)rrrrZ label_listsrrnr3rrrr/s4   &zBabyl._generate_toccCsmdt}|dt7}|j}dd|D}|ddj|t7}|d7}|j|dS) z,Called before writing the mailbox to file f.sBABYL OPTIONS:s Version: 5css|]}|jVqdS)N)rH)r r5rrrr Rsz*Babyl._pre_mailbox_hook..sLabels:r6sN)r\r,rxr])rrZbabylr3rrrrMs   zBabyl._pre_mailbox_hookcCs|jdtdS)z-Called before writing each message to file f.s N)r]r\)rrrrrrWszBabyl._pre_message_hookcCs|jtddS)z,Called after writing each message to file f.sN)r]r\)rrrrrr[szBabyl._post_message_hookcCs|jj}t|trg}g}x@|jD]2}||jkr\|j|q7|j|q7W|jjdx(|D] }|jjd|jqW|jjdx,|D]$}|jjd|jdqW|jjt n|jjdt t|t j j rt j}t jj|dd}|j||jdx@|j}|jj|jd t |d ks| rdPqdW|jjd t t|trDt j} t jj| dd} | j|jx| j}|jj|jd t |d ks<| rPqWnP|jdx@|j}|jj|jd t |d ks| rTPqTWx@|jd } | sP|jj| jd t qWnt|ttt jfrt|t jrtjd td |j}t|tr:|j|}|jdd} | ddkr|jj|d| jd t |jjd t |jj|d| jd t |jj|| djd t q|jjd t t |jj|jd t nt |drt |drWtjdtd |j!}|j} d}x|j}|j"dr|ddd }n#|j"dr|ddd }|jj|jd t |d ks| rl|r d}|jjd t |j| qlPqlWx|j}|s;P|j"dra|ddt }nI|j"dr|ddt }n#|j"d r|ddt }|jj|q(Wnt#dt$||jj}||fS)z0Write message contents and return (start, stop).1s, s,, r6s1,,Frs s *** EOOH ***iz8Use of StringIO input is deprecated, use BytesIO insteadrLs rOrPNrgrNzDUse of text mode files is deprecated, use a binary mode file insteadTs s zInvalid message type: %srSrRrSrRrSrS)%rrrTr r,r2rr]rHr\r,rrrUrVrWrXrYrZrgr[ get_visiblerMrar`rbrcrdrerfrKrr@rNr_rirj)rrrZspecial_labelsr3r5Z orig_bufferZorig_generatorrnZ vis_bufferZ vis_generatorrNZ body_startZ original_posZ first_passrrrrr_s  "        #   &&)      zBabyl._install_message)rprqrrrs frozensetr2rrrr#r'r.r*r,rrrrrrrrrrs          c@s=eZdZdZdddZddZddZdS) rz0Message with mailbox-format-specific properties.NcCs)t|tjjrJ|jtj|t|tr%|j|nt|trr|jtj |nt|t r|jtj |nt|t j r|jtj|n`t|dr|jtj|n8|dkrtjjj|ntdt|dS)zInitialize a Message instance.rMNzInvalid message type: %s)rTr,rr_become_messagecopydeepcopy _explain_torar-r`Zmessage_from_stringrU TextIOWrapperZmessage_from_filer@Zmessage_from_binary_filerrirj)rrrrrrs zMessage.__init__cCsJt|dg}x1|jD]&}||kr|j||j|szMessage._explain_to)rprqrrrsrr;r>rrrrrs  c@seZdZdZdddgZdddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZdS)r z)Message with Maildir-specific properties._subdir_info_dateNcCs5d|_d|_tj|_tj||dS)z%Initialize a MaildirMessage instance.rvrN)rCrDrrErr)rrrrrrs  zMaildirMessage.__init__cCs|jS)zReturn 'new' or 'cur'.)rC)rrrrrszMaildirMessage.get_subdircCs8|dks|dkr$||_ntd|dS)zSet subdir to 'new' or 'cur'.rvrwz!subdir must be 'new' or 'cur': %sN)rCrJ)rrrrrrs zMaildirMessage.set_subdircCs+|jjdr#|jddSdSdS)z*Return as a string the flags that are set.z2,rONr)rDrh)rrrr get_flagsszMaildirMessage.get_flagscCs ddjt||_dS)z)Set the given flags and unset all others.z2,rN)rxrrD)rflagsrrr set_flagsszMaildirMessage.set_flagscCs0|jdjt|jt|BdS)z.Set the given flag(s) without changing others.rN)rHrxrrF)rflagrrradd_flagszMaildirMessage.add_flagcCs<|jr8|jdjt|jt|dS)z7Unset the given string flag(s) without changing others.rN)rFrHrxr)rrIrrr remove_flags zMaildirMessage.remove_flagcCs|jS)z1sN         "            zMaildirMessage._explain_to)rprqrrrsr@rrrrFrHrJrKrrrrr>rrrrr s           c@seZdZdZdgZdddZddZddd Zd d Zd d Z ddZ ddZ ddZ dS)rz/Message with mbox- or MMDF-specific properties._fromNcCsw|jddt|tjjrc|j}|dk rc|jdrc|j|ddtj||dS)z'Initialize an mboxMMDFMessage instance.z MAILER-DAEMONTNzFrom rQ)rrTr,rrrrhr)rrrrrrrbs  z_mboxMMDFMessage.__init__cCs|jS)z Return contents of "From " line.)rY)rrrrrksz_mboxMMDFMessage.get_fromcCsH|dk r;|dkr$tj}|dtj|7}||_dS)z>Set "From " line, formatting and appending time_ if specified.NT )rrrrY)rrZtime_rrrros    z_mboxMMDFMessage.set_fromcCs |jdd|jddS)z*Return as a string the flags that are set.StatusrzX-Status)r&)rrrrrFwsz_mboxMMDFMessage.get_flagscCst|}d \}}x1d D])}||kr||7}|j|qWx1d D])}||krS||7}|j|qSW|djt|7}y|jd|Wn"tk r|jd|YnXy|jd|Wn"tk r |jd|YnXd S) z)Set the given flags and unset all others.rrOrPrRrSrTr[zX-StatusN)rr)rOrP)rRrSrT)rrrxrreplace_headerr!Z add_header)rrGZ status_flagsZ xstatus_flagsrIrrrrH{s&          z_mboxMMDFMessage.set_flagscCs0|jdjt|jt|BdS)z.Set the given flag(s) without changing others.rN)rHrxrrF)rrIrrrrJsz_mboxMMDFMessage.add_flagcCsHd|ksd|krD|jdjt|jt|dS)z7Unset the given string flag(s) without changing others.r[zX-StatusrN)rHrxrrF)rrIrrrrKsz_mboxMMDFMessage.remove_flagc Csst|trt|j}d|kr:|jdd|krS|jdd|krl|jdd|kr|jdd|kr|jd|d =|d =d j|jjdd }y&|j t j t j |dWqottfk rYqoXnZt|trM|j|j|j|jn"t|trt|j}d|kr|jdd|kr|jdd|kr|jd|d =|d =nt|trGt|j}d|kr|jdd|kr|jdd|kr6|jd|d =|d =n(t|trYntdt|d S)zACopy mbox- or MMDF-specific state to message insofar as possible.rPrwrSrTrOrNrRrQZstatuszx-statusrZrQNz%a %b %d %H:%M:%S %Yr&rUrVr'r(z$Cannot convert to specified type: %s)rTr rrFrrJrxrrrcalendarZtimegmrZstrptimerJ OverflowErrorrrHrr r r rXrrirj)rrrGZ maybe_daterrrr>s^          %              z_mboxMMDFMessage._explain_to) rprqrrrsr@rrrrFrHrJrKr>rrrrr]s       rc@seZdZdZdS)r z&Message with mbox-specific properties.N)rprqrrrsrrrrr s c@sjeZdZdZdgZdddZddZdd Zd d Zd d Z ddZ dS)r z$Message with MH-specific properties. _sequencesNcCsg|_tj||dS)z!Initialize an MHMessage instance.N)r`rr)rrrrrrs zMHMessage.__init__cCs|jddS)z4Return a list of sequences that include the message.N)r`)rrrrrszMHMessage.get_sequencescCst||_dS)z3Set the list of sequences that include the message.N)r2r`)rrrrrr szMHMessage.set_sequencescCsKt|tr1||jkrG|jj|ntdt|dS)z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rTr`r`rrirj)rr%rrrr szMHMessage.add_sequencec Cs-y|jj|Wntk r(YnXdS)zARemove sequence from the list of sequences including the message.N)r`rrJ)rr%rrrremove_sequences zMHMessage.remove_sequencecCst|trt|j}d|kr=|jdn|jd|jdd|krp|jdd|kr|jdn3t|tr t|j}d|kr|jdn |jd d|kr|jdd|kr|jd nt|trAx|jD]}|j|q'Wn~t|t rt|j}d|kr{|j dd|kr|j d n(t|t rnt d t |d S)z6Copy MH-specific state to message insofar as possible.r&rwrNrVrSrUrOROrPrTr(z$Cannot convert to specified type: %sN)rTr rrrrJrr r r rXrrirj)rrrr%rrrr>s@              zMHMessage._explain_to) rprqrrrsr@rrr r rar>rrrrr s      c@seZdZdZddgZdddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ dS)r z'Message with Babyl-specific properties.r+_visibleNcCs)g|_t|_tj||dS)z#Initialize a BabylMessage instance.N)r+rrcr)rrrrrrs  zBabylMessage.__init__cCs|jddS)z'Return a list of labels on the message.N)r+)rrrrr,%szBabylMessage.get_labelscCst||_dS)z&Set the list of labels on the message.N)r2r+)rr3rrrr.)szBabylMessage.set_labelscCsKt|tr1||jkrG|jj|ntdt|dS)z+Add label to list of labels on the message.zlabel must be a string: %sN)rTr`r+rrirj)rr5rrrrX-szBabylMessage.add_labelc Cs-y|jj|Wntk r(YnXdS)z4Remove label from the list of labels on the message.N)r+rrJ)rr5rrr remove_label5s zBabylMessage.remove_labelcCs t|jS)z3Return a Message representation of visible headers.)rrc)rrrrr9<szBabylMessage.get_visiblecCst||_dS)z2Set the Message representation of visible headers.N)rrc)rZvisiblerrrr-@szBabylMessage.set_visiblecCsxG|jjD]6}||kr<|jj|||q|j|=qWx:dD]2}||krQ||jkrQ|||j|OsF               zBabylMessage._explain_to)rprqrrrsr@rr,r.rXrdr9r-rlr>rrrrr s         c@seZdZdZdS)r z&Message with MMDF-specific properties.N)rprqrrrsrrrrr ys c@seZdZdZdddZdddZdddZdd d Zdd d Zd dZ ddZ dddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zed$d%ZdS)&rzA read-only wrapper of a file.NcCs4||_|dkr'|j|_n ||_dS)zInitialize a _ProxyFile.N)rr_pos)rrposrrrrs  z_ProxyFile.__init__cCs|j||jjS)z Read bytes.)_readrrM)rsizerrrrMsz_ProxyFile.readcCs|j||jjS)z Read bytes.)rorread1)rrprrrrqsz_ProxyFile.read1cCs|j||jjS)z Read a line.)rorrg)rrprrrrgsz_ProxyFile.readlinecCsQg}xD|D]<}|j||dk r |t|8}|dkr Pq W|S)zRead multiple lines.Nr)rr)rsizehintr=rnrrr readliness    z_ProxyFile.readlinesccs&x|j}|sdS|VqWdS)zIterate over lines.N)rg)rrnrrrr6s  z_ProxyFile.__iter__cCs|jS)zReturn the position.)rm)rrrrrsz_ProxyFile.tellrcCsH|dkr|jj|j|jj|||jj|_dS)zChange position.rPN)rrZrmr)roffsetwhencerrrrZs z_ProxyFile.seekc Cs@t|dr<z#t|jdr1|jjWd|`XdS)zClose the file.rrGN)r@rrG)rrrrrGs z_ProxyFile.closecCsG|dkrd}|jj|j||}|jj|_|S)z"Read size bytes using read_method.NrPrS)rrZrmr)rrp read_methodr=rrrros   z_ProxyFile._readcCs|S)z$Context management protocol support.r)rrrr __enter__sz_ProxyFile.__enter__cGs|jdS)N)rG)rexcrrr__exit__sz_ProxyFile.__exit__cCs |jjS)N)rreadable)rrrrrzsz_ProxyFile.readablecCs |jjS)N)rwritable)rrrrr{sz_ProxyFile.writablecCs |jjS)N)rseekable)rrrrr|sz_ProxyFile.seekablecCs |jjS)N)rrD)rrrrrDsz_ProxyFile.flushcCs3t|dsdSt|jds)dS|jjS)NrTrF)r@rr)rrrrrs z_ProxyFile.closed)rprqrrrsrrMrqrgrsr6rrZrGrorwryrzr{r|rDpropertyrrrrrr}s$         rc@s[eZdZdZddddZddZddd Zd d Zd d ZdS)rz&A read-only wrapper of part of a file.NcCs)tj|||||_||_dS)zInitialize a _PartialFile.N)rr_start_stop)rrrrrrrrs z_PartialFile.__init__cCstj||jS)z*Return the position with respect to start.)rrr~)rrrrrsz_PartialFile.tellrcCsV|dkr!|j|_d}n|dkr?|j|_d}tj|||dS)z8Change position, possibly with respect to start or stop.rrPrON)r~rmrrrZ)rrtrurrrrZs     z_PartialFile.seekcCs]|j|j}|dkr dS|dksD|dksD||krJ|}tj|||S)z;Read size bytes using read_method, honoring start and stop.rrN)rrmrro)rrprvZ remainingrrrros  $z_PartialFile._readcCst|dr|`dS)Nr)r@r)rrrrrGsz_PartialFile.close) rprqrrrsrrrZrorGrrrrrs   rTc-Csd}ytrytj|tjtjBWn_tk r}z?|jtjtjtjfkryt d|j nWYdd}~XnX|ry!t |j d}|j WnGtk r}z'|jtjtjfkrdSWYdd}~XnXyft tdrEtj|j |j dd}tj|j n tj|j |j dd}Wn5tk rtj|j t d|j YnXWn>trtj|tj|rtj|j dYnXdS)z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNz.lockrTzdot lock unavailable: %s)fcntllockfZLOCK_EXZLOCK_NBrrZEAGAINrrrrrrGr@rrr!rrrLOCK_UN)rrZ dotlock_donerZpre_lockrrrrsF!  rcCsJtrtj|tjtjj|jdrFtj|jddS)z*Unlock file f using lockf and dot locking.z.lockN)rrrrrrzrr)rrrrr0src CsLtj|tjtjBtjBd}zt|dSWdtj|XdS)zCCreate a file if it doesn't exist and open for reading and writing.izrb+N)rrrrO_RDWRrG)rfdrrrr7s&rcCs2td|ttjtjtjfS)zBCreate a temp file based on path and open for reading and writing.z %s.%s.%s.%s)rrrrrrr)rrrrr?s rcCs0|jttdr,tj|jdS)z0Ensure changes to file f are physically on disk.fsyncN)rDr@rrfileno)rrrrrEs rcCst||jdS)z:Close file f, ensuring all changes are physically on disk.N)rrG)rrrrrKs rc@seZdZdZdS)Errorz"Raised for module-specific errors.N)rprqrrrsrrrrrQs rc@seZdZdZdS)r|z:The specified mailbox does not exist and won't be created.N)rprqrrrsrrrrr|Ts r|c@seZdZdZdS)rz>The specified mailbox is not empty and deletion was requested.N)rprqrrrsrrrrrWs rc@seZdZdZdS)rz)Another process caused an action to fail.N)rprqrrrsrrrrrZs rc@seZdZdZdS)rz)A file appears to have an invalid format.N)rprqrrrsrrrrr]s r)0rsrrr^rrr<rcr,Z email.messageZemail.generatorrUr(r ImportError__all__r\rHrrrrrrrrrrr rr r r r rrrrrrrr Exceptionrr|rrrrrrrsd                6B4-1%mqH_c')