eaiovnaovbqoebvqoeavibavo B  f>3@sRdZddlZddlZddlZddlZddlZddlZddlZddlZddl Zddl Zddl Z ddl Z y ddl Z Wnek rdZ YnXddddddd d d d d ddddddgZejdZGdddZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdd d ejjZGd d d eZGd!d"d"eZGd#d d eZGd$d d eZGd%d d eZ Gd&ddeZ!Gd'd(d(Z"Gd)d*d*e"Z#d=d,d-Z$d.d/Z%d0d1Z&d2d3Z'd4d5Z(d6d7Z)Gd8dde*Z+Gd9dde+Z,Gd:dde+Z-Gd;dde+Z.GdzDRead/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.NMailboxMaildirmboxMHBabylMMDFMessageMaildirMessage mboxMessage MHMessage BabylMessage MMDFMessageErrorNoSuchMailboxError NotEmptyErrorExternalClashError FormatErrorasciic@seZdZdZdCddZddZdd Zd d Zd d ZddZ dDddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/ZdEd0d1Zd2d3ZdFd4d5Zd6d7Zd8d9Zd:d;Zdd?Z!d@Z"dGdAdBZ#dS)Hrz*A group of messages in a particular place.NTcCs tjtj||_||_dS)zInitialize a Mailbox instance.N)ospathabspath expanduser_path_factory)selfrfactorycreater,/opt/alt/python37/lib64/python3.7/mailbox.py__init__$szMailbox.__init__cCs tddS)z$Add message and return assigned key.z&Method must be implemented by subclassN)NotImplementedError)rmessagerrradd)sz Mailbox.addcCs tddS)z=Remove the keyed message; raise KeyError if it doesn't exist.z&Method must be implemented by subclassN)r )rkeyrrrremove-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#rrrdiscard4szMailbox.discardcCs tddS)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#defaultrrrget?s z Mailbox.getc Cs6|js||St|| }||SQRXdS)z=Return the keyed message; raise KeyError if it doesn't exist.N)r get_message contextlibclosingget_file)rr#filerrrr)Fs zMailbox.__getitem__cCs tddS)z4Return a Message representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr,NszMailbox.get_messagecCst||S)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)rr#rrr get_stringRszMailbox.get_stringcCs tddS)z8Return a byte string representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr3YszMailbox.get_bytescCs tddS)z6Return a file-like representation or raise a KeyError.z&Method must be implemented by subclassN)r )rr#rrrr/]szMailbox.get_filecCs tddS)zReturn an iterator over keys.z&Method must be implemented by subclassN)r )rrrriterkeysaszMailbox.iterkeyscCs t|S)zReturn a list of keys.)listr6)rrrrkeysesz 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:)rrrrvaluesuszMailbox.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=)rrrritemssz Mailbox.itemscCs tddS)z9Return True if the keyed message exists, False otherwise.z&Method must be implemented by subclassN)r )rr#rrr __contains__szMailbox.__contains__cCs tddS)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#rrrclearsz Mailbox.clearcCs0y ||}Wntk r |SX|||S)z3Delete the keyed message and return it, or default.)r&r')rr#r*resultrrrpops   z Mailbox.popcCs*x$|D]}|||fSWtddS)z6Delete an arbitrary (key, message) pair and return it.zNo messages in mailboxN)r6rCr&)rr#rrrpopitemszMailbox.popitemc Csxt|dr|}nt|dr(|}n|}d}x6|D].\}}y |||<Wq6tk rbd}Yq6Xq6W|rttddS)z4Change the messages that correspond to certain keys.r=r>FTzNo message with key(s)N)hasattrr=r>r&)rargsourceZbad_keyr#r!rrrupdates     zMailbox.updatecCs tddS)z&Write any pending changes to the disk.z&Method must be implemented by subclassN)r )rrrrflushsz Mailbox.flushcCs tddS)zLock the mailbox.z&Method must be implemented by subclassN)r )rrrrlocksz Mailbox.lockcCs tddS)z#Unlock the mailbox if it is locked.z&Method must be implemented by subclassN)r )rrrrunlockszMailbox.unlockcCs tddS)zFlush and close the mailbox.z&Method must be implemented by subclassN)r )rrrrclosesz Mailbox.closecCs,y |dStk r&tdYnXdS)Nrz?String input must be ASCII-only; use bytes or a Message instead)encode UnicodeError ValueError)rr!rrr_string_to_bytess zMailbox._string_to_bytesFc Cst|tjjrvt}tj||d}||| d| }| dt }| ||jrr|t sr| t nt|tttjfrt|tjrtdtd|}t|tr||}|r| dd}| dt }| ||jr|t s| t nt|drt|dr2td td|j}d }x|}|d r^|d d d}n|d rz|d dd}|sP|r|drd|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 insteads From s >From readbufferzDUse of text mode files is deprecated, use a binary mode file insteadNs  sFrom s>From zInvalid message type: %s) isinstancer1r!rioBytesIO generatorBytesGeneratorflattenseekrSreplacelinesepwrite_append_newlineendswithstrbytesStringIOwarningswarnDeprecationWarninggetvaluerPrErTreadline startswith TypeErrortype) rr!targetZ mangle_from_rTgendataZlastlinelinerrr _dump_messagesZ                   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@seZdZdZdZd6ddZddZd 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)7rzA qmail-style Maildir mailbox.:NTcCst||||tj|jdtj|jdtj|jdd|_tj|js|rt|jdx*|j D]}t|dqnWn t |ji|_ ddd|_ d|_ d|_d S) zInitialize a Maildir instance.tmpnewcur)rzr{r|ir)r|r{g?N)rrrrjoinr_pathsexistsmkdirr<r_toc _toc_mtimes _last_read _skewfactor)rdirnamerrrrrrr s  zMaildir.__init__c Cs~|}y|||Wn*tk rB|t|jYnXt|t|t r|| }|j | }||j krd}nd}d}tj |j|j d}tj |j|||}t|t rt|jtj |j|fyLyt|j|Wn(ttfk rt|j|YnXt|jWnNtk rx}z.t|j|jtjkrftd|nWdd}~XYnX|S)z$Add message and return assigned key.r{rz$Name clash with existing message: %sN) _create_tmprt BaseExceptionrLrr$name _sync_closerYr get_subdircolonget_inforbasenamesplitr}rutimegetatimeget_datelinkAttributeErrorPermissionErrorrenameOSErrorerrnoZEEXISTr)rr!Ztmp_filesubdirsuffixuniqdesterrrr"!sB      z Maildir.addcCs ttj|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|tr.|}n|}tj|}|j|kr`|j||jd}nd}| |tj |j |} tj |j |||} t|trt | tj | |ft| | dS)z>Replace the keyed message; raise KeyError if it doesn't exist.rWrN)rr"rYr rrrrrr'r}rrrrr) rr#r!Z old_subpathZtemp_keyZ temp_subpathZdominant_subpathrrZtmp_pathnew_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)ropenrrr}rrr r set_subdirrset_infoset_dategetmtime)rr#Zsubpathfmsgrrrrrr,rs    zMaildir.get_messagec Cs8ttj|j||d}|tdSQRXdS)z2Return a bytes representation or raise a KeyError.rrQN) rrrr}rrrSr`ra)rr#rrrrr3szMaildir.get_bytescCs$ttj|j||d}t|S)z6Return a file-like representation or raise a KeyError.r)rrrr}rr _ProxyFile)rr#rrrrr/szMaildir.get_filec csH|x:|jD]0}y||Wntk r8wYnX|VqWdS)zReturn an iterator over keys.N)_refreshrrr&)rr#rrrr6s zMaildir.iterkeyscCs|||jkS)z9Return True if the keyed message exists, False otherwise.)rr)rr#rrrr?szMaildir.__contains__cCs|t|jS)z*Return a count of messages in the mailbox.)rlenr)rrrrr@szMaildir.__len__cCsdS)z"Write any pending changes to disk.Nr)rrrrrIsz Maildir.flushcCsdS)zLock the mailbox.Nr)rrrrrJsz Maildir.lockcCsdS)z#Unlock the mailbox if it is locked.Nr)rrrrrKszMaildir.unlockcCsdS)zFlush and close the mailbox.Nr)rrrrrLsz Maildir.closecCs`g}xVt|jD]F}t|dkr|ddkrtjtj|j|r||ddqW|S)zReturn a list of folder names.r.N)rlistdirrrrisdirr}append)rrBentryrrr list_folderss zMaildir.list_folderscCs ttj|jd||jddS)z/Return a Maildir instance for the named folder.rF)rr)rrrr}rr)rfolderrrr get_folderszMaildir.get_foldercCs\tj|jd|}t||jd}tj|d}tj|sXtt|tj tj Bd|S)z>Create a folder and return a Maildir instance representing it.r)rZ maildirfolderi) rrr}rrrrrLrO_CREATO_WRONLY)rrrrBZmaildirfolder_pathrrr add_folders zMaildir.add_foldercCs,tj|jd|}xTttj|dttj|dD](}t|dksZ|ddkr>td|q>WxPt|D]B}|dkrv|dkrv|dkrvtjtj||rvtd||fqvWx`tj|d d D]N\}}}x |D]}t tj||qWx |D]}t tj||qWqWt |d S) z-Delete the named folder, which must be empty.rr{r|rrzFolder contains message(s): %srzz%Folder contains subdirectory '%s': %sF)topdownN) rrr}rrrrrwalkr$rmdir)rrrrrootdirsfilesrrr remove_folders   zMaildir.remove_foldercCs\t}xNttj|jdD]4}tj|jd|}|tj|dkr t|q WdS)zDelete old files in "tmp".rzi@N)timerrrr}rrr$)rnowrrrrrcleans z Maildir.cleanrc Cst}t}d|kr$|dd}d|kr8|dd}dt|t|ddttj|f}tj |j d|}yt |Wn@t k rtjd7_yt|Stk rYnXYnXtd |d S) z=Create a file in the tmp subdirectory and open and return it./z\057ryz\072z%s.M%sP%sQ%s.%srg.Arzz&Name clash prevented file creation: %sN)rsocket gethostnamer`intrgetpidr_countrr}rstatr_create_carefullyFileExistsErrorr)rrZhostnamerrrrrrs&    zMaildir._create_tmpcCst|jd|jkrbd}x<|jD]2}tj|j|}||j|krLd}||j|<q$W|sbdSi|_xl|jD]b}|j|}xRt |D]D}tj ||}tj |rq| |j d}tj |||j|<qWqpWt|_dS)z!Update table of contents mapping.FTNr)rrrrrrrr~rrr}rrr)rZrefreshrmtimerrprrrrrs&    zMaildir._refreshcCs|y,tjtj|j|j|r*|j|SWntk r@YnX|y |j|Stk rvtd|dYnXdS)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|ds||_xReplace the keyed message; raise KeyError if it doesn't exist.TN)rrrr)rr#r!rrrr(hs z_singlefileMailbox.__setitem__ccs||jEdHdS)zReturn an iterator over keys.N)rrr8)rrrrr6nsz_singlefileMailbox.iterkeyscCs|||jkS)z9Return True if the keyed message exists, False otherwise.)rr)rr#rrrr?ssz_singlefileMailbox.__contains__cCs|t|jS)z*Return a count of messages in the mailbox.)rrr)rrrrr@xsz_singlefileMailbox.__len__cCs|jst|jd|_dS)zLock the mailbox.TN)r _lock_filer)rrrrrJ}s z_singlefileMailbox.lockcCs|jrt|jd|_dS)z#Unlock the mailbox if it is locked.FN)r _unlock_filer)rrrrrKs z_singlefileMailbox.unlockc Cs|js |jrt|jd|_dS|jdk s.t|jdd|j}||jkrbt d|j|ft |j }yi}| |xt |jD]|}|j|\}}|j||||}x0|jtd||j}|sP||qW||f||<||qW||_Wn"|t|jYnXt||jt|j j} t|j| yt|j|j Wn2tk rt|j t|j|j YnXt|j d|_||_d|_d|_|jrt |jdddS) z"Write any pending changes to disk.FNrrz4Size of mailbox file changed (expected %i, found %i)izrb+)dotlock)!rr _sync_flushrrAssertionErrorr_tellrr_create_temporaryr_pre_mailbox_hooksortedr8_pre_message_hookrSminrb_post_message_hookrLrr$rrrst_modechmodrrrrr) rZcur_lenZnew_fileZnew_tocr#startstopZ new_startrTmoderrrrIs`           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_hookcCs4z |Wdz|jr|Wd|jXXdS)zFlush and close the mailbox.N)rIrrKrrL)rrrrrLs   z_singlefileMailbox.closecCsL|jdkr||dk rHy |j|Stk rFtd|dYnXdS)z'Return (start, stop) or raise KeyError.NzNo message with key: %s)r _generate_tocr&)rr#rrrrs  z_singlefileMailbox._lookupcCs|jdd|j}t|jdkr8|js8||jy&||j||}| |jWn"t k r|j |YnX|j |j|_ |S)z;Append message to mailbox and return (start, stop) offsets.rr)rr_rrrrrr_install_messagerrtruncaterIr)rr!ZbeforeZoffsetsrrrrs       z"_singlefileMailbox._append_message)NT)N)rurvrwrxrr"r$r(r6r?r@rJrKrIrrrrLrrrrrrr>s"  @ rc@sBeZdZdZdZddZdddZddd Zdd d Zd d Z dS) _mboxMMDFzAn mbox or MMDF mailbox.TcCsp||\}}|j||jtd}|j||j}||td}| |dd d|S)z4Return a Message representation or raise a KeyError.rQrXNr) rrr_rlr`rarSr_message_factoryset_fromdecode)rr#rr from_linestringrrrrr,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}|tdS)z3Return a string representation or raise a KeyError.rQ)rrr_rlrSrr`ra)rr#rrrrrrrr3s   z_mboxMMDF.get_bytescCs<||\}}|j||s(|jt|j|j|S)z6Return a file-like representation or raise a KeyError.)rrr_rl _PartialFiler)rr#rrrrrrr/s   z_mboxMMDF.get_filecCs d}t|tr||}t|trf|drf|d}|dkr\|d|}||dd}q|}d}nJt|tr|d}d|}n(t|t j j r| }|dk r|d}|dkrdt t }|j}|j|t|||j|j|j}||fS) z1Format a message and blindly write to self._file.NsFrom rQrWrrrsFrom MAILER-DAEMON )rYrerPrfrmfind_mboxMMDFMessageget_fromrMr1r!r get_unixfromrasctimegmtimerrrbrart _mangle_from_)rr!rnewlineZauthorrrrrrr&s0         z_mboxMMDF._install_messageN)F)F)F) rurvrwrxrr,r5r3r/rrrrrrs  rc@s2eZdZdZdZdZd ddZddZdd ZdS) rzA classic mbox mailbox.TNcCst|_t||||dS)zInitialize an mbox mailbox.N)r rrr)rrrrrrrrLsz mbox.__init__cCs|tdS)z,Called after writing each message to file f.N)rbra)rrrrrrQszmbox._post_message_hookcCsgg}}d}|jdx|j}|j}|dr|t|t|krl|rb||ttn ||||d}q|s|r||ttn ||Pq|tkrd}qd}qWtt t |||_ t|j |_ |j|_ dS)z0Generate key-to-(start, stop) table of contents.FrsFrom TN)rr_rrlrmrrradict enumerateziprrr)rstartsstopsZlast_was_emptyline_posrsrrrrUs0         zmbox._generate_toc)NT) rurvrwrxrrcrrrrrrrrCs  c@s2eZdZdZd ddZddZdd Zd d ZdS) rzAn MMDF mailbox.NTcCst|_t||||dS)zInitialize an MMDF mailbox.N)r rrr)rrrrrrrrzsz MMDF.__init__cCs|dtdS)z-Called before writing each message to file f.sN)rbra)rrrrrrszMMDF._pre_message_hookcCs|tdtdS)z,Called after writing each message to file f.sN)rbra)rrrrrrszMMDF._post_message_hookcCsgg}}|jdd}x|}|j}|j}|dtr||xV|}|j}|j}|dtkr||ttPqN|sN||PqNWq|sPqWtt t |||_ t|j |_ |jdd|j|_ dS)z0Generate key-to-(start, stop) table of contents.rsrN)rr_rlrrmrarrrrrrrr)rrrnext_posrrsrrrrs2          zMMDF._generate_toc)NT)rurvrwrxrrrrrrrrrws  c@seZdZdZd0ddZddZdd 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)1rzAn MH mailbox.NTcCstt||||tj|jsj|r`t|jdtttj |jdtj tj Btj Bdn t |jd|_dS)zInitialize an MH instance.iz .mh_sequencesiFN)rrrrrrrrLrr}rO_EXCLrrr)rrrrrrrrs z MH.__init__cCs|}t|dkrd}n t|d}tj|jt|}t|}d}z|j rVt |zfy| ||Wn:t k r|j rt |t|d}t|YnXt|tr|||Wd|j rt |XWd|st|X|S)z$Add message and return assigned key.rrFTN)r8rmaxrrr}rrerrrrtrrrr$rYr _dump_sequences)rr!r8Znew_keyrrclosedrrrr"s6     zMH.addc Csxtj|jt|}yt|d}Wn>tk r`}z |jtjkrNt d|nWdd}~XYnX| t |dS)z=Remove the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN) rrr}rrerrrrr&rLr$)rr#rrrrrrr$s z MH.removec Cstj|jt|}yt|d}Wn>tk r`}z |jtjkrNt d|nWdd}~XYnXzd|j rrt |z@t t|tj tjB|||t|tr|||Wd|j rt|XWdt|XdS)z>Replace the keyed message; raise KeyError if it doesn't exist.zrb+zNo message with key: %sN)rrr}rrerrrrr&rrrLrO_TRUNCrtrYr r rr)rr#r!rrrrrrr(s$   zMH.__setitem__c Csy@|jr$ttj|jt|d}nttj|jt|d}Wn>tk r~}z |jtj krlt d|nWdd}~XYnX|2|jrt |z t |}Wd|jrt |XWdQRXx*|D]\}}||kr||qW|S)z4Return a Message representation or raise a KeyError.zrb+rzNo message with key: %sN)rrrrr}rrerrrr&rr r get_sequencesr> add_sequence)rr#rrrrkey_listrrrr,s&  zMH.get_messagec Csy@|jr$ttj|jt|d}nttj|jt|d}Wn>tk r~}z |jtj krlt d|nWdd}~XYnX|6|jrt |z| tdS|jrt|XWdQRXdS)z2Return a bytes representation or raise a KeyError.zrb+rzNo message with key: %sNrQ)rrrrr}rrerrrr&rrSr`rar)rr#rrrrrr3s z MH.get_bytesc Csfyttj|jt|d}Wn>tk r\}z |jtjkrJt d|nWdd}~XYnXt |S)z6Return a file-like representation or raise a KeyError.rzNo message with key: %sN) rrrr}rrerrrr&r)rr#rrrrrr/)s z MH.get_filecCsttddt|jDS)zReturn an iterator over keys.css|]}|rt|VqdS)N)isdigitr).0rrrr 6szMH.iterkeys..)iterrrrr)rrrrr64sz MH.iterkeyscCstjtj|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.)rr7r6)rrrrr@=sz MH.__len__cCs2|js.ttj|jdd|_t|jd|_dS)zLock the mailbox.z .mh_sequenceszrb+TN)rrrrr}rrr)rrrrrJAs zMH.lockcCs(|jr$t|jt|j|`d|_dS)z#Unlock the mailbox if it is locked.FN)rrrr)rrrrrKHs   z MH.unlockcCsdS)z&Write any pending changes to the disk.Nr)rrrrrIPszMH.flushcCs|jr|dS)zFlush and close the mailbox.N)rrK)rrrrrLTszMH.closecCs@g}x6t|jD]&}tjtj|j|r||qW|S)zReturn a list of folder names.)rrrrrr}r)rrBrrrrrYs zMH.list_folderscCsttj|j||jddS)z+Return an MH instance for the named folder.F)rr)rrrr}rr)rrrrrrasz MH.get_foldercCsttj|j||jdS)z:Create a folder and return an MH instance representing it.)r)rrrr}rr)rrrrrrfsz MH.add_foldercCs`tj|j|}t|}|dgkr:ttj|dn|gkrDntd|jt|dS)z-Delete the named folder, which must be empty.z .mh_sequenceszFolder not empty: %sN)rrr}rrr$rr)rrrentriesrrrrks  zMH.remove_folderc s i}ttj|jdddd}t|x|D]}y|d\}}t}xT|D]H}|rr| t |qVdd|dD\}} | t || d qVWfd d t |D||<t||d kr||=Wq2tk rtd |Yq2Xq2WWdQRX|S)z=Return a name-to-key-list dictionary to define each sequence.z .mh_sequencesrASCII)encodingrycss|]}t|VqdS)N)r)rxrrrrsz#MH.get_sequences..-rcsg|]}|kr|qSrr)rr#)all_keysrr sz$MH.get_sequences..rz"Invalid sequence specification: %sN)rrrr}rsetr8rrr"rrHrangerrrOrrstrip) rZresultsrrsrcontentsr8specrrr)rrrws&    zMH.get_sequencescCs ttj|jdddd}ztt|jtjtjBx| D]\}}t |dkrXqB| |dd}d}xbt t |D]R}|d |kr|sd }| d n*|rd}| d ||fn| d ||}q|W|r| t|dqB| dqBWWdt|XdS)z:Set sequences using the given name-to-key-list dictionary.z .mh_sequenceszr+r)rrryNFrTrz%s %sz %s )rrrr}rrLrrr r>rrbrrrer)r sequencesrrr8prevZ completingr#rrr set_sequencess.   zMH.set_sequencesc CsL|}d}g}x|D]}|d|kr|||dfy4ttj|jt|tj|jt|dWnHt t fk rt tj|jt|tj|jt|dYnXt tj|jt||d7}qW|d|_ t|dkrdSxB|D]6\}}x*|D]"\}}||kr||||<qWqW||dS)z?Re-name messages to eliminate numbering gaps. Invalidates keys.rrN)rr6rrrrr}rrerrrunlinkrrr>indexr%) rr#r$Zchangesr#rroldr{rrrpacks,      zMH.packcCs||}|}x<|D]0\}}||kr6||q||kr|||=qWx|D]}||krT|g||<qTW||dS)z;Inspect a new MHMessage and update sequences appropriately.N)rr>rr'r%)rr!r#Zpending_sequencesZ all_sequencesrrsequencerrrr s  zMH._dump_sequences)NT)rurvrwrxrr"r$r(r,r3r/r6r?r@rJrKrIrLrrrrrr%r)r rrrrrs. "  c@seZdZdZedddddddhZd%d d Zd dZddZddZ ddZ ddZ ddZ ddZ ddZddZdd Zd!d"Zd#d$Zd S)&rzAn Rmail-style Babyl mailbox.unseendeletedZfiledanswered forwardedZeditedresentNTcCst||||i|_dS)zInitialize a Babyl mailbox.N)rr_labels)rrrrrrrrszBabyl.__init__cCs(t||}t|tr$||j|<|S)z$Add message and return assigned key.)rr"rYr get_labelsr0)rr!r#rrrr"s  z Babyl.addcCs"t||||jkr|j|=dS)z=Remove the keyed message; raise KeyError if it doesn't exist.N)rr$r0)rr#rrrr$s  z Babyl.removecCs*t|||t|tr&||j|<dS)z>Replace the keyed message; raise KeyError if it doesn't exist.N)rr(rYr r1r0)rr#r!rrrr(s zBabyl.__setitem__c Cs||\}}|j||jt}x2|j}|dtksH|sJP||tdq.Wt}x.|j}|tks|sP||tdqjW||j }|dkst |j |}|td}t | |} | | ||jkr| |j|| S)z4Return a Message representation or raise a KeyError.s *** EOOH ***rQr)rrr_rlrZr[rarbr`rrrSr rk set_visibler0 set_labels) rr#rroriginal_headersrsZvisible_headersnZbodyrrrrr,s0         zBabyl.get_messagec Cs||\}}|j||jt}x2|j}|dtksH|sJP||tdq.Wx|j}|tksx|sbPqbW| }||j }|dkst |j |}|td}||S)z3Return a string representation or raise a KeyError.s *** EOOH ***rQr) rrr_rlrZr[rarbr`rkrrrS) rr#rrr4rsZheadersr5rrrrrr3s&        zBabyl.get_bytescCst||dtS)z6Return a file-like representation or raise a KeyError.rQ)rZr[r3r`ra)rr#rrrr/%szBabyl.get_filecCs@|t}x|jD]}||qW||jt|S)z4Return a list of user-defined labels in the mailbox.)rrr0r<rHdifference_update_special_labelsr7)rlabelsZ label_listrrrr1)s  zBabyl.get_labelscCs>gg}}|jdd}g}x|}|j}|j}|dtkrt|t|krf||tt||dd|jdddD}||q |dks|dtkrt|t|kr||ttq |s ||ttPq Wtt t |||_ tt ||_ t|j |_ |jdd |j|_dS) z0Generate key-to-(start, stop) table of contents.rs cSsg|]}|r|qSr)strip)rlabelrrrr@sz'Babyl._generate_toc..rN,r)rr_rlrrarrrrrrrr0rr)rrrrZ label_listsrrsr8rrrr2s4        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)rr:rrrrUsz*Babyl._pre_mailbox_hook..sLabels:r;r<N)rar1r}rb)rrZbabylr8rrrrPs zBabyl._pre_mailbox_hookcCs|dtdS)z-Called before writing each message to file f. N)rbra)rrrrrrZszBabyl._pre_message_hookcCs|tddS)z,Called after writing each message to file f.r<N)rbra)rrrrrr^szBabyl._post_message_hookcCs|j}t|trg}g}x0|D]$}||jkr@||q&||q&W|jdx |D]}|jd|q`W|jdx$|D]}|jd|dqW|jt n|jdt t|t j j r*t }t j|dd}|||dx4|}|j|d t |d ks6|s Pq W|jd t t|trt } t j| dd} | |xv| }|j|d t |d ks|sPqWn@|dx4|}|j|d t |d ks|sPqWx,|d } | s P|j| d t qWnXt|ttt jfr&t|t jrbtd td |}t|trx||}|dd} | ddkr|j|d| d t |jd t |j|d| d t |j|| dd t n(|jd t t |j|d t n\t |drrt |drRtdtd |j!}|} d}x|}|"dr|ddd }n|"dr|ddd }|j|d t |d ks|s`|rd}|jd t || nPq`Wx|}|sP|"dr$|ddt }n:|"drB|ddt }n|"d r^|ddt }|j|qWnt#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 rrWNrlrTzDUse of text mode files is deprecated, use a binary mode file insteadTs rUrVzInvalid message type: %s)%rrrYr r1r7rrbrMrar1r!rrZr[r\r]r^r_rlr` get_visiblerSrfrergrhrirjrkrPrrErTrdrnro)rr!rZspecial_labelsr8r:Z orig_bufferZorig_generatorrsZ vis_bufferZ vis_generatorrTZ body_startZ original_posZ first_passrrrrrbs                         zBabyl._install_message)NT)rurvrwrx frozensetr7rr"r$r(r,r3r/r1rrrrrrrrrrs      c@s*eZdZdZd ddZddZddZdS) rz0Message with mailbox-format-specific properties.NcCst|tjjr4|t|t|tr||nt|trP|t |n~t|t rl|t |nbt|t j r|t|nDt|dr|t|n(|dkrtjj|ntdt|dS)zInitialize a Message instance.rSNzInvalid message type: %s)rYr1r!r_become_messagecopyZdeepcopy _explain_torfr2reZmessage_from_stringrZ TextIOWrapperZmessage_from_filerEZmessage_from_binary_filerrnro)rr!rrrrs      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_specificrrrrrBs  zMessage._become_messagecCst|trdStddS)z:Copy format-specific state to message insofar as possible.Nz Cannot convert to specified type)rYrrn)rr!rrrrDs zMessage._explain_to)N)rurvrwrxrrBrDrrrrrs c@s|eZdZdZdddgZdddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZdS)r z)Message with Maildir-specific properties._subdir_info_dateNcCs&d|_d|_t|_t||dS)z%Initialize a MaildirMessage instance.r{rN)rIrJrrKrr)rr!rrrrs zMaildirMessage.__init__cCs|jS)zReturn 'new' or 'cur'.)rI)rrrrrszMaildirMessage.get_subdircCs(|dks|dkr||_n td|dS)zSet subdir to 'new' or 'cur'.r{r|z!subdir must be 'new' or 'cur': %sN)rIrO)rrrrrrszMaildirMessage.set_subdircCs"|jdr|jddSdSdS)z*Return as a string the flags that are set.z2,rNr)rJrm)rrrr get_flags s zMaildirMessage.get_flagscCsddt||_dS)z)Set the given flags and unset all others.z2,rN)r}rrJ)rflagsrrr set_flagsszMaildirMessage.set_flagscCs$|dt|t|BdS)z.Set the given flag(s) without changing others.rN)rNr}rrL)rflagrrradd_flagszMaildirMessage.add_flagcCs,|r(|dt|t|dS)z7Unset the given string flag(s) without changing others.rN)rLrNr}r)rrOrrr remove_flagszMaildirMessage.remove_flagcCs|jS)zSet "From " line, formatting and appending time_ if specified.NT )rrrr_)rrZtime_rrrrrs z_mboxMMDFMessage.set_fromcCs|dd|ddS)z*Return as a string the flags that are set.StatusrzX-Status)r+)rrrrrLzsz_mboxMMDFMessage.get_flagscCst|}d\}}x&dD]}||kr||7}||qWx&dD]}||kr>||7}||q>W|dt|7}y|d|Wn tk r|d|YnXy|d|Wn tk r|d|YnXdS)z)Set the given flags and unset all others.)rr)rUrV)rXrYrZrrazX-StatusN)rr$r}rreplace_headerr&Z add_header)rrMZ status_flagsZ xstatus_flagsrOrrrrN~s&  z_mboxMMDFMessage.set_flagscCs$|dt|t|BdS)z.Set the given flag(s) without changing others.rN)rNr}rrL)rrOrrrrPsz_mboxMMDFMessage.add_flagcCs4d|ksd|kr0|dt|t|dS)z7Unset the given string flag(s) without changing others.razX-StatusrN)rNr}rrL)rrOrrrrQsz_mboxMMDFMessage.remove_flagc Cst|trt|}d|kr(|dd|kr:|dd|krL|dd|kr^|dd|krp|d|d =|d =d |d d }y| t t |dWnttfk rYnXn t|tr||||nt|trZt|}d|kr$|dd|kr8|dd|krL|d|d =|d =nt|trt|}d|kr|dd|kr|dd|kr|d|d =|d =nt|trntdt|d S)zACopy mbox- or MMDF-specific state to message insofar as possible.rVr|rYrZrUrTrXrWZstatuszx-statusr`Nz%a %b %d %H:%M:%S %Yr+r[r\r,r-z$Cannot convert to specified type: %s)rYr rrLrrPr}rrrcalendarZtimegmrZstrptimerO OverflowErrorrrNrr rr r^rrnro)rr!rMZ maybe_daterrrrDs^                          z_mboxMMDFMessage._explain_to)N)N) rurvrwrxrFrrrrLrNrPrQrDrrrrr`s  rc@seZdZdZdS)r z&Message with mbox-specific properties.N)rurvrwrxrrrrr sc@sHeZdZdZdgZdddZddZdd Zd d Zd d Z ddZ dS)r z$Message with MH-specific properties. _sequencesNcCsg|_t||dS)z!Initialize an MHMessage instance.N)rfrr)rr!rrrrszMHMessage.__init__cCs|jddS)z4Return a list of sequences that include the message.N)rf)rrrrrszMHMessage.get_sequencescCst||_dS)z3Set the list of sequences that include the message.N)r7rf)rr#rrrr%szMHMessage.set_sequencescCs6t|tr"||jkr2|j|ntdt|dS)z8Add sequence to list of sequences including the message.zsequence type must be str: %sN)rYrerfrrnro)rr*rrrrs  zMHMessage.add_sequencecCs*y|j|Wntk r$YnXdS)zARemove sequence from the list of sequences including the message.N)rfr$rO)rr*rrrremove_sequenceszMHMessage.remove_sequencecCsJt|trdt|}d|kr*|dn|d|dd|krP|dd|krb|dnt|trt|}d|kr|dn |d d|kr|dd|kr|d nt|trx||D]}||qWn`t|t r(t|}d|kr| dd|krF| d nt|t r6nt d t |d S)z6Copy MH-specific state to message insofar as possible.r+r|rTr\rYr[rUROrVrZr-z$Cannot convert to specified type: %sN)rYr rrrrPrr rr r^rrnro)rr!r#r*rrrrDs@                     zMHMessage._explain_to)N) rurvrwrxrFrrr%rrgrDrrrrr s c@sbeZdZdZddgZdddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ dS)r z'Message with Babyl-specific properties.r0_visibleNcCsg|_t|_t||dS)z#Initialize a BabylMessage instance.N)r0rrir)rr!rrrr"szBabylMessage.__init__cCs|jddS)z'Return a list of labels on the message.N)r0)rrrrr1(szBabylMessage.get_labelscCst||_dS)z&Set the list of labels on the message.N)r7r0)rr8rrrr3,szBabylMessage.set_labelscCs6t|tr"||jkr2|j|ntdt|dS)z+Add label to list of labels on the message.zlabel must be a string: %sN)rYrer0rrnro)rr:rrrr^0s  zBabylMessage.add_labelcCs*y|j|Wntk r$YnXdS)z4Remove label from the list of labels on the message.N)r0r$rO)rr:rrr remove_label8szBabylMessage.remove_labelcCs t|jS)z3Return a Message representation of visible headers.)rri)rrrrr@?szBabylMessage.get_visiblecCst||_dS)z2Set the Message representation of visible headers.N)rri)rZvisiblerrrr2CszBabylMessage.set_visiblecCsjx6|jD](}||kr,|j|||q |j|=q Wx,dD]$}||kr>||jkr>|||j|<q>WdS)z9Update and/or sensibly generate a set of visible headers.)ZDateZFromzReply-ToZToZCCZSubjectN)rir8rb)rheaderrrrupdate_visibleGs  zBabylMessage.update_visiblecCsvt|tr~t|}d|kr*|dn|d|dd|ksNd|krX|dd|krj|dd |kr||d nt|trt|}d|kr|d n |d d |kr|d d|kr|dnt|trt|}d|kr|dd|krr|dnXt|t rT| | x<|D]}| |q>Wnt|t rbntdt|dS)z9Copy Babyl-specific state to message insofar as possible.r+r|rTr.r/r]r-rUr,rWrhrVrXrZr[z$Cannot convert to specified type: %sN)rYr rr1rrPrr rr r2r@r^rrnro)rr!r8r:rrrrDRsF                      zBabylMessage._explain_to)N)rurvrwrxrFrr1r3r^rjr@r2rlrDrrrrr s  c@seZdZdZdS)r z&Message with MMDF-specific properties.N)rurvrwrxrrrrr |sc@seZdZdZd&ddZd'ddZd(ddZd)d d Zd*d d Zd dZ ddZ d+ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zed$d%ZdS),rzA read-only wrapper of a file.NcCs$||_|dkr||_n||_dS)zInitialize a _ProxyFile.N)rr_pos)rrposrrrrs z_ProxyFile.__init__cCs|||jjS)z Read bytes.)_readrrS)rsizerrrrSsz_ProxyFile.readcCs|||jjS)z Read bytes.)rorread1)rrprrrrqsz_ProxyFile.read1cCs|||jjS)z Read a line.)rorrl)rrprrrrlsz_ProxyFile.readlinecCs>g}x4|D],}|||dk r |t|8}|dkr Pq W|S)zRead multiple lines.Nr)rr)rsizehintrBrsrrr readliness   z_ProxyFile.readlinesccs x|}|sdS|VqWdS)zIterate over lines.N)rl)rrsrrrr;s z_ProxyFile.__iter__cCs|jS)zReturn the position.)rm)rrrrrsz_ProxyFile.tellrcCs4|dkr|j|j|j|||j|_dS)zChange position.rN)rr_rmr)roffsetwhencerrrr_sz_ProxyFile.seekcCs0t|dr,zt|jdr"|jWd|`XdS)zClose the file.rrLN)rErrL)rrrrrLs   z_ProxyFile.closecCs2|dkr d}|j|j||}|j|_|S)z"Read size bytes using read_method.NrW)rr_rmr)rrp read_methodrBrrrros  z_ProxyFile._readcCs|S)z$Context management protocol support.r)rrrr __enter__sz_ProxyFile.__enter__cGs |dS)N)rL)rexcrrr__exit__sz_ProxyFile.__exit__cCs |jS)N)rreadable)rrrrrzsz_ProxyFile.readablecCs |jS)N)rwritable)rrrrr{sz_ProxyFile.writablecCs |jS)N)rseekable)rrrrr|sz_ProxyFile.seekablecCs |jS)N)rrI)rrrrrIsz_ProxyFile.flushcCs&t|dsdSt|jdsdS|jjS)NrTr F)rErr )rrrrr s   z_ProxyFile.closed)N)N)N)N)N)r)rurvrwrxrrSrqrlrsr;rr_rLrorwryrzr{r|rIpropertyr rrrrrs$        rc@s<eZdZdZdddZddZddd Zd d Zd d ZdS)rz&A read-only wrapper of part of a file.NcCst|||||_||_dS)zInitialize a _PartialFile.N)rr_start_stop)rrrrrrrrsz_PartialFile.__init__cCst||jS)z*Return the position with respect to start.)rrr~)rrrrrsz_PartialFile.tellrcCs<|dkr|j|_d}n|dkr*|j|_d}t|||dS)z8Change position, possibly with respect to start or stop.rrrN)r~rmrrr_)rrtrurrrr_sz_PartialFile.seekcCsB|j|j}|dkrdS|dks0|dks0||kr4|}t|||S)z;Read size bytes using read_method, honoring start and stop.rrN)rrmrro)rrprvZ remainingrrrros  z_PartialFile._readcCst|dr|`dS)Nr)rEr)rrrrrLs z_PartialFile.close)NN)r) rurvrwrxrrr_rorLrrrrrs    rTc Csd}yZtrpyt|tjtjBWnJtk rn}z,|jtjtjtjfkr\t d|j nWdd}~XYnX|r^yt |j d}| Wn:tk r}z|jtjtjfkrdSWdd}~XYnXy`yt |j |j dd}Wn2ttfk rt |j |j dd}YnXt |j Wn0tk r\t |j t d|j YnXWn8tr|t|tj|rt |j dYnXdS)z(Lock file f using lockf and dot locking.Fzlockf: lock unavailable: %sNz.lockTzdot lock unavailable: %s)fcntllockfZLOCK_EXZLOCK_NBrrZEAGAINrrrrrrLrrrrrr&rr$LOCK_UN)rrZ dotlock_donerZpre_lockrrrr sH    rcCs8trt|tjtj|jdr4t|jddS)z*Unlock file f using lockf and dot locking.z.lockN)rrrrrrrr$)rrrrr4src Cs8t|tjtjBtjBd}z t|dSt|XdS)zCCreate a file if it doesn't exist and open for reading and writing.izrb+N)rrrr O_RDWRrL)rfdrrrr;s rcCs$td|ttttfS)zBCreate a temp file based on path and open for reading and writing.z %s.%s.%s.%s)rrrrrrr)rrrrrCsrcCs$|ttdr t|dS)z0Ensure changes to file f are physically on disk.fsyncN)rIrErrfileno)rrrrrIs rcCst||dS)z:Close file f, ensuring all changes are physically on disk.N)rrL)rrrrrOsrc@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)0rxrrrdrrrCrhr1Z email.messageZemail.generatorrZr-r ImportError__all__rarMrrrrrrrrr!rr rr r r r rrrrrrrr Exceptionrrrrrrrrrsp     h8DB4-3z%mqH_c' *