ó õ^‚Rc@s|dZddlmZedddƒ[dZdZdZd Zdd lZdd lZdd l Z dd l Z dd l Z dd l Z dd l m Z d d ddgZd efd„ƒYZd fd„ƒYZe jdƒZd„Zdfd„ƒYZde jfd„ƒYZdefd„ƒYZdfd„ƒYZdd„Zdd„Zd„Zedkrxeƒnd S(sŸ MH interface -- purely object-oriented (well, almost) Executive summary: import mhlib mh = mhlib.MH() # use default mailbox directory and profile mh = mhlib.MH(mailbox) # override mailbox location (default from profile) mh = mhlib.MH(mailbox, profile) # override mailbox and profile mh.error(format, ...) # print error message -- can be overridden s = mh.getprofile(key) # profile entry (None if not set) path = mh.getpath() # mailbox pathname name = mh.getcontext() # name of current folder mh.setcontext(name) # set name of current folder list = mh.listfolders() # names of top-level folders list = mh.listallfolders() # names of all folders, including subfolders list = mh.listsubfolders(name) # direct subfolders of given folder list = mh.listallsubfolders(name) # all subfolders of given folder mh.makefolder(name) # create new folder mh.deletefolder(name) # delete folder -- must have no subfolders f = mh.openfolder(name) # new open folder object f.error(format, ...) # same as mh.error(format, ...) path = f.getfullname() # folder's full pathname path = f.getsequencesfilename() # full pathname of folder's sequences file path = f.getmessagefilename(n) # full pathname of message n in folder list = f.listmessages() # list of messages in folder (as numbers) n = f.getcurrent() # get current message f.setcurrent(n) # set current message list = f.parsesequence(seq) # parse msgs syntax into list of messages n = f.getlast() # get last message (0 if no messagse) f.setlast(n) # set last message (internal use only) dict = f.getsequences() # dictionary of sequences in folder {name: list} f.putsequences(dict) # write sequences back to folder f.createmessage(n, fp) # add message from file f as number n f.removemessages(list) # remove messages in list from folder f.refilemessages(list, tofolder) # move messages in list to other folder f.movemessage(n, tofolder, ton) # move one message to a given destination f.copymessage(n, tofolder, ton) # copy one message to a given destination m = f.openmessage(n) # new open message object (costs a file descriptor) m is a derived class of mimetools.Message(rfc822.Message), with: s = m.getheadertext() # text of message's headers s = m.getheadertext(pred) # text of message's headers, filtered by pred s = m.getbodytext() # text of message's body, decoded s = m.getbodytext(0) # text of message's body, not decoded iÿÿÿÿ(twarnpy3ksOthe mhlib module has been removed in Python 3.0; use the mailbox module insteadt stacklevelis ~/.mh_profiles~/Mails .mh_sequencesiÀN(tbisecttMHtErrortFoldertMessagecBseZRS((t__name__t __module__(((s/usr/lib/python2.7/mhlib.pyR[scBs’eZdZddd„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zd„ZRS(s<Class representing a particular collection of folders. Optional constructor arguments are the pathname for the directory containing the collection, and the MH profile to use. If either is omitted or empty a default is used; the default directory is taken from the MH profile if it is specified there.cCsÏ|dkrt}ntjj|ƒ|_|dkrH|jdƒ}n|sWt}ntjj|ƒ r’|ddkr’tjj d|ƒ}ntjj|ƒ}tjj |ƒsÂt d‚n||_dS(s Constructor.tPathit~sMH() path not foundN( tNonet MH_PROFILEtostpatht expandusertprofilet getprofiletPATHtisabstjointisdirR(tselfRR((s/usr/lib/python2.7/mhlib.pyt__init__fs   # cCsd|j|jfS(sString representation.s MH(%r, %r)(RR(R((s/usr/lib/python2.7/mhlib.pyt__repr__rscGstjjd||ƒdS(sARoutine to print an error. May be overridden by a derived class.s MH error: %s N(tsyststderrtwrite(Rtmsgtargs((s/usr/lib/python2.7/mhlib.pyterrorvscCst|j|ƒS(s*Return a profile entry, None if not found.(tpicklineR(Rtkey((s/usr/lib/python2.7/mhlib.pyRzscCs|jS(s9Return the path (the name of the collection's directory).(R(R((s/usr/lib/python2.7/mhlib.pytgetpath~scCs7ttjj|jƒdƒdƒ}|s3d}n|S(s&Return the name of the current folder.tcontextsCurrent-Foldertinbox(RR RRR!(RR"((s/usr/lib/python2.7/mhlib.pyt getcontext‚s   cCsItjj|jƒdƒ}t|dƒ}|jd|ƒ|jƒdS(s#Set the name of the current folder.R"twsCurrent-Folder: %s N(R RRR!topenRtclose(RR"tfntf((s/usr/lib/python2.7/mhlib.pyt setcontext‰scCsqg}|jƒ}xNtj|ƒD]=}tjj||ƒ}tjj|ƒr"|j|ƒq"q"W|jƒ|S(s*Return the names of the top-level folders.(R!R tlistdirRRRtappendtsort(RtfoldersRtnametfullname((s/usr/lib/python2.7/mhlib.pyt listfolderss  c CsÔtjj|j|ƒ}tj|ƒj}|dkr:gSg}tj|ƒ}xt|D]l}tjj||ƒ}tjj|ƒrVtjj||ƒ}|j|ƒ|d}|dkrÂPqÂqVqVW|jƒ|S(scReturn the names of the subfolders in a given folder (prefixed with the given folder name).ii( R RRtstattst_nlinkR+RR,R-( RR/R0tnlinkst subfolderstsubnamestsubnamet fullsubnamet name_subname((s/usr/lib/python2.7/mhlib.pytlistsubfolders›s        cCs |jdƒS(s<Return the names of all folders and subfolders, recursively.t(tlistallsubfolders(R((s/usr/lib/python2.7/mhlib.pytlistallfolders³sc Cs$tjj|j|ƒ}tj|ƒj}|dkr:gSg}tj|ƒ}xÄ|D]¼}|ddksVt|ƒr~qVntjj||ƒ}tjj|ƒrVtjj||ƒ}|j|ƒtjj |ƒsõ|j |ƒ} || }n|d}|dkrPqqVqVW|j ƒ|S(s>Return the names of subfolders in a given folder, recursively.iit,i( R RRR2R3R+t isnumericRR,tislinkR<R-( RR/R0R4R5R6R7R8R9t subsubfolders((s/usr/lib/python2.7/mhlib.pyR<·s,         cCs t||ƒS(s0Return a new Folder object for the named folder.(R(RR/((s/usr/lib/python2.7/mhlib.pyt openfolderÓscCset|jdƒ}|r6t|ƒr6t|dƒ}nt}tjtjj|j ƒ|ƒ|ƒdS(s@Create a new folder (or raise os.error if it cannot be created).sFolder-ProtectiN( RRR?tinttFOLDER_PROTECTR tmkdirRRR!(RR/tprotecttmode((s/usr/lib/python2.7/mhlib.pyt makefolder×s cCs”tjj|jƒ|ƒ}xetj|ƒD]T}tjj||ƒ}ytj|ƒWq+tjk r~|jd|ƒq+Xq+Wtj|ƒdS(s‡Delete a folder. This removes files in the folder but not subdirectories. Raise os.error if deleting the folder itself fails.s%s not deleted, continuing...N(R RRR!R+tunlinkRtrmdir(RR/R0R7R8((s/usr/lib/python2.7/mhlib.pyt deletefolderàs N(RRt__doc__R RRRRR!R$R*R1R:R=R<RBRHRK(((s/usr/lib/python2.7/mhlib.pyR_s           s ^[1-9][0-9]*$cCstj|ƒdk S(N(t numericprogtmatchR (tstr((s/usr/lib/python2.7/mhlib.pyR?ïscBsòeZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zdd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„ZRS(s'Class representing a particular folder.cCs>||_||_tjj|jƒƒs:td|‚ndS(s Constructor.s no folder %sN(tmhR/R RRt getfullnameR(RRPR/((s/usr/lib/python2.7/mhlib.pyRõs  cCsd|j|jfS(sString representation.sFolder(%r, %r)(RPR/(R((s/usr/lib/python2.7/mhlib.pyRüscGs|jj|ŒdS(sError message handler.N(RPR(RR((s/usr/lib/python2.7/mhlib.pyRscCstjj|jj|jƒS(s'Return the full pathname of the folder.(R RRRPR/(R((s/usr/lib/python2.7/mhlib.pyRQscCstjj|jƒtƒS(s8Return the full pathname of the folder's sequences file.(R RRRQt MH_SEQUENCES(R((s/usr/lib/python2.7/mhlib.pytgetsequencesfilenamescCstjj|jƒt|ƒƒS(s4Return the full pathname of a message in the folder.(R RRRQRO(Rtn((s/usr/lib/python2.7/mhlib.pytgetmessagefilename scCs|jj|jƒS(s!Return list of direct subfolders.(RPR:R/(R((s/usr/lib/python2.7/mhlib.pyR:scCs|jj|jƒS(sReturn list of all subfolders.(RPR<R/(R((s/usr/lib/python2.7/mhlib.pyR<scCsg}tj}|j}x6tj|jƒƒD]}||ƒr.||ƒq.q.Wtt|ƒ}|jƒ|r€|d|_ n d|_ |S(s€Return the list of messages currently present in the folder. As a side effect, set self.last to the last message (or 0).iÿÿÿÿi( RMRNR,R R+RQtmapRCR-tlast(RtmessagesRNR,R/((s/usr/lib/python2.7/mhlib.pyt listmessagess     cCsÔi}|jƒ}yt|dƒ}Wntk r9|SXx“|jƒ}|sSPn|jdƒ}t|ƒdkr”|jd||jƒfƒn|djƒ}t|djƒdƒj ƒ}|||iismultiple errors:N( RUROR RIRtrenameR,tremovefromallsequencesR`(RtlistterrorstdeletedRTRt commapathR((s/usr/lib/python2.7/mhlib.pytremovemessagesÑs( ic Cs„g}i}xö|D]î}|jƒd}|j|ƒ}|j|ƒ} ytj|| ƒWnŒtjk réy!tj|| ƒtj|ƒWqêttjfk rå} |j | ƒytj| ƒWqtjk rÞqXqqêXnX|j |ƒ|||RxcCs5g|_||_||_|r1|j|ƒndS(N(tpairstseptrngt fromstring(RtdataRãRä((s/usr/lib/python2.7/mhlib.pyRs    cCs g|_dS(N(Râ(R((s/usr/lib/python2.7/mhlib.pytreset scCst|j|jƒS(N(tcmpRâ(Rtother((s/usr/lib/python2.7/mhlib.pyt__cmp__#scCs t|jƒS(N(thashRâ(R((s/usr/lib/python2.7/mhlib.pyt__hash__&scCsd|jƒ|j|jfS(NsIntSet(%r, %r, %r)(RkRãRä(R((s/usr/lib/python2.7/mhlib.pyR)scCs¤|jjƒd}xŠ|t|jƒkrŸ|j|d\}}|j|\}}||dkr’|t||ƒfg|j|d|d+q|d}qWdS(Ni(RâR-R`Rp(RR~talotahitblotbhi((s/usr/lib/python2.7/mhlib.pyt normalize,s -cCs|d}xo|jD]d\}}||kr7t|ƒ}nt|ƒ|jt|ƒ}|rn||j|}q|}qW|S(NR;(RâR»RäRã(RRmtlothitt((s/usr/lib/python2.7/mhlib.pyRk7s  cCsAg}x4|jD])\}}t||dƒ}||}qW|S(Ni(Râtrange(RtlRòRótm((s/usr/lib/python2.7/mhlib.pyRc@s cCs"x|D]}|j|ƒqWdS(N(R,(RR‘R~((s/usr/lib/python2.7/mhlib.pyRjGs cCstƒ}|j|_|S(N(RbRâ(RR©((s/usr/lib/python2.7/mhlib.pytcloneKs  cCs|jddS(Ni(Râ(R((s/usr/lib/python2.7/mhlib.pytminPscCs|jddS(Niÿÿÿÿ(Râ(R((s/usr/lib/python2.7/mhlib.pyRpSscCs>x7|jD],\}}||ko-|knr tSq WtS(N(RâtTruetFalse(RtxRòRó((s/usr/lib/python2.7/mhlib.pytcontainsVscCsqxøtt|jƒƒD]á}|j|\}}||krç|d|kra||f|j|/dev/nulls<-- picksf.listmessages()(sfirstslastscurR‰sprevsnextsfirst:3slast:3scur:3scur:-3sprev:3snext:3s1:3s1:-3s100:3s100:-3s10000:3s10000:-3sall(R tsystemRRPRBR)RhRbRcRntreversedR$RtpopenR¯RVRCR_( Rt testfoldersRôRsR"RlRtstuffR‘((s/usr/lib/python2.7/mhlib.pyttestÂsP                      t__main__(RLtwarningsRR RRRRDR RRR¹RÔR—Rt__all__t ExceptionRRRRMR?RRR×RbRRuRR(((s/usr/lib/python2.7/mhlib.pyt6s<         ÿ¦M‰  " *