Ϫf9 dZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z mZddlmZddlmZddlmZmZmZddlmZddlmZdd lmZmZdd lmZm Z m!Z!dd l"m#Z#dd l$m%Z%m&Z&m'Z'm(Z(m)Z)dd l*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:ddl;mZ>m?Z@mAZBmCZDmEZFmGZHmIZJmKZLmMZNmOZOmPZQddlRmSZSmTZTddlUmVZVmWZWddlXmYZYmZZZm[Z[m\Z\m]Z]e^e_e`dddjZbdZcdZdGddZeGddZfGddZgGddZhGdd Zid!Zjekee`d"e`d#d$Zld%ejzelzZmemjd&Zoejd'eozd(zZqekd)e`d$DZreeFGd*d+eSjeTjZue jZweeFGd,d-eSjeTjZxdwd.Zyd/Zzd0Z{e|Z}dxd1Z~d2Zd3Zdwd4Zd5Zd6Zd7Zdyd8Zd9Zd:ekd;ekfd<ZGd=d>Zd?Zd@ZdAZdBZdCZdDZee=GdEdFZeeOGdGdHeZdIdJdKdLdMdNZdOZdPZdQZdRZdSZdTZdUZGdVdWZGdXdYeZGdZd[eZGd\d]eZGd^d_eZdzd`ZdaZdbZdcZGdddeZGdfdgZGdhdiZdjZeedkdlZdmZdnZdwdoZdwdpZGdqdrejZZGdsdtej\Zej^eeeeZduZejdegdvZy){a An IMAP4 protocol implementation @author: Jp Calderone To do:: Suspend idle timeout while server is processing Use an async message parser instead of buffering in memory Figure out a way to not queue multi-message client requests (Flow? A simple callback?) Clarify some API docs (Query, etc) Make APPEND recognize (again) non-existent mailboxes before accepting the literal N) decodebytes encodebytes)BytesIO)chain)AnyListcast) implementer) credentials)UnauthorizedLoginUnhandledCredentials)defererror interfaces) maybeDeferred)CramMD5ClientAuthenticatorLOGINAuthenticatorLOGINCredentialsPLAINAuthenticatorPLAINCredentials)IllegalClientResponseIllegalIdentifierErrorIllegalMailboxEncodingIllegalOperationIllegalQueryErrorIllegalServerResponseIMAP4ExceptionMailboxCollisionMailboxExceptionMismatchedNestingMismatchedQuotingNegativeResponse NoSuchMailboxNoSupportedAuthenticationReadOnlyMailboxUnhandledResponse) IAccountIMAPIClientAuthenticationICloseableMailboxIMAP IMailboxIMAPIMailboxIMAPInfoIMailboxIMAPListener IMessageIMAPIMessageIMAPCopierIMessageIMAPFileIMessageIMAPPartINamespacePresenterISearchableIMAPMailbox)basicpolicies)logtext)_get_async_param_matchingString iterbytes nativeString networkString z/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Decc||ur|S|S)z Swap C{this} with C{that} if C{this} is C{ifIs}. @param this: The object that may be replaced. @param that: The object that may replace C{this}. @param ifIs: An object whose identity will be compared to C{this}. )thisthatifIss 4/usr/lib/python3/dist-packages/twisted/mail/imap4.py_swaprD`s4<4)T)c h|Dcgc]\}}t|||t|||f!c}}Scc}}w)a Swap each element in each pair in C{of} with C{that} it is C{ifIs}. @param of: A list of 2-L{tuple}s, whose members may be the object C{that} @type of: L{list} of 2-L{tuple}s @param ifIs: An object whose identity will be compared to members of each pair in C{of} @return: A L{list} of 2-L{tuple}s with all occurences of C{ifIs} replaced with C{that} )rD)ofrArBfirstseconds rC _swapAllPairsrJns> TV BO%udD !5t#<=  s$.ceZdZUdZgZeeed<edZ eefdZ e dZ e jdZ efdZdZd Zd Zd Zd Zd ZdZdZdefdZdefdZdedefdZy) MessageSeta A set of message identifiers usable by both L{IMAP4Client} and L{IMAP4Server} via L{IMailboxIMAP.store} and L{IMailboxIMAP.fetch}. These identifiers can be either message sequence numbers or unique identifiers. See Section 2.3.1, "Message Numbers", RFC 3501. This represents the C{sequence-set} described in Section 9, "Formal Syntax" of RFC 3501: - A L{MessageSet} can describe a single identifier, e.g. C{MessageSet(1)} - A L{MessageSet} can describe C{*} via L{None}, e.g. C{MessageSet(None)} - A L{MessageSet} can describe a range of identifiers, e.g. C{MessageSet(1, 2)}. The range is inclusive and unordered (see C{seq-range} in RFC 3501, Section 9), so that C{Message(2, 1)} is equivalent to C{MessageSet(1, 2)}, and both describe messages 1 and 2. Ranges can include C{*} by specifying L{None}, e.g. C{MessageSet(None, 1)}. In all cases ranges are normalized so that the smallest identifier comes first, and L{None} always comes last; C{Message(2, 1)} becomes C{MessageSet(1, 2)} and C{MessageSet(None, 1)} becomes C{MessageSet(1, None)} - A L{MessageSet} can describe a sequence of single identifiers and ranges, constructed by addition. C{MessageSet(1) + MessageSet(5, 10)} refers the message identified by C{1} and the messages identified by C{5} through C{10}. B{NB: The meaning of * varies, but it always represents the largest number in use}. B{For servers}: Your L{IMailboxIMAP} provider must set L{MessageSet.last} to the highest-valued identifier (unique or message sequence) before iterating over it. B{For clients}: C{*} consumes ranges smaller than it, e.g. C{MessageSet(1, 100) + MessageSet(50, None)} is equivalent to C{1:*}. @type getnext: Function taking L{int} returning L{int} @ivar getnext: A function that returns the next message number, used when iterating through the L{MessageSet}. By default, a function returning the next integer is supplied, but as this can be rather inefficient for sparse UID iterations, it is recommended to supply one when messages are requested by UID. The argument is provided as a hint to the implementation and may be ignored if it makes sense to do so (eg, if an iterator is being used that maintains its own state, it is guaranteed that it will not be called out-of-order). _emptyinfc|j|_g|_d|_||juryt |t r|dd|_|j y|j||y)z Create a new MessageSet() @type start: Optional L{int} @param start: Start of range, or only message number @type end: Optional L{int} @param end: End of range. c |dzSNr<r?xs rCz%MessageSet.__init__..s QrEN)rM_lastrangesgetnext isinstancelistcleanaddselfstartends rC__init__zMessageSet.__init__sZ[[  &  DKK   eT "(DK JJL HHUC rEc|jS)z{ The largest number in use. This is undefined until it has been set by assigning to this property. )rUr]s rClastzMessageSet.lasts zzrEc|j|jur td||_t|jD]*\}\}}||}||}||kDr||}}||f|j|<,|j y)z Replaces all occurrences of "*". This should be the largest number in use. Must be set before attempting to use the MessageSet as a container. @raises ValueError: if a largest value has already been set. zlast already setN)rUrM ValueError enumeraterVrZ)r]valueilowhighs rCrczMessageSet.lasts ::T[[ (/0 0 ' 4 )NA{T{|Tz #T!4[DKKN ) rEcR||jur|}|j|jur| |j}| |j}t||gt j t |jd\}}|jj||f|jy)z Add another range @type start: L{int} @param start: Start of range, or only message number @type end: Optional L{int} @param end: End of range. NrArB)key) rMrUrcsorted functoolspartialrD _infinityrVappendrZr\s rCr[zMessageSet.adds $++ C ::T[[ (} {ii CLi//DNNQUV s E3<( rEcLt|tr$|j|jz}t|St|j}|j|jur|j|_ |j ||S#t $r|j |Y|SwxYwN)rXrLrVrcrMr[ TypeError)r]otherrVress rC__add__zMessageSet.__add__s eZ ([[5<</Ff% %T[[)Cyy +99 J J s4BB#"B#ct|tr7|jj|j|j |S |j ||S#t $r|j |Y|SwxYw)z Extend our messages with another message or set of messages. @param other: The messages to include. @type other: L{MessageSet}, L{tuple} of two L{int}s, or a single L{int} )rXrLrVextendrZr[rur]rvs rCrzzMessageSet.extendso eZ ( KK  u|| , JJL  %     s AA87A8cZtt|j|jd}t dt dfg}|D]D\}}|d\}}||dz kr|j ||f*t ||t||f|d<Ft|ddd|j|_y)z> Clean ranges list, combining adjacent ranges Nrlz-infr<)rnrJrVrqfloatrrminmax)r]rV mergedRangesrirj previousLow previousHighs rCrZzMessageSet.clean0s  dkkTRSvf 67  PIC(4R(8 %KcAg%##S$K0 #K 5s<7NOL  P$L$44dnnU rEc*|jddduS)a Is there a L{None} in our ranges? L{MessageSet.clean} merges overlapping or consecutive ranges. None is represents a value larger than any number. There are thus two cases: 1. C{(x, *) + (y, z)} such that C{x} is smaller than C{y} 2. C{(z, *) + (x, y)} such that C{z} is larger than C{y} (Other cases, such as C{y < x < z}, can be split into these two cases; for example C{(y - 1, y)} + C{(x, x) + (z, z + 1)}) In case 1, C{* > y} and C{* > z}, so C{(x, *) + (y, z) = (x, *)} In case 2, C{z > x and z > y}, so the intervals do not merge, and the ranges are sorted as C{[(x, y), (z, *)]}. C{*} is represented as C{(*, *)}, so this is the same as 2. but with a C{z} that is greater than everything. The result is that there is a maximum of two L{None}s, and one of them has to be the high element in the last tuple in C{self.ranges}. That means checking if C{self.ranges[-1][-1]} is L{None} suffices to check if I{any} element is L{None}. @return: L{True} if L{None} is in some range in ranges and L{False} if otherwise. r}N)rVrbs rC _noneInRangeszMessageSet._noneInRangesDs>{{2r"d**rEc|jr td|jD]\}}||cxkr|ksyy)z May raise TypeError if we encounter an open-ended range @param value: Is this in our ranges? @type value: L{int} z.Can't determine membership; last value not setTF)rrurV)r]rgrirjs rC __contains__zMessageSet.__contains__esM    LM M ICe#t#$ rEc#K|jD]:\}}|j|dz }||ks ||j|}||kr<ywrQ)rVrW)r]lhs rC _iteratorzMessageSet._iteratorvsQKK $DAq QU#Aq&LLOq& $s,A A  A cX|jr td|jS)Nz!Can't iterate; last value not set)rrurrbs rC__iter__zMessageSet.__iter__}s'    ?@ @~~rEcrd}|jD]%\}}||dz }| td|||z dzz }'|S)Nrr<z%Can't size object; last value not set)rVru)r]rwrrs rC__len__zMessageSet.__len__sVKK #DAqyq GHHA{"  # rEreturncg}|jD]g\}}||k(r/||jd|jt|:||jd|fzR|jd||fzidj|S)N*z%d:*z%d:%d,)rVrrstrjoin)r]prirjs rC__str__zMessageSet.__str__s  0ICd{;HHSMHHSX&3&)C;./ 0xx{rEc dt|dS)Nz )rrbs rC__repr__zMessageSet.__repr__sc$i[**rErvc|t|tr'tt|j|jk(St Srt)rXrLr boolrVNotImplementedr{s rC__eq__zMessageSet.__eq__s, eZ (dkkU\\9: :rEN)__name__ __module__ __qualname____doc__rMrr__annotations__r~rqr`propertyrcsetterr[rxrzrZrrrrrrrrobjectrrr?rErCrLrLs7rFDIe I#!0 [[,$2 &V(+B"$   +#+FtrErLceZdZdZdZdZy) LiteralStringc.||_g|_||_yrt)sizedatarr]rdefereds rCr`zLiteralString.__init__s   rEc2|xjt|zc_d}|jdkDr|jj||S|jr|d|j||jd}}nd}|r|jj||SNrrE)rlenrrrr]rpassons rCwritezLiteralString.writes SY  99q= II  T " yy#Kdii0$tyy{2Cf   & rEcp|jjdj|j|fy): Call deferred with data and rest of line rEN)rcallbackrrr]lines rCrzLiteralString.callbacks( SXXdii0$78rEN)rrrr`rrr?rErCrrs 9rErc"eZdZdZdZdZdZy) LiteralFilec||_||_||jkDrtj|_yt |_yrt)rr_memoryFileLimittempfile TemporaryFilerrrs rCr`zLiteralFile.__init__s7  $'' ' ..0DI DIrEc2|xjt|zc_d}|jdkDr|jj||S|jr|d|j||jd}}nd}|r|jj||Sr)rrrrrs rCrzLiteralFile.writes SY  99q= IIOOD ! yy#Kdii0$tyy{2Cf % rEc|jjdd|jj|j|fy)rrN)rseekrrrs rCrzLiteralFile.callbacks1 q! TYY-.rEN)rrrrr`rrr?rErCrrs'" /rErc$eZdZdZddZdZdZy) WriteBufferzU Buffer up a bunch of writes before sending them all to a transport at once. c<||_||_d|_g|_yNr) bufferSize transport_length_writes)r]rrs rCr`zWriteBuffer.__init__s"  rEc|xjt|z c_|jj||j|jkDr|j yyrt)rrrrrrflushr]ss rCrzWriteBuffer.writesD A  A <<$// ) JJL *rEc|jr4|jj|jg|_d|_yyr)rr writeSequencerrbs rCrzWriteBuffer.flushs2 << NN ( ( 6DLDL rEN)i )rrrrr`rrr?rErCrrs  rErcBeZdZdZdZdZdZ d dZdefdZ dZ d Z y) Command) CAPABILITYFLAGSLISTLSUBSTATUSSEARCH NAMESPACE)EXISTSEXPUNGEFETCHRECENT) UIDVALIDITYUNSEEN READ-WRITE READ-ONLYUIDNEXTPERMANENTFLAGSNcZ||_||_||_fd|_g|_y)Nc|giSrtr?)rScontArgscontKw continuations rCrTz"Command.__init__..sl1&Jx&J6&JrE)commandargs wantResponserlines)r]rrrrrrs ```rCr`zCommand.__init__s*  (J rErcdj|j|j|j|j|j S)Nz()formatrrrrrrbs rCrzCommand.__repr__s89@@ LL$))T%6%68I8I4::  rEc|jdj||jfSdj||j|jfSN )rrrr]tags rCrzCommand.format$sB 99 99c4<<01 1yy#t||TYY788rEcg}g}|jD]}t|}t|}|dk\r|d|jvsJ|dk\r|d|jvs4|dk\rA|ddk(r9t |dt r&|dd|jvr|j||j||jdc}|_ |j||f|r ||yy)Nr<rOK) rparseNestedParensr _1_RESPONSES _2_RESPONSESrXrY _OK_RESPONSESrrrr) r]lastLineunusedCallbacksendunuseLnamesNds rCfinishzCommand.finish)s $A%a(EE AQ!H 1 116!H 1 116!H%uQx.!HQK4#5#55 E" U# $  D 4: D(#$  5 ! rE)Nr?N) rrrrrrrr`rrrrr?rErCrrsEL@LM E   # 9 "rErr!s ]\\(){%*"charmap[]c#2K|]}|tvs |ywrt) _nonAtomChars).0chs rC rRsH"-0G2Hs ceZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZdZdZhdZd Zd Zdd Zd Zd ZdZdZdZdZdZdZdZdZddZdZ dZ!dZ"dZ#dZ$dZ%dZ&ddZ'e(jRde(jTe+zdzZ,d Z-d!Z.d"Z/d#Z0d$Z1d%Z2d&Z3d'Z4d(Z5d)Z6d*Z7d+Z8dd,Z9dd-Z:dd.Z;dd/Zd2Z?d3Z@e@fZAeAZBeAZCeAZDd4ZEeEfZFeFZGeFZHeFZId5ZJeJfZKeKZLeKZMeKZNd6ZOeOe-fZPd7ZQd8ZRd9ZSd:ZTd;ZUd<ZVd=ZWeWfZXd>ZYeYe'e&fZZd?Z[d@Z\dAZ]dBZ^e^fZ_e_Z`dCZadDZbdEZceae'dFdGfZdedZeeae'dHdIfZfefZgdJZhdKZiehfZjejZkdLZlele&fZmemZndMZoeoe&fZpepZqdNZrere'e&fZsesZtdOZueue&fZvevZwdPZxexe&fZyeyZzdQZ{dRZ|dSZ}e{e'e'dHdTfZ~e~Ze{e'e'dFdUfZeZdVZdWZdXZee'e.fZeZdYZdZZd[Zd\Zd]Zee'e5e6e/fZeZd^Zd_Zd`ZefZdaZdbZdcZddZefZdeZdfZdgZefZdhZdiZddjZee7e0fZdkZddlZdmZdnZdoZdpZdqZdrZdsZdtZduZdvZdwZdxZdyZdzZd{Zd|Zd}Zd~ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZddZee1e2fZdZdZddZddZddZddZddZddZddZddZddZddZdZdZddZee1e-e3fZdZdZddZee1e&fZdZdZdZdZdZdZee-e4fZdZdZdZy) IMAP4Serverz Protocol implementation for an IMAP4rev1 server. The server can be in any of four states: - Non-authenticated - Authenticated - Selected - Logout sTwisted IMAP4rev1 Ready<iFNi>ORNOTUIDunauthrcT|i}||_||_|t}||_g|_yrt) challengersctxiterateInReactor _scheduler _queuedAsync)r]chalcontextFactory schedulers rCr`zIMAP4Server.__init__s5 <D!  (I#rEcdt|jji}|jrB|jr6|j s*t j|jd d|d<d|d<d|d<d|d<|S)NAUTH LOGINDISABLEDSTARTTLSrsIDLE) rYrkeysr canStartTLS startedTLSr ISSLTransportr)r]caps rC capabilitieszIMAP4Server.capabilitiesszT--22456 88((OO,,T^^TBJ(,$%#'K  LG  rEci|_tj|jddu|_|j |j |jyrt)tagsr ITLSTransportrr$ setTimeouttimeOutsendServerGreetingrbs rCconnectionMadezIMAP4Server.connectionMadesD %33DNNDIQUU  % !rEcn|jd|jr|jd|_yyrt)r, _onLogout)r]reasons rCconnectionLostzIMAP4Server.connectionLosts+  >> NN !DN rEcX|jd|jj|jrl|jj |t |jd}|2t |jjtjd|_d|_ y)Ns** BYE Autologout; connection idle too longtimeout) sendLinerloseConnectionmboxremoveListenerICloseableMailboxrclose addErrbackr5errstate)r]cmbxs rCtimeoutConnectionzIMAP4Server.timeoutConnectionsw CD %%' 99 II $ $T *$TYY5Ddjj)44SWW=DI rEc|j|jj|}||j|yyrt) resetTimeout_pendingLiteralr setLineModers rCrawDataReceivedzIMAP4Server.rawDataReceiveds= %%++D1     V $ rEc|j}d|_|r;|j/|j|jd|r |j/|j|jj|yyr)blocked lineReceivedpoprz)r]commandss rC_unblockzIMAP4Server._unblocksc<< 4<</   hll1o .4<</ << # LL   ) $rEc X|j|jj|y|jt|d|jz} ||y#t $rD}|j dtt|ztjYd}~yd}~wwxYw)Nparse_sBAD Server error: ) rGrrrBgetattr parseState ExceptionsendUntaggedResponser;rr5r=)r]rfes rCrHzIMAP4Server.lineReceiveds << # LL   %   D(T__4 5  dG   % %&;mCPQF>S&S T GGII sA B)%:B$$B)c |jdd}d}t|dk(r|\}}}nMt|dk(r|\}}n9t|dk(r|d}|j|dy|jddy|j} |j |||S#t $r1}|j|dt t|zYd}~yd}~wt$r1}|j|dt t|zYd}~yd}~wt$r1}|j|d t t|zYd}~yd}~wwxYw) Nrr<rsMissing commands Null commandIllegal syntax: Illegal operation: Illegal mailbox name: ) splitrsendBadResponseupperdispatchCommandrr;rrsendNegativeResponser)r]rrrestrcmdrSs rC parse_commandzIMAP4Server.parse_commands6zz$" t9>!NCd Y!^HC Y!^q'C  &8 9   7iik ''S$7 7$ S  &9M#a&r:r[)r]r_s rCrdzIMAP4Server.lookupCommand s/tSXXtzz< 3L&MNPTUUrEc Rt|D]p\}}t|rO||dzd}t|||j|j|||||j |j |y|j|r|rtdt|z| ||d|iy||y)Nr<z Too many arguments for command: rf) rfcallabler addCallback_IMAP4Server__cbDispatchr<_IMAP4Server__ebDispatchrrrrepr) r]rhandlerrrhrrfrhargs rC __doCommandzIMAP4Server.__doCommand s * !FAs}%a!eg. c4.::%%sGT9c*T..4 C  ! '(JTRVZ(WX X ? d # # TNrEc\|\}}|j||j||||||yrt)rrre) r]resultrrgrrhrfrrr^s rC __cbDispatchzIMAP4Server.__cbDispatch s/ d C b$ 4=rEc :|jtr2|j|dtt |j zy|jt r2|j|dtt |j zy|jtr2|j|dtt |j zy|j|dtt |j ztj|y)NrVrWrXServer error: ) checkrrZr;rrgrr]rr5r=r]failurers rC __ebDispatchzIMAP4Server.__ebDispatch%s ==. /  (=W]]9K+LL ]]+ ,  % %+mC ++-.  NN #,T15 $$ 7$> ?  rEctj}d|_t|||_|j t d|z|j|S)Nr~zReady for %d octets of data)rrrOrrCrr;rrs rC _fileLiteralzIMAP4Server._fileLiteralGsQ NN #*43 $$ 7$> ?  rEc(|j|dS)a Parse an astring from line that represents a command's final argument. This special case exists to enable parsing empty string literals. @param line: A line that contains a string literal. @type line: L{bytes} @return: A 2-tuple containing the parsed argument and any trailing data, or a L{Deferred} that fires with that 2-tuple @rtype: L{tuple} of (L{bytes}, L{bytes}) or a L{Deferred} @see: https://twistedmatrix.com/trac/ticket/9207 T)final) arg_astringrs rCarg_finalastringzIMAP4Server.arg_finalastringQs D11rEc |j}|s tdd}d\}}|dddk(r |jdd\}}}|dd}nw|ddd k(r9|d dd k7r td  t |dd }|r|sy|j |}n6|jdd}t|dk(r|jd|\}}|xs||fS#t$r tdwxYw#t$rtd t |dd zwxYw)a Parse an astring from the line, return (arg, rest), possibly via a deferred (to handle literals) @param line: A line that contains a string literal. @type line: L{bytes} @param final: Is this the final argument? @type final L{bool} @return: A 2-tuple containing the parsed argument and any trailing data, or a L{Deferred} that fires with that 2-tuple @rtype: L{tuple} of (L{bytes}, L{bytes}) or a L{Deferred} Missing argumentNNNrr<"rzUnmatched quotes{r}}Malformed literalBad literal size: )rErErrE) striprrYreintrprrrr)r]rrrrrr^spamrs rCrzIMAP4Server.arg_astringcsE"zz|'(:; ;  T !9  @"&**T1"5c4ABx!AY$ BCyD +,?@@ U4":T!##D)A**T1%C3x1} 3ICS$K% @+,>?? @ U+,@4Qr CS,STT UsC &C! C!$Ds (?P[s]+)( (?P.*$)|$)c|s td|jj|}|r"|jd|jdfStd)z- Parse an atom from the line ratomr^zMalformed ATOM)ratomrematchgroup)r]rms rCarg_atomzIMAP4Server.arg_atomsQ'(:; ; KK  d # 776?AGGFO3 3'(89 9rEc|s td|dddk7r td|jd}|dk(r tdt|d|d ||d zdfS) zG Parse a (non-nested) parenthesised list from the line rNr<(zMissing parenthesis)r}Mismatched parenthesisrr)rfindr)r]rrhs rC arg_plistzIMAP4Server.arg_plistso'(:; ; 8t '(=> > IIdO 7'(@A A!$q)Q/a!eg??rEc|s td|dddk7r td|dddk7r td t|dd}|j|S#t$rtd |ddwxYw) z/ Parse a literal from the line rNr<rzMissing literalr}rrr)rrrer)r]rrs rC arg_literalzIMAP4Server.arg_literals'(:; ; 8t '(9: : 9 '(;< < MtAbz?D  && M'*>$' '$< rEc|jdr |jdd\}}}||ddfSd|fS#t$r tdwxYw)z+ Optional date-time string rrzMalformed date-timer<N)rrYrer)r]rrdater^s rC opt_datetimezIMAP4Server.opt_datetimesi ??4  C#'::dA#6 dD$qr(# #$<   C+,ABB Cs 4A c|ddjdk(rT|jdd}t|dk(r tdt|dk(r|j d|\}}}||fSd|fS) z4 Optional charset of SEARCH command NsCHARSETrrr<zMissing charset identifierrE)r[rYrrrr)r]rrrrr^s rC opt_charsetzIMAP4Server.opt_charsetsu 8>> z )**T1%C3x1}+,HII3x1} 3!OD#t; $< rEcddj|jzdz|jz}|j|y)Ns [CAPABILITY r] )message)rlistCapabilitiesIDENTsendPositiveResponser]msgs rCr.zIMAP4Server.sendServerGreeting*s= $*?*?*A BBUJTZZW !!#!.rEc*|jd||y)NBAD_respondr]rrs rCrZzIMAP4Server.sendBadResponse.s fc7+rEc*|jd||y)Nrrrs rCrz IMAP4Server.sendPositiveResponse1 eS'*rEc*|jd||y)NNOrrs rCr]z IMAP4Server.sendNegativeResponse4rrEc t|fi|}|r |j|j|ddy|jj |yrt)r7rGrrrr)r]risAsynckwargss rCrQz IMAP4Server.sendUntaggedResponse7sA"75f54<</ MM'4 .    $ $W -rEcT|r|jd|zy|jdy)Ns+ +r6rs rCrz#IMAP4Server.sendContinuationRequest>s!  MM%#+ & MM$ rEc|dvr9|jr-|j}g|_|D]}|j|dd|sd}|r$|jdj|||fy|jdj||fy)N)rrr*r)rrr6r)r]r>rrrrs rCrzIMAP4Server._respondDs * *t/@/@%%E "D  / c4. /C  MM$))S%$9: ; MM$))S%L1 2rEcdg}|jjD]J\}}||j|t|s&|j |Dcgc] }|dz|z c}L|Scc}w)Ns IMAP4rev1=)r(itemsrrrrz)r]capscvr's rCrzIMAP4Server.listCapabilitiesQsp~%%'--/ =DAqy AQ ;#a$hn;<  =  ?rEc~|jd|j|d|jjy)NsBYE Nice talking to yousLOGOUT successful)rQrrr7rs rC do_LOGOUTzIMAP4Server.do_LOGOUTcs2 !!"<= !!#';< %%'rEc(|j|dy)NsNOOP No operation performedrrs rCdo_NOOPzIMAP4Server.do_NOOPms !!#'EFrEc|jj}||jvr|j|dy|j |j||y)NsAUTHENTICATE method unsupported)r[rrr] authenticate)r]rrs rCdo_AUTHENTICATEzIMAP4Server.do_AUTHENTICATEusVzz|!!# t'' '  % %c+M N   4d..t46 >#3D  ( ( /  , ,T-?-?s K  + +D,>,> D Q  &7-A:O&O P P QsB C('CCc^ t|}|j ||j r|j ||y|jj|dtj|j|j|fd|fdy#tj$r tdwxYw)NzMalformed Response - not base64) rbinasciiErrorr setResponsemoreChallengesrrloginIAccount addCallbacks_IMAP4Server__cbAuthResp_IMAP4Server__ebAuthResp)r]rurruncodeds rC __cbAuthChunkzIMAP4Server.__cbAuthChunks K!&)G !     s + KK  dD( 3 @ @!!4#4#4sfdSFD ~~ K'(IJ J Ks B B,c|\}}}|tusJd||_d|_||_|j |d|j |j y)Nz(IAccount is the only supported interfaceauthsAuthentication successful)raccountr>r1rr,POSTAUTH_TIMEOUTr]rurifaceavatarlogouts rC __cbAuthRespzIMAP4Server.__cbAuthRespsZ"( L"LL    !!#'CD --.rEc|jtr|j|dy|jtr|j|dy|j |dt j |y)Ns#Authentication failed: unauthorizeds+Authentication failed: server misconfigureds'Server error: login failed unexpectedly)ryr r]r rZr5r=rzs rC __ebAuthRespzIMAP4Server.__ebAuthResps` ==* +  % %c+Q R ]]/ 0  % %C   &P Q GGG rEc f|j|dtt|jzy)NsAuthentication failed: )r]r;rrgrzs rC __ebAuthChunkzIMAP4Server.__ebAuthChunks) !! +mC r,rrs rC __cbLoginzIMAP4Server.__cbLoginsv"(   &V W GG,UI5HI J!DL#DN  % %c+= >DJ OOD11 2rEc |jtr|j|dy|j|dt t |j ztj|y)Ns LOGIN failedrx) ryr r]rZr;rrgr5r=rzs rC __ebLoginzIMAP4Server.__ebLoginsT ==* +  % %c? ;  &s7==7I)JJ  GGG rEcdx}x}}t|jd}|0|j}|j}|j}|j dt |||gz|j |dy)Ns NAMESPACE sNAMESPACE command completed)r1rgetPersonalNamespacesgetSharedNamespacesrQcollapseNestedListsr)r]rpersonalpublicsharednps rC do_NAMESPACEzIMAP4Server.do_NAMESPACEs%)))6F t 4 >//1H++-F++-F !! /660JK K  !!#'EFrEc|jrs|jj|t|jd}|2t|jj t jd|_d|_t|}t|jjt||j|j||j |j||y)Nr)r8r9r:rr;r<r5r=r> _parseMboxrselectrm _cbSelectWork _ebSelectWork)r]rnamerwcmdNamer?s rC _selectWorkzIMAP4Server._selectWorks 99 II $ $T *$TYY5Ddjj)44SWW=DIDJ$dll)):d+;R@LL    *T''# 6rEcX|j||dztj|y)Ns failed: Server errorrZr5r=)r]r{r,rs rCr)zIMAP4Server._ebSelectWorks$ S',D"DE rEc||j|dyd|jDcgc]}|jc}vr|j|dy|jDcgc] }t|}}|j d|j fz|j d|j fz|j ddj|zdz|jdd |jfz|jxrd xsd }|j||j|d |zd z|zdzd|_ ||_ ycc}wcc}w)NsNo such mailboxz \noselectzMailbox cannot be selected %d EXISTS %d RECENTFLAGS (rrs[UIDVALIDITY %d]rr[rs successfulr')r]getFlagslowerr;rQgetMessageCountgetRecentCountrrgetUIDValidity isWriteable addListenerr>r8)r]r8r,rrflagrs rCr(zIMAP4Server._cbSelectWork sP <  % %c+= >  t}}?!AGGI? ?  % %c+G H 15At$AA !!,$2F2F2H1J"JK !!,$2E2E2G1I"IJ !!*tyy/?"?$"FG !!$(;t?R?R?T>V(VW     0= @L  !!#tax%'7''AN'RS  @Bs E#)E(r<SELECTrEXAMINEcd|jd||_|j|_d|_y)Nidle)rparseTagrO lastStaters rCdo_IDLEzIMAP4Server.do_IDLE:s) $$T*  rEcf|j|_|`|j|jd|`y)NsIDLE terminated)rBrOrrA)r]rs rC parse_idlezIMAP4Server.parse_idle@s,.. N !!$--1CD MrEc tt|} |jj|}|r|j|dy|j |dy#t $r.}|j |t t|Yd}~yd}~wt$r)|j|dtjYywxYw)NsMailbox createdsMailbox not createds/Server error encountered while creating mailbox) r&rcreaterr]rr;r BaseExceptionrZr5r=)r]rr*rurs rC do_CREATEzIMAP4Server.do_CREATEIs$ G\\((.F))#/AB))#/EF  B  % %c=Q+@ A A   G  GGI  sA B7$B2B76B7ct|}|jdk(r|j|dy |jj ||j |dy#t $r4}|j|t|jdYd}~yd}~wt$r)|j|dtjYywxYw)NinboxsYou cannot delete the inboxsMailbox deleted imap4-utf-7s/Server error encountered while deleting mailbox) r&r6r]rdeleterrrencoderHrZr5r=r]rr*rs rC do_DELETEzIMAP4Server.do_DELETE]s$ ::<7 "  % %c+I J  ? LL   %  % %c+= >  I  % %c3q6==+G H H   G  GGI  sA!! C**B2C Cc d||fD\}}|jdk(s|jdk(r|j|dy |jj|||j |dy#t $r|j |dYyt$r.}|j|tt|Yd}~yd}~wt$r)|j |dtjYywxYw)Nc32K|]}t|ywrt)r&)r ns rCrz(IMAP4Server.do_RENAME..rsFaJqMFrKs@You cannot rename the inbox, or rename another mailbox to inbox.sMailbox renamedsInvalid command syntaxs/Server error encountered while renaming mailbox) r6r]rrenamerrurZrr;rrHr5r=)r]roldnamenewnamers rC do_RENAMEzIMAP4Server.do_RENAMEqsFGW3EF ==?g %G)C  % %X   ? LL   1  % %c+= > A  &? @ B  % %c=Q+@ A A   G  GGI  s$ A88C;C;$C2C;:C;c Jt|} |jj||j|dy#t$r.}|j |t t|Yd}~yd}~wt$r)|j|dtjYywxYw)Ns Subscribeds5Server error encountered while subscribing to mailbox) r&r subscriberrr]r;rrHrZr5r=rOs rC do_SUBSCRIBEzIMAP4Server.do_SUBSCRIBEs$ : LL " "4 (  % %c= 9  B  % %c=Q+@ A A   M  GGI  ; B"$A--2B"!B"c Jt|} |jj||j|dy#t$r.}|j |t t|Yd}~yd}~wt$r)|j|dtjYywxYw)Ns Unsubscribeds9Server error encountered while unsubscribing from mailbox) r&r unsubscriberrr]r;rrHrZr5r=rOs rCdo_UNSUBSCRIBEzIMAP4Server.do_UNSUBSCRIBEs$ < LL $ $T *  % %c? ;  B  % %c=Q+@ A A   Q  GGI  r\ct|}t|}t|jj||j |j |||j |j|yrt)r&rr listMailboxesrm _cbListWorkr< _ebListWork)r]rrefr8subr,s rC _listWorkzIMAP4Server._listWorksW$odll00#t<HH   c3 *T%%s +rEc|D]\}}|r|jj|s$|jDcgc] }t|}}|j j d} t |tt || |j df} |jt| |j||dzycc}w)NrLs completed) r isSubscribedr5r;getHierarchicalDelimiterrN DontQuoteMemaprQrr) r] mailboxesrrer,r*boxr<rdelimresps rCrbzIMAP4Server._cbListWorks" EID#$,,33D99<Ht,HH446==mL( U+KK .  ))*=d*CD E !!#w'>?IsC cR|j|dtj|y)Ns1Server error encountered while listing mailboxes.r/rzs rCrczIMAP4Server._ebListWorks S"VW rErrcg}|D]}|jt|t|}t|jj |dj |j|||j|j|yr) rrr:r&rrr'rm_cbStatusGotMailboxr<_ebStatusGotMailbox)r]rmailboxr nativeNamesr*s rC do_STATUSzIMAP4Server.do_STATUSsw  3D   |D1 2 3W%dll))7A6BB  $ $c7K *T--s 3rEc|rCt|j|j|j|j||fd||fdy|j |dy)NsCould not open mailbox)r requestStatusr_IMAP4Server__cbStatus_IMAP4Server__ebStatusr])r]r8rrtrs rCrrzIMAP4Server._cbStatusGotMailboxsU  $,,e 4 A Agg    % %c+D ErEcR|j|dtj|yNs/Server error encountered while opening mailbox.r/rzs rCrszIMAP4Server._ebStatusGotMailbox S"TU rEc tdj|jDcgc]}d|z c}}|jd|j dzdz|zdz|j |dycc}w)N z%s %sSTATUS rL (rsSTATUS complete)r;rrrQrNr)r]statusrrmrSrs rC __cbStatuszIMAP4Server.__cbStatussqSXXFLLN&Kqw{&KLM !! M2 2U :T AD H  !!#'9: 'Ls A9 c r|j|d|zdztt|jzy)Nrs failed: rZr;rrg)r]r{rrms rC __ebStatuszIMAP4Server.__ebStatuss2  c!L0=W]]AS3TT rEct|}t|jj|j |j ||||j |j|yrt)r&rrr'rm_cbAppendGotMailboxr<_ebAppendGotMailbox)r]rrtrrrs rC do_APPENDzIMAP4Server.do_APPENDsNW%dll))73??  $ $c5$ *T--s 3rEc|s|j|dy|Dcgc] }t|}}|j|||}|j|j|||j |j |ycc}w)NzRYCREATE] No such mailbox)r]r: addMessagerm_IMAP4Server__cbAppendr<_IMAP4Server__ebAppend) r]r8rrrrr< decodedFlagsrs rCrzIMAP4Server._cbAppendGotMailboxsn  % %c+H I 7<=t T*= = OOG\4 8 doosD1 T__c*>sA;cR|j|dtj|yr|r/rzs rCrzIMAP4Server._ebAppendGotMailboxr}rEcn|jd|jfz|j|dy)Nr1sAPPEND complete)rQr7r)r]rurr8s rC __cbAppendzIMAP4Server.__cbAppend s2 !!,$2F2F2H1J"JK !!#'9:rEc f|j|dtt|jzy)NsAPPEND failed: rrzs rC __ebAppendzIMAP4Server.__ebAppends)  #mC 4F&GG rEc|j}||jd|y|j|j|j|f|fy)N) callbackArgs errbackArgs) checkpoint_IMAP4Server__cbCheckr_IMAP4Server__ebCheck)r]rrs rCdo_CHECKzIMAP4Server.do_CHECKsI OO  9 NN4 % NNcVRUQW  rEc(|j|dy)NsCHECK completedrr]rurs rC __cbCheckzIMAP4Server.__cbCheck!s !!#'9:rEc f|j|dtt|jzy)NsCHECK failed: rrzs rC __ebCheckzIMAP4Server.__ebCheck$& S"3mC DV6W"WXrEcy)ah Called when the client issues a CHECK command. This should perform any checkpoint operations required by the server. It may be a long running operation, but may not block. If it returns a deferred, the client will only be informed of success (or failure) when the deferred's callback (or errback) is invoked. Nr?rbs rCrzIMAP4Server.checkpoint'srEcd}|jjrt|jj}t |jd,||j fdntj }|-|j|j|j|fd|fdy|jd|y)Nc$jSrt)r;)rur?s rCrTz&IMAP4Server.do_CLOSE..9s TZZ\rE) r8r:rexpunger:rmr;r_IMAP4Server__cbClose_IMAP4Server__ebClose)r]rrr?s @rCdo_CLOSEzIMAP4Server.do_CLOSE2s  99 "dii//0A D1  } 9:!$**- = NN4>>4>>C64#QU V NN4 %rEcz|j|d|jj|d|_d|_y)NsCLOSE completedr)rr8r9r>rs rC __cbClosezIMAP4Server.__cbCloseCs3 !!#'9:   &  rEc f|j|dtt|jzy)NsCLOSE failed: rrzs rC __ebClosezIMAP4Server.__ebCloseIrrEc|jjrJt|jjj |j |j |fd|fdy|j|dy)Ns$EXPUNGE ignored on read-only mailbox)r8r:rrr_IMAP4Server__cbExpunge_IMAP4Server__ebExpunger]rs rC do_EXPUNGEzIMAP4Server.do_EXPUNGELs_ 99 " $))++ , 9 9  $"2"2SFD3&$   % %c+R SrEc`|D]}|jd|fz|j|dy)Ns %d EXPUNGEsEXPUNGE completed)rQr)r]rurrSs rC __cbExpungezIMAP4Server.__cbExpungeVs7 "))U 4 @ @dii j#.F#A $))//1# 6 B B%%sDIIuc j#.rEc |rt|j|}tdj|Dcgc] }t |c}}|j d|z|j |dycc}w)NrSEARCH SEARCH completed)rkgetUIDr;rrrQr)r]rurr8rfrhidss rC __cbSearchzIMAP4Server.__cbSearchqs` f-FCHHf%=c!f%=>? !!*s"23 !!#':;&>sA1 c 0|g}d}|xr|dd}|xr|ddj} tttd|D]X\}\} } |j t j || | || s2|jd|r| jn| fzZ|dk(r5ddlm } | jd|jt|dd|||||y|r#|jd d j|z|j|d y) aL Apply the search filter to a set of messages. Send the response to the client. @type result: L{list} of L{tuple} of (L{int}, provider of L{imap4.IMessage}) @param result: A list two tuples of messages with their sequence ids, sorted by the ids in descending order. @type tag: L{str} @param tag: A command tag. @type mbox: Provider of L{imap4.IMailbox} @param mbox: The searched mailbox. @type query: L{list} @param query: A list representing the parsed form of the search query. @param uid: A flag indicating whether the search is over message sequence numbers or UIDs. @type searchResults: L{list} @param searchResults: The search results so far or L{None} if no results yet. Nrr}r<s%dreactorrrr)rrYziprange _searchFilterr deepcopyrrtwisted.internetr callLaterrrQrr) r]rurr8rrf searchResultsrhlastSequenceId lastMessageIdmsgIdrrs rC__cbManualSearchzIMAP4Server.__cbManualSearchxs'4  M  1F2JqM96":a=#7#7#9 #Ca&$9: POA|s!! e$eS.-$$Uccjjlu-N%NO P 6 0   %%VABZ  ))*tyy7O*OP  % %c+> ?rEc:|r|j|||||sy|ry)a Pop search terms from the beginning of C{query} until there are none left and apply them to the given message. @param query: A list representing the parsed form of the search query. @param id: The sequence number of the message being checked. @param msg: The message being checked. @type lastSequenceId: L{int} @param lastSequenceId: The highest sequence number of any message in the mailbox being searched. @type lastMessageId: L{int} @param lastMessageId: The highest UID of any message in the mailbox being searched. @return: Boolean indicating whether all of the query terms match the message. FT_singleSearchStep)r]ridrrrs rCrzIMAP4Server._searchFilters/,))r3   rEc|jd}t|tr|j|||||syy|j }|ddj st ||}||vSt|dt|zd} | tdt|z||jvr| |||||f} n | |||} | syy)a Pop one search term from the beginning of C{query} (possibly more than one element) and return whether it matches the given message. @param query: A list representing the parsed form of the search query. @param msgId: The sequence number of the message being checked. @param msg: The message being checked. @param lastSequenceId: The highest sequence number of any message in the mailbox being searched. @param lastMessageId: The highest UID of any message in the mailbox being searched. @return: Boolean indicating whether the query term matched the message. rFNr<search_zInvalid search command %sT) rIrXrYrr[isalpharrNr:r_requiresLastMessageInfo) r]rrrrrqr messageSetrRrus rCrzIMAP4Server._singleSearchSteps( IIaL a %%a^]S.+ ARa5==?)N;  **D)l1o"=tD9+3l1oE555ueS>=2QRFueS1F rEcy)aS Returns C{True} if the message matches the ALL search key (always). @type query: A L{list} of L{str} @param query: A list representing the parsed query string. @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} Tr?r]rrrs rC search_ALLzIMAP4Server.search_ALLsrEc&d|jvS)aA Returns C{True} if the message has been answered. @type query: A L{list} of L{str} @param query: A list representing the parsed query string. @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} \Answeredr5rs rCsearch_ANSWEREDzIMAP4Server.search_ANSWEREDss||~--rEc|jddjdd}|jj|j djdk7S)aR Returns C{True} if the message has a BCC address matching the query. @type query: A L{list} of L{str} @param query: A list whose first element is a BCC L{str} @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} Fbccrr} getHeadersgetr6rrI)r]rrrrs rC search_BCCzIMAP4Server.search_BCCsNnnUE*..ub9yy{ ! 2 2 45;;rEct|jd}tjj t |j |kSr) parseTimerIemailutils parsedater:getInternalDater]rrrrs rC search_BEFOREzIMAP4Server.search_BEFORE,s<1&{{$$\#2E2E2G%HIDPPrEc|jdj}tj||j dSNrFrIr6r6strFile getBodyFiler]rrrbodys rC search_BODYzIMAP4Server.search_BODY0s2yy|!!#||D#//"3U;;rEc|jddjdd}|jj|j djdk7S)NFccrrr}r)r]rrrrs rC search_CCzIMAP4Server.search_CC4J ^^E4 ( , ,T2 6xxzuyy|1134::rEc&d|jvSNz\Deletedrrs rCsearch_DELETEDzIMAP4Server.search_DELETED8clln,,rEc&d|jvSNz\Draftrrs rC search_DRAFTzIMAP4Server.search_DRAFT;sCLLN**rEc&d|jvSNz\Flaggedrrs rCsearch_FLAGGEDzIMAP4Server.search_FLAGGED>rrEc|jddjdd}|jj|j djdk7S)NFfromrrr}r)r]rrrfms rC search_FROMzIMAP4Server.search_FROMAsJ ^^E6 * . .vr :xxzuyy|1134::rEc|jdj}|jd|j|d}|jj |jdjdk7S)NrFrr})rIr6rrr)r]rrrhdrs rC search_HEADERzIMAP4Server.search_HEADEREsbiil  "nnUC(,,S"5yy{ ! 2 2 45;;rEc&|jdyrrIrs rCsearch_KEYWORDzIMAP4Server.search_KEYWORDJ ! rEcXt|jd|jkSrrrIgetSizers rC search_LARGERzIMAP4Server.search_LARGERN 599Q< 3;;=00rEcNd|jvxrd|jvS)N\Recent\Seenrrs rC search_NEWzIMAP4Server.search_NEWQs#S\\^+N 0NNrEc8|\}}|j||||| S)a Returns C{True} if the message does not match the query. @type query: A L{list} of L{str} @param query: A list representing the parsed form of the search query. @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} @param msg: The message being checked. @type lastIDs: L{tuple} @param lastIDs: A tuple of (last sequence id, last message id). The I{last sequence id} is an L{int} containing the highest sequence number of a message in the mailbox. The I{last message id} is an L{int} containing the highest UID of a message in the mailbox. r)r]rrrlastIDsrrs rC search_NOTzIMAP4Server.search_NOTTs*&+2'))%S.-XXXrEc&d|jvSNrrrs rC search_OLDzIMAP4Server.search_OLDjs//rEct|jd}tjj |j |k(SrrrIrrrrrs rC search_ONzIMAP4Server.search_ONms71&{{$$S%8%8%:;tCCrEcl|\}}|j|||||}|j|||||}|xs|S)a Returns C{True} if the message matches any of the first two query items. @type query: A L{list} of L{str} @param query: A list representing the parsed form of the search query. @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} @param msg: The message being checked. @type lastIDs: L{tuple} @param lastIDs: A tuple of (last sequence id, last message id). The I{last sequence id} is an L{int} containing the highest sequence number of a message in the mailbox. The I{last message id} is an L{int} containing the highest UID of a message in the mailbox. r) r]rrrr!rrabs rC search_ORzIMAP4Server.search_ORqsG(+2'  " "5"c>= Q  " "5"c>= QvA rEc&d|jvSr$rrs rC search_RECENTzIMAP4Server.search_RECENTsS\\^++rEc&d|jvSNrrrs rC search_SEENzIMAP4Server.search_SEENs3<<>))rEc|jddjdd}tjj |}|t |j dkS)a Returns C{True} if the message date is earlier than the query date. @type query: A L{list} of L{str} @param query: A list whose first element starts with a stringified date that is a fragment of an L{imap4.Query()}. The date must be in the format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'. @type id: L{int} @param id: The sequence number of the message being checked. @type msg: Provider of L{imap4.IMessage} FrrrrrrrrrrIrs rCsearch_SENTBEFOREzIMAP4Server.search_SENTBEFOREsM~~eV,00<{{$$T*i ! ---rEc|jddjdd}tjj |}|ddt |j dddk(S)a Returns C{True} if the message date is the same as the query date. @type query: A L{list} of L{str} @param query: A list whose first element starts with a stringified date that is a fragment of an L{imap4.Query()}. The date must be in the format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'. @type msg: Provider of L{imap4.IMessage} FrrNrUrr3rs rC search_SENTONzIMAP4Server.search_SENTONsZ~~eV,00<{{$$T*BQx9UYYq\22A666rEc|jddjdd}tjj |}|t |j dkDS)a Returns C{True} if the message date is later than the query date. @type query: A L{list} of L{str} @param query: A list whose first element starts with a stringified date that is a fragment of an L{imap4.Query()}. The date must be in the format 'DD-Mon-YYYY', for example '03-March-2003' or '03-Mar-2003'. @type msg: Provider of L{imap4.IMessage} Frrrr3rs rCsearch_SENTSINCEzIMAP4Server.search_SENTSINCEsM~~eV,00<{{$$T*i ! ---rEct|jd}tjj |j |kDSrr'rs rC search_SINCEzIMAP4Server.search_SINCEs71&{{$$S%8%8%:;dBBrEcXt|jd|jkDSrrrs rCsearch_SMALLERzIMAP4Server.search_SMALLERrrEc|jddjdd}|jj|j djdk7S)NFsubjectrrr}r)r]rrrsubjs rCsearch_SUBJECTzIMAP4Server.search_SUBJECTsL~~eY/33IrBzz|  1!3!3!56"<11rEc&d|jvSrrrs rCsearch_UNDELETEDzIMAP4Server.search_UNDELETED#,,.00rEc&d|jvSrrrs rCsearch_UNDRAFTzIMAP4Server.search_UNDRAFTs ..rEc&d|jvSr rrs rCsearch_UNFLAGGEDzIMAP4Server.search_UNFLAGGEDrLrEc&|jdyrrrs rCsearch_UNKEYWORDzIMAP4Server.search_UNKEYWORDrrEc&d|jvSr0rrs rC search_UNSEENzIMAP4Server.search_UNSEENss||~--rEc |j|dtt|jzt j |y)NsSEARCH failed: rrzs rC __ebSearchzIMAP4Server.__ebSearchs7  #mC 4F&GG  rEc0|r|jd|_t|jj||j t j |j|||j|j|y|j|dy)NrsFETCH complete) r, _oldTimeoutrr8rrmiter_IMAP4Server__cbFetchr<_IMAP4Server__ebFetchr)r]rmessagesrrfs rCdo_FETCHzIMAP4Server.do_FETCHsq #t4D  $))//8 = I I k$..#uc:::<  % %c+< =rEctjg_ t\}}j||jfdj j y#t $rBjj`jdjYywxYw)Nc,jSrt)rZ)rjrresultsr]rrfs rCrTz'IMAP4Server.__cbFetch..4s$..#ucBrEsFETCH completed) rGnext spewMessagermr<_IMAP4Server__ebSpewMessage StopIterationr,rXrrK)r]r`rrrfrrs````` rC __cbFetchzIMAP4Server.__cbFetchs << DL /7mGB4   ReS 1 = =B j--.7  OOD,, -   % %c+= > MMO/ sA,,AB76B7cbtj||jjyrt)r5r=rr7r]r{s rC__ebSpewMessagezIMAP4Server.__ebSpewMessage7s  %%'rEcp||jj}|dtt|gzy)Ns ENVELOPE )rrr getEnveloper]rr_w_fs rC spew_envelopezIMAP4Server.spew_envelope?s1 :%%B <-{3/?.@A ABrEc||jj}|jDcgc] }t|}}|ddj |zdzycc}w)Nr3rr)rwritenr5r;r)r]rrrlrmr< encodedFlagss rC spew_flagszIMAP4Server.spew_flagsDsV :&&B8; G d+G G dii 5 5 <=HsAc||jj}|j}tjj t |}|&tjd|||fztdtjd|dd}t|t|dfz}|d|dz}n@|ddk\rd} nd } || zd t|dd zd zt|dd zd zzfzz}|dt|zy)Nz$%d:%r: unpareseable internaldate: %rz(Internal failure generating INTERNALDATEz%d-%%s-%Y %H:%M:%S r<s+0000rr-s%04didrs INTERNALDATE )rrrrr parsedate_tzr:r5rrtimestrftimer; _MONTH_NAMESabs_quote) r]rrrlrmidatettupstrdateodatesigns rCspew_internaldatezIMAP4Server.spew_internaldateJs% :%%B##%{{'' U(;< < GG:b#u=MM N !KL L-- 5tBQx@gd1g)>(@@A 7?H$EAw!|QLD(C/3tAw<$3F22MMOPP  fUm +,rEc||jj}t|jd}|dt |zy)NTsRFC822.HEADER )rr_formatHeadersr_literal)r]rrrlrmhdrss rCspew_rfc822headerzIMAP4Server.spew_rfc822headeres; :%%BcnnT23 x~ -.rEc||jj}|d|t|jj |jS)Ns RFC822.TEXT )rr FileProducerrbeginProducingrks rCspew_rfc822textzIMAP4Server.spew_rfc822textksD :%%B ? COO-.==dnnMMrEch||jj}|d|jfzy)NsRFC822.SIZE %d)rrrrks rCspew_rfc822sizezIMAP4Server.spew_rfc822sizers- :%%B  / /0rEc0||jj}|d|t|d}|2t|j j |jSt |d|jj |jS)NsRFC822 )rr IMessageFileropenrMessageProducerr)r]rrrlrmmfs rC spew_rfc822zIMAP4Server.spew_rfc822wsz :%%B :  #t $ > *99$..I IsD$//:II NN  rEch||jj}|d|jfzy)NsUID %d)rrrrks rCspew_uidzIMAP4Server.spew_uids+ :%%B 9  &'rEc B|dtt|dgzy)NsBODYSTRUCTURE T)rgetBodyStructurerks rCspew_bodystructurezIMAP4Server.spew_bodystructures! 24DS$4O3PQ QRrEc||jj}|jD]4}|jr|j |}%|dkDs+t d|j rl|j|j jg|j j}t|}||jdzt|zy|jrR||jdz|t|jj!|jS|j"r@t|jd}||jdzt|zy|j$r||jdz||jr2t|jj!|jSt'|d}|2t|j)j!|jSt+|d|j,j!|jS|dt/t1|gzy)Nrz*Requested subpart of non-multipart messagerTsBODY )rrpart isMultipart getSubPartruheaderrnegatefieldsr __bytes__rr6rrrmimeemptyrrrrrr) r]rrrrlrmrrrs rC spew_bodyzIMAP4Server.spew_bodys :%%B NA nnQ'Q LMM  N ;;!3>>$++"4"4Jt{{7I7IJD!$'D t~~$&$7 8 YY t~~$& ' D 12AA$..Q Q YY!#.."67D t~~$&$7 8 ZZ t~~$& ' Dyy#COO$56EEdnnUU!#t,>' 2AA$..QQ&sD$//BQQNN x-/?/D.EFF GrEc  tj}|j |j fd fd fd   f d}j |S)Ncdfzy)Ns * %d FETCH (r?)rrsrCr^z&IMAP4Server.spewMessage..starts /RE) *rEcdy)Ns) r?rsrCrz'IMAP4Server.spewMessage..finishs (OrEcdyrr?rsrCspacez&IMAP4Server.spewMessage..spaces $KrEc3f Kd} D]o}|jdk(rd}|jdk(rj| n&td|jz}| |dusi q r|s j yw)NFrfTrspew_r})typerrNr) seenUIDrrRrrrrrr]rr^rfrs rCspewz%IMAP4Server.spewMessage..spewsG G 99%"G99&..r3uEEg &9:ABUE22uRy(G 7mmBUE:: H Gs A4B189B1)rrrrr) r]rrrrfwbufrrrrr^rs ````` @@@@@rCrbzIMAP4Server.spewMessagesP4>>*   +    &tv&&rEc |j|j|`tj||j |dt t |jzy)NsFETCH failed: )r,rXr5r=rZr;rrgrzs rC __ebFetchzIMAP4Server.__ebFetchsJ (()    S"3mC DV6W"WXrEc|j}|jd}|jdrd}n|jdrd}nd}|Dcgc] }t|}}t |j j ||||j|j|j||j ||fd|fdycc}w)NsSILENTrr<rur}rr) r[endswithrr:rr8storer_IMAP4Server__cbStore_IMAP4Server__ebStore)r]rr\moderrfsilentr<s rCdo_STOREzIMAP4Server.do_STOREszz|y) ??4 D __T "DD056d#66diioox#FSS NN NN $))S& )  F   7sCc|rr|sp|jD]]\}}|rd|j|fz}nd}|D cgc] } t| } } |jd|dj | |fz_|j |dycc} w)Ns UID %drEs%d FETCH (FLAGS (%b)%b)rsSTORE completed)rrr;rQrr) r]rurr8rfrkruidstrr<rs rC __cbStorezIMAP4Server.__cbStores &  1'4;;q>*;;F F9:;t,;;)).!TYYu5Ev1NN  !!#'9: +H I $))//8S 9 E E sD k$//35jjPS6TrEc f|j|dtt|jzyrrrzs rCrz"IMAP4Server._ebCopySelectedMailbox rrEc,g}td}|D]\}}|(t|j|}|j|0|j } |j } t |d} | )| j} tj| | | }nTdtj} t|| |jjdj| | | ffd }|j|tj |S)Nc(|jd|Sr)rrRs rCrewindz$IMAP4Server.__cbCopy..rewind+ sFF1IHrEc6j|||Srt)r)rjr+rRrr8rs rCrTz&IMAP4Server.__cbCopy..4 sT__"1Iq!>rE)IMessageCopierrr rrr5rrrrrrrrrrmr DeferredList)r]r\rr8addedDeferreds fastCopyMboxrrrrrrbodyFilebufferrs ` @rC__cbCopyzIMAP4Server.__cbCopy s %dD1  %GB'!,"3"3S9%%a( LLNE&&(DT*D99;!$//8UDI"//1#CA#^D) [$*et  ! !! $A %B!!.11rEcg}g}|D]4\}}|r|j||j|j6|r|j|dy|j|dy)Nz%[ALERT] Some messages were not copiedsCOPY completed)rrrgr]r)r] deferredIdsrr8rfailuresrrus rC __cbCopiedzIMAP4Server.__cbCopied< se) .NFF 6" -  .   % %c+R S  % %c+< =rEc |j|dtt|jzt j |y)Ns COPY failed:rrzs rC__ebCopyzIMAP4Server.__ebCopyI s1 S/M#gmmBT4U"UV rEcl|j}|dvr t||j|||dy)N)COPYrSTORErr<r)r[rr\)r]rrrs rCdo_UIDzIMAP4Server.do_UIDM s8--/ B B'0 0 S'4Q7rEcV|r|jddy|jddy)Ns [READ-WRITE]T)rrs [READ-ONLY]rQr] writeables rC modeChangedzIMAP4Server.modeChangedZ s+   % %ot % L  % %nd % KrEc|jD]F\}}|Dcgc] }t|}}d|dj|fz}|j|dHycc}w)Ns%d FETCH (FLAGS (%b))rTr)rr;rrQ)r]newFlagsmIdrr<rqrs rC flagsChangedzIMAP4Server.flagsChanged` sb"..* 9JC % M    % %lfY&> % M rENNNrtFNrE)s!Ready for additional command textrr)rrrrrr-rr%r$r*rrr1r8rCrrrr>rOr`r(r/r3r@rErGrKrHr`rbr\rdrernrorrrrrecompileescape _atomCharsrrrrrrrrrrrrr.rZrr]rQrrrrunauth_CAPABILITYauth_CAPABILITYselect_CAPABILITYlogout_CAPABILITYr unauth_LOGOUT auth_LOGOUT select_LOGOUT logout_LOGOUTr unauth_NOOP auth_NOOP select_NOOP logout_NOOPrunauth_AUTHENTICATErrrrrrrunauth_STARTTLSr unauth_LOGINrrrr$auth_NAMESPACEselect_NAMESPACEr-r)r( auth_SELECT select_SELECT auth_EXAMINEselect_EXAMINErCrE select_IDLE auth_IDLErI auth_CREATE select_CREATErP auth_DELETE select_DELETErX auth_RENAME select_RENAMEr[auth_SUBSCRIBEselect_SUBSCRIBEr_auth_UNSUBSCRIBEselect_UNSUBSCRIBErfrbrc auth_LIST select_LIST auth_LSUB select_LSUBrvrrrs auth_STATUS select_STATUSryrzrrr auth_APPEND select_APPENDrrr select_CHECKrrrr select_CLOSErrrselect_EXPUNGErrr select_SEARCHrrrrrrrrrrrrr rrrrrr"r%r(r,r.r1r4r6r8r:r<r@rBrErGrIrKrNrPrRrTrr] select_FETCHrZrcrnrrrrrrrrrrrbr[r select_STORErrr select_COPYrrrrrr select_UIDrrrr?rErCrrUs 'EGJK DFGI DOK 7 EJ " " %G* : >V(> & 2$, ^RZZ  *--0HHF :@"'( H0      /,++. 3@'('O))( LMK!M!MG*KIKK=+H5( E /  A#nO*k+;j,7L /D(C > -6/ N1  ( S$HL!'FY  (j(LAL ;Y7 J(89KUY&2P >8(H-J L 9 NrErceZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZeeedZdZdbd Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dcdZ$dZ%dZ&dZ'dZ(d Z)dbd!Z*d"Z+d#Z,d$Z-d%Z.d&Z/d'Z0d(Z1d)Z2d*Z3d+Z4d,Z5d-Z6d.Z7d/Z8d0Z9d1Z:d2Z;d3Zd6Z?d7Z@d8ZAd9ZBd:ZCd;Dcic]}||jd<c}}ZEd=ZFd>ZGddd?ZHd@ZIdAZJdBZKdCZLdDZMdEZNddFdGZOdHZPdedIZQdedJZRdedKZSdedLZTdedMZUdedNZVdedOZWdedPZXdedQZYdedRZZdedSZ[dedTZ\dedUZ]dVZ^dWZ_ dfdXZ`dedYZadgdZZbdgd[Zcdgd\Zdd]Zed^Zfd_Zgd`ZhdaZiycc}}w)h IMAP4ClientzIMAP4 client protocol implementation @ivar state: A string representing the state the connection is currently in. Nr<Frr)OKNOBADPREAUTHBYE)MESSAGESRECENTUNSEENcfi|_g|_i|_||_d|_d|_d|_yrt)r*queuedauthenticatorscontext_tag_parts_lastCmd)r]rs rCr`zIMAP4Client.__init__ s4   %    rEcZ||j|jj<y)a Register a new form of authentication When invoking the authenticate() method of IMAP4Client, the first matching authentication scheme found will be used. The ordering is that in which the server lists support authentication schemes. @type auth: Implementor of C{IClientAuthentication} @param auth: The object to use to perform the client side of this authentication scheme. N)r4getNamer[)r]rs rCregisterAuthenticatorz!IMAP4Client.registerAuthenticator s#7;DLLN0023rEcR|jdkDr|j|xjt|zc_|jdkDr|jj |yd}|jdkr|d|j||jd}}|jj ||j}d|_d|_|j dd|jj|j|j|jdy)NrrE ) r5rB _pendingSizer_pendingBufferrrr7rrreadrDlstrip)r]rrr^s rCrEzIMAP4Client.rawDataReceived s <r7rzr)r]r^octetss rC_setupForLiteralzIMAP4Client._setupForLiteral sR"..v6" ;; /DK KK  g / rEcZ|jdkDr|j|jyyr)r5r,rbs rCr/zIMAP4Client.connectionMade s# <HqLN+H  &6 #2/F;;&'+zz$':$DIu E%%eV4 ;;   ! !$ ' KK  t $ 388DKK#8C&* *DI  d +'"6/556s DD0c|jrS|jj=|jjdc}|j_|jt|jrG|jD]8}|j|jc}|_|jt:|j j yrt)r8rrH TIMEOUT_ERRORr3rr7)r]rr_s rCr@zIMAP4Client.timeoutConnection s ==T]]00<%)]]%8%8$ "At}}" IIm $ ;;{{ -99(#&99aLAsyIIm, - %%'rEc|jdd}t|dk7r|jd|\}}|j||y)Nr<rrE)rYrrrr\)r]rrNrr^s rCrLzIMAP4Client._regularDispatch sB 4# u:? LL  T S$'rEc\||jkDrtjStS)a8 Create a file to which an incoming message may be written. @type octets: L{int} @param octets: The number of octets which will be written to the file @rtype: Any object which implements C{write(string)} and C{seek(int, int)} @return: A file-like object )rrrr)r]rDs rCrCzIMAP4Client.messageFile! s) D)) )))+ +9 rEcld|jzjd}|xjdz c_|S)Nz%0.4Xasciir<)tagIDrNrs rCmakeTagzIMAP4Client.makeTag1 s-#++G4 a  rEc|j |j}n(t|d|jjzd}|r |||yt j d|jd|d||jjy#t$r1t j |jjYywxYw)N response_zCannot dispatch: z, ) r>response_UNAUTHrNr[rHr5r=rr7)r]rr^rRs rCr\zIMAP4Client.dispatchCommand6 s :: $$AkDJJ,<,<,>>EA  0#t GG' |2cWBthG H NN ) ) + ! 0 --/ 0s B7C  C c |j|jdd\}}|jdk(rd|_nF|jdk(rd|_n+|jj t |dz|z|j d|j d}}|d k7r8|d k7r3|j|jt||dz|gdfy|jdy|j||y) Nr<rrsPREAUTHrrr4]r}) r>rYr[rr7rrserverGreeting_IMAP4Client__cbCapabilitiesr_defaultHandler)r]rr^rr+rSs rCrYzIMAP4Client.response_UNAUTHE s :: ::dA.LFD||~&% :-# --/+C$J,=>>99T?DIIdOqABw17##)),=d1q51o,N+OQU*VW##D)  d +rEc(|j||yrt)r^)r]rr^s rC response_AUTHzIMAP4Client.response_AUTH\ s S$'rEc|dk(s|dk(rt|js|jt|gy|j|j}|dk(r|j |y|j j |y |j|}|jdd\}}|dk(r|j||jn$|jjt||j|=d|_|jy#t$r,|jjt!|dz|zwxYw)Nrrr<rr)waiting _extraInforr*rrrrrYrrrHr _flushQueueKeyErrorrr7r)r]rr^r_rrs rCr^zIMAP4Client._defaultHandler_ s $;#+<<!24!8 9:ii -$;$$T*II$$T* #iin $zz$2 U?JJtT__5II%%nT&:;IIcN#   " ?--/+C$J,=>> ?s D5Ec|jrb|jjd}|j}||j|<|j |j |||_yyr)r3rIrVr*r6rrbr]r_ts rCrdzIMAP4Client._flushQueue{ sS ;;++//!$C ADIIaL MM#**Q- (DL rEcti}dx}}|D]}t|}|dk(r|ddgk(r|jd/|dk(r|ddgk(r|jdO|dk(r|ddk(rt|d}k|dk(r|dd k(rt|d}|d k(r_|dd k(rWt|d}|j|d\}} |j |gj |j d d tjd||r|j||||j||yy)Nr<rrFrTrrrrUrFLAGSr?z Unhandled unsolicited response: ) rrr_parseFetchPairs setdefaultrzrr5rrr) r]rrrrresponseelementsrrIrjs rCrczIMAP4Client._extraInfo sV GH8}H1}!!>  'Q8A;=/#A  &Q8A;)#;Xa[)Q8A;)#;Xa[)Q8A;(#:(1+& 11(1+>   b)00GR1HI:8*EF G"    e $  !3   VV ,"4rEcLtj|_|jr'|jj ||jS|j }||j |<|j|j|||_||_ |jSrt) rrrbr3rrrVr*r6rr8rgs rC sendCommandzIMAP4Client.sendCommand swNN$ << KK  s #99  LLN !  cjjm$  yyrEc|r+|jtj|jSd}d}|jt ||}|j |j |S)av Request the capabilities available on this server. This command is allowed in any state of connection. @type useCache: C{bool} @param useCache: Specify whether to use the capability-cache or to re-retrieve the capabilities from the server. Server capabilities should never change, so for normal use, this flag should never be false. @rtype: L{Deferred} @return: A deferred whose callback will be invoked with a dictionary mapping capability types to lists of supported mechanisms, or to None if a support list is not applicable. r)rr) _capCachersucceedrprrmr])r]useCacher_rors rCgetCapabilitieszIMAP4Client.getCapabilities s[" 2==0 0   WSt< = d++,rEc |\}}i}|D]Z}|ddD]P}|jdd}t|dk(r|dd} }n|\}} |j|gj| R\|D]}||dgk(s d||<||_|S)Nr<rr)rYrrlrrrs) r]rurtaglinerr^r'rNcategoryrgs rC__cbCapabilitieszIMAP4Client.__cbCapabilities s! .1 s 4 4 6rE) r%_getContextFactoryrfailrrsrr+rrprrm _startedTLS)r]rtlsrs` rCr zIMAP4Client.startTLS s" C B C   !!446N  !::6  dnn ,::S  &&t~~t< ;::/    W[1 2 d&&7 67rEc|j|j}ntj|j}|j |j ||S)a2 Attempt to enter the authenticated state with the server This command is allowed in the Non-Authenticated state. @rtype: L{Deferred} @return: A deferred whose callback is invoked if the authentication succeeds and whose errback will be invoked otherwise. )rsrvrrtrm_IMAP4Client__cbAuthenticate)r]secretrs rCrzIMAP4Client.authenticate4 sG >> !$$&A dnn-A d++V4rEc |jddD]K}|jjvs td|dj||}j |cSj r7tjtjjSfd}j}|j||jfd|jj||S)Nr r? AUTHENTICATEc|jttjt j j Srt)traprrrr$r4r#)r=authsr]s rC ebStartTLSz0IMAP4Client.__cbAuthenticate..ebStartTLST s9(zz-eT5H5H5M5M5OPrEc$jSrtrrs rCrTz.IMAP4Client.__cbAuthenticate..] sD$8$8$:rE)rr[r4r_IMAP4Client__cbContinueAuthrpr%rrr$r#r r<rm_IMAP4Client__cbAuthTLS)r]rrschemer_rrrs` @rC__cbAuthenticatezIMAP4Client.__cbAuthenticateE s"% -F||~!4!44#VR1F1FPV'',,  - ??::)%1D1D1I1I1KL    A LL $ MM: ; MM$**F 3HrEc t|dz}|j|}|j||}|jt |j y#t j$r|jdt|wxYw)N r) rr4challengeResponser6rrrrr)r]r^rrrrs rC__cbContinueAuthzIMAP4Client.__cbContinueAutha s 5te|,D &&v.D))&$7D MM+d+113 4 ~~ . MM$ '- - .s A0B c |jdd}|D]K}|j|jvs td|d|j||}|j |cSt ||jj)Nr r?r)rr[r4rrrpr$r#)r]rrrrr_s rC __cbAuthTLSzIMAP4Client.__cbAuthTLSl s"% -F||~!4!44#VR1F1FPV'',,  - (t/B/B/G/G/IJJrEcjt|j}|j|j|||S)a Authenticate with the server using a username and password This command is allowed in the Non-Authenticated state. If the server supports the STARTTLS capability and our transport supports TLS, TLS is negotiated before the login command is issued. A more secure way to log in is to use C{startTLS} or C{authenticate} or both. @type username: L{str} @param username: The username to log in with @type password: L{str} @param password: The password to log in with @rtype: L{Deferred} @return: A deferred whose callback is invoked if login is successful and whose errback is invoked otherwise. )rrvrm_IMAP4Client__cbLoginCaps)r]usernamepasswordrs rCrzIMAP4Client.loginv s/* $.. / d(((H=rEcy)z Called when the server has sent us a greeting. @type caps: C{dict} @param caps: Capabilities the server advertised in its greeting. Nr?)r]rs rCr\zIMAP4Client.serverGreeting rEc~|j |jS ddlm}|jS#t$rYywxYw)Nr)ssl)r5rrClientContextFactory ImportError)r]rs rCrzIMAP4Client._getContextFactory sC << #<<  . ,++- -  s 0 <<cd|v}tj|jddu}tj|jddu}|jsB|r@|r>|r<|j }|j |j|j||f|S|rtjddjt|t|f}|jtd|S)Nr")rz5Server has no TLS support. logging in over cleartext!rr )rr+rr&r%r r_IMAP4Client__cbLoginTLS_IMAP4Client__ebLoginTLSr5rrr|rpr) r]r(rrtryTLStlsableTransportnontlsTransportrrs rC __cbLoginCapszIMAP4Client.__cbLoginCaps s ,&33DNNDIQUU%224>>4HDP6.>? A NN!!!!&1   HOP99fX.x0@ABD##GHd$;< $ 788rEc0tj||Srt)r5r=rgs rC __ebLoginTLSzIMAP4Client.__ebLoginTLS s rEc|d}d}|jt||}|j|j|S)a Retrieve information about the namespaces available to this account This command is allowed in the Authenticated and Selected states. @rtype: L{Deferred} @return: A deferred whose callback is invoked with namespace information. An example of this information is:: [[['', '/']], [], []] which indicates a single personal namespace called '' with '/' as its hierarchical delimiter, and no shared or user namespaces. r)rrr)rprrm_IMAP4Client__cbNamespacer]r_rors rC namespacezIMAP4Client.namespace s<   WSt< = d(()rEc |\}}d}|D]H}t|dk(s|ddk(s|ddDcgc]}|gn|Dcgc] }|| c}c}}cStjdggggScc}wcc}}w)NcJ|Dcgc]}|jdc}Scc}wNrL)decode) namespaceListelements rC_prepareNamespaceOrDelimiterz?IMAP4Client.__cbNamespace.._prepareNamespaceOrDelimiter sANOgGNN=1O OOs rrrr<z*No NAMESPACE response to NAMESPACE command)rr5r=)r]rurrcrrN pairOrNonergs rC __cbNamespacezIMAP4Client.__cbNamespace s  P E5zQ58|#; ',ABi #")KUV%6u=VW  <=B| Ws A5A0 A50A5cd}t|}d}|jt|||}|j|jd|S)a Select a mailbox This command is allowed in the Authenticated and Selected states. @type mailbox: L{str} @param mailbox: The name of the mailbox to select @rtype: L{Deferred} @return: A deferred whose callback is invoked with mailbox information if the select is successful and whose errback is invoked otherwise. Mailbox information consists of a dictionary with the following L{str} keys and values:: FLAGS: A list of strings containing the flags settable on messages in this mailbox. EXISTS: An integer indicating the number of messages in this mailbox. RECENT: An integer indicating the number of "recent" messages in this mailbox. UNSEEN: The message sequence number (an integer) of the first unseen message in the mailbox. PERMANENTFLAGS: A list of strings containing the flags that can be permanently set on messages in this mailbox. UIDVALIDITY: An integer uniquely identifying this mailbox. r=)rjEXISTSr0r1PERMANENTFLAGS UIDVALIDITYrrr<_prepareMailboxNamerprrm_IMAP4Client__cbSelectr]rtr_rrors rCr'zIMAP4Client.select sL@"7+X   WS$TB C dooq)rEcd}t|}d}|jt|||}|j|jd|S)a Select a mailbox in read-only mode This command is allowed in the Authenticated and Selected states. @type mailbox: L{str} @param mailbox: The name of the mailbox to examine @rtype: L{Deferred} @return: A deferred whose callback is invoked with mailbox information if the examine is successful and whose errback is invoked otherwise. Mailbox information consists of a dictionary with the following keys and values:: 'FLAGS': A list of strings containing the flags settable on messages in this mailbox. 'EXISTS': An integer indicating the number of messages in this mailbox. 'RECENT': An integer indicating the number of "recent" messages in this mailbox. 'UNSEEN': An integer indicating the number of messages not flagged \Seen in this mailbox. 'PERMANENTFLAGS': A list of strings containing the flags that can be permanently set on messages in this mailbox. 'UIDVALIDITY': An integer uniquely identifying this mailbox. r>)rrrrrrrrrrrs rCexaminezIMAP4Client.examine! sM@"7+    WS$TB C dooq)rEcJ t|S#t$r t|wxYw)z Parse C{value} as an integer and return the result or raise L{IllegalServerResponse} with C{phrase} as an argument if C{value} cannot be parsed as an integer. )rrer)r]rgphrases rC _intOrRaisezIMAP4Client._intOrRaiseO s+  0u:  0'/ / 0s "cH|\}}d|i}|jt||D]}t|dkDr|djdk(r|d}t |t r|d}n|}|j}|dk(rd|d<`|dk(rd|d<k|d k(r|j |d||d <|d k(r|j |d||d <|d k(r|j |d||d<|dk(rtd|dD|d<tjd|t|dk(r|djdk(rtd|dD|d<:t |dtrz|djdk(r|j |d||d<}|djdk(r|j |d||d<tjd|tjd|tjd||S)zy Handle lines received in response to a SELECT or EXAMINE command. See RFC 3501, section 6.3.1. z READ-WRITErrr<rFrTrrrr1rUIDNEXTrc32K|]}t|ywrtr:r r<s rCrz)IMAP4Client.__cbSelect..z s4/3 T*4rTrzUnhandled SELECT response (2): rrc32K|]}t|ywrtrrs rCrz)IMAP4Client.__cbSelect.. s*S$<+=*SrTrjrrrr0zUnhandled SELECT response (0): zUnhandled SELECT response (1): zUnhandled SELECT response (4): ) rrrrr[rXrYrtupler5r=bytes) r]rur+rrxdatumrYcontentrms rC __cbSelectzIMAP4Client.__cbSelectZ s: "r" &w/0+ CE5zA~%(.."2e";(gt,!!*C"Ciik,&*/E,'M)*.E,'N*+/+;+;GAJ+NE-(I%&*&6&6wqz5&IE(OJ&'+'7'7 E'JE)$--.347>qz4/E*+GG=eWEFUq8>>#x/%**S%PQ(*S%SE'Na%0Qx~~'94*.*:*:58U*Khq)Y6*.*:*:58U*Kh"A% IJGG=eWEF9%ABW+ CX rEcJ|jtdt|S)a| Create a new mailbox on the server This command is allowed in the Authenticated and Selected states. @type name: L{str} @param name: The name of the mailbox to create. @rtype: L{Deferred} @return: A deferred whose callback is invoked if the mailbox creation is successful and whose errback is invoked otherwise. sCREATErprrr]r*s rCrGzIMAP4Client.create " 3Ft3L MNNrEcJ|jtdt|S)ak Delete a mailbox This command is allowed in the Authenticated and Selected states. @type name: L{str} @param name: The name of the mailbox to delete. @rtype: L{Deferred} @return: A deferred whose calblack is invoked if the mailbox is deleted successfully and whose errback is invoked otherwise. sDELETErrs rCrMzIMAP4Client.delete rrEc t|}t|}|jtddj||fS)a Rename a mailbox This command is allowed in the Authenticated and Selected states. @type oldname: L{str} @param oldname: The current name of the mailbox to rename. @type newname: L{str} @param newname: The new name to give the mailbox. @rtype: L{Deferred} @return: A deferred whose callback is invoked if the rename is successful and whose errback is invoked otherwise. sRENAMEr)rrprr)r]rVrWs rCrUzIMAP4Client.rename s> &g.%g. 499gw=O3P QRRrEcJ|jtdt|S)a Add a mailbox to the subscription list This command is allowed in the Authenticated and Selected states. @type name: L{str} @param name: The mailbox to mark as 'active' or 'subscribed' @rtype: L{Deferred} @return: A deferred whose callback is invoked if the subscription is successful and whose errback is invoked otherwise. s SUBSCRIBErrs rCrZzIMAP4Client.subscribe s" 6I$6O PQQrEcJ|jtdt|S)a{ Remove a mailbox from the subscription list This command is allowed in the Authenticated and Selected states. @type name: L{str} @param name: The mailbox to unsubscribe @rtype: L{Deferred} @return: A deferred whose callback is invoked if the unsubscription is successful and whose errback is invoked otherwise. s UNSUBSCRIBErrs rCr^zIMAP4Client.unsubscribe s"8KD8Q RSSrEcd}d|d|djd}d}|jt|||}|j|jd|S)ap List a subset of the available mailboxes This command is allowed in the Authenticated and Selected states. @type reference: L{str} @param reference: The context in which to interpret C{wildcard} @type wildcard: L{str} @param wildcard: The pattern of mailbox names to match, optionally including either or both of the '*' and '%' wildcards. '*' will match zero or more characters and cross hierarchical boundaries. '%' will also match zero or more characters, but is limited to a single hierarchical level. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a list of L{tuple}s, the first element of which is a L{tuple} of mailbox flags, the second element of which is the hierarchy delimiter for this mailbox, and the third of which is the mailbox name; if the command is unsuccessful, the deferred's errback is invoked instead. B{NB}: the delimiter and the mailbox name are L{str}s. r"z" "rL)rrr)rNrprrm_IMAP4Client__cbList)r] referencewildcardr_rrors rCrYzIMAP4Client.list s]8I;c(1-55mD   WS$TB C dmmW-rEcd}|jd}|jd}djd|d|dg}d}|jt|||}|j |j d|S) aa List a subset of the subscribed available mailboxes This command is allowed in the Authenticated and Selected states. The parameters and returned object are the same as for the L{list} method, with one slight difference: Only mailboxes which have been subscribed can be included in the resulting list. rrTrLrErs" ")rrr)rNrrprrmr) r]rrr_encodedReferenceencodedWildcardrrors rClsubzIMAP4Client.lsub s$++G4"//-8xx       WS$TB C dmmW-rEc|\}}g}|D]}}t|dk(s|d|k(std|dD|d<|djd|d<|djd|d<|jt|dd|S)Nrrc32K|]}t|ywrtrrs rCrz'IMAP4Client.__cbList..) s Id!3 IrTr<rrLrU)rrrrr)r]rurrrcr`rNs rC__cbListzIMAP4Client.__cbList" s  1E5zQ58w#6 Ia IIa!8??=9a 8??=9auU12Y/0) 1*rEr/r0rrr1rTcjd}t|} djfd|D}dj|d|dg}d}j t||| }|jj|S#t$r.tdt |t j z wxYw) a7 Retrieve the status of the given mailbox This command is allowed in the Authenticated and Selected states. @type mailbox: L{str} @param mailbox: The name of the mailbox to query @type names: L{bytes} @param names: The status names to query. These may be any number of: C{'MESSAGES'}, C{'RECENT'}, C{'UIDNEXT'}, C{'UIDVALIDITY'}, and C{'UNSEEN'}. @rtype: L{Deferred} @return: A deferred which fires with the status information if the command is successful and whose errback is invoked otherwise. The status information is in the form of a C{dict}. Each element of C{names} is a key in the dictionary. The value for each key is the corresponding response from the server. rrc3<K|]}j|ywrt) _statusNames)r r*r]s rCrz%IMAP4Client.status..a sH$d//5HszUnknown names: rErr)rrr) rrreresetrrprrm_IMAP4Client__cbStatus)r]rtrr_preparedMailboxrrors` rCrzIMAP4Client.statusH s*-g6 XIIH%HHExx%=>   WS$TB C doo& Xs5zC@Q@QDD8=> d+> >  ( IIl #  #      IsB(?(? I ?sB4ctj}|j||jdj |j Srt)r3 FileSenderbeginFileTransferrrm_IMAP4Client__cbFinishAppend)r]rrrs rC__cbContinueAppendzIMAP4Client.__cbContinueAppend s?    ""7DNNDAMM  ! !  rEc&|jdyrr)r]foos rC__cbFinishAppendzIMAP4Client.__cbFinishAppend s crEc6|jtdS)a Tell the server to perform a checkpoint This command is allowed in the Selected state. @rtype: L{Deferred} @return: A deferred whose callback is invoked when this command succeeds or whose errback is invoked if it fails. sCHECKrprrbs rCryzIMAP4Client.check s 122rEc6|jtdS)a Return the connection to the Authenticated state. This command is allowed in the Selected state. Issuing this command will also remove all messages flagged \Deleted from the selected mailbox if it is opened in read-write mode, otherwise it indicates success by no messages are removed. @rtype: L{Deferred} @return: A deferred whose callback is invoked when the command completes successfully or whose errback is invoked if it fails. sCLOSErrbs rCr;zIMAP4Client.close s 122rEc|d}d}|jt||}|j|j|S)a Return the connection to the Authenticate state. This command is allowed in the Selected state. Issuing this command will perform the same actions as issuing the close command, but will also generate an 'expunge' response for every message deleted. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a list of the 'expunge' responses when this command is successful or whose errback is invoked otherwise. r)rrr)rprrm_IMAP4Client__cbExpungers rCrzIMAP4Client.expunge s<   WSt< = d&&'rEc|\}}g}|D]>}t|dk(s|ddk(s|j|j|d|@|S)Nrr<rr)rrrr)r]rurrcrrNs rCrzIMAP4Client.__cbExpunge sY  >E5zQ58z#9 4++E!He<= > rErc|Dcgc]}|jd}}|rdnd}dj|}|jt|||f}|j |j |Scc}w)a Search messages in the currently selected mailbox This command is allowed in the Selected state. Any non-zero number of queries are accepted by this method, as returned by the C{Query}, C{Or}, and C{Not} functions. @param uid: if true, the server is asked to return message UIDs instead of message sequence numbers. @type uid: L{bool} @rtype: L{Deferred} @return: A deferred whose callback will be invoked with a list of all the message sequence numbers return by the search, or whose errback will be invoked if there is an error. rs UID SEARCHrrrr)rNrrprrm_IMAP4Client__cbSearch)r]rfqueriesrr_rrs rCrzIMAP4Client.search sn(9@@u5<< *@@"m yy!   WS$cVD E doo& AsA1c |\}}g}|D]L}t|dkDs|ddk(s|j|ddDcgc]}|j||c}N|Scc}w)Nrrr<)rrzr)r]rurr_rrNrs rCrzIMAP4Client.__cbSearchsn  LE5zA~%(i"7 ab J1D,,Q6JK L KsA c*|j||dS)aV Retrieve the unique identifier for one or more messages This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message sequence numbers to unique message identifiers, or whose errback is invoked if there is an error. r<)useUIDrf_fetchr]r\rfs rCfetchUIDzIMAP4Client.fetchUIDs${{8CQ{77rEc*|j||dS)aH Retrieve the flags for one or more messages This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: The messages for which to retrieve flags. @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to lists of flags, or whose errback is invoked if there is an error. r<)rrrrs rC fetchFlagszIMAP4Client.fetchFlags,s${{8Cq{99rEc*|j||dS)a Retrieve the internal date associated with one or more messages This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: The messages for which to retrieve the internal date. @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to date strings, or whose errback is invoked if there is an error. Date strings take the format of "day-month-year time timezone". r<)r internaldaterrs rCfetchInternalDatezIMAP4Client.fetchInternalDate@s&{{8Ca{@@rEc*|j||dS)a Retrieve the envelope data for one or more messages This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: The messages for which to retrieve envelope data. @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to envelope data, or whose errback is invoked if there is an error. Envelope data consists of a sequence of the date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, and message-id header fields. The date, subject, in-reply-to, and message-id fields are L{str}, while the from, sender, reply-to, to, cc, and bcc fields contain address data as L{str}s. Address data consists of a sequence of name, source route, mailbox name, and hostname. Fields which are not present for a particular address may be L{None}. r<)renveloperrs rC fetchEnvelopezIMAP4Client.fetchEnvelopeUs6{{8C!{<>rEc*|j||dS)a6 Retrieve the size, in octets, of one or more messages This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to sizes, or whose errback is invoked if there is an error. r<)r rfc822sizerrs rC fetchSizezIMAP4Client.fetchSizer-rEc 2|j||dddddS)aV Retrieve several different fields of one or more messages This command is allowed in the Selected state. This is equivalent to issuing all of the C{fetchFlags}, C{fetchInternalDate}, C{fetchSize}, C{fetchEnvelope}, and C{fetchSimplifiedBody} functions. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to dict of the retrieved data values, or whose errback is invoked if there is an error. They dictionary keys are "flags", "date", "size", "envelope", and "body". r<)rrrr/rrrrs rC fetchFullzIMAP4Client.fetchFulls/,{{   rEc0|j||ddddS)a. Retrieve several different fields of one or more messages This command is allowed in the Selected state. This is equivalent to issuing all of the C{fetchFlags}, C{fetchInternalDate}, C{fetchSize}, and C{fetchEnvelope} functions. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to dict of the retrieved data values, or whose errback is invoked if there is an error. They dictionary keys are "flags", "date", "size", and "envelope". r<)rrrr/rrrs rCfetchAllzIMAP4Client.fetchAlls(*{{ SaRS  rEc.|j||dddS)a Retrieve several different fields of one or more messages This command is allowed in the Selected state. This is equivalent to issuing all of the C{fetchFlags}, C{fetchInternalDate}, and C{fetchSize} functions. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a dict mapping message numbers to dict of the retrieved data values, or whose errback is invoked if there is an error. They dictionary keys are "flags", "date", and "size". r<)rrrr/rrs rC fetchFastzIMAP4Client.fetchFast2s*{{8CqqUV{WWrEcF fd i}g}t|} t|} t|}|dvrd}n>t |t sd}n+t |dkDrd}n|rt |dt rd}nd}t|}|j||rt |dkr7|Dcgc] }t|}}|j||t|f}nKt|d} |dDcgc] }t|} }|j| | g|| t| ff} t|}|jd rN|jd r= t|dd t|}|j|||fz} t|} |}|j||||<#t$rY||fSwxYw#t$r td|wxYwcc}wcc}w#t$r td|wxYw#t$r td|wxYw#t$rYwxYw) a Given the result of parsing a single I{FETCH} response, construct a L{dict} mapping response keys to response values. @param fetchResponseList: The result of parsing a I{FETCH} response with L{parseNestedParens} and extracting just the response data (that is, just the part that comes after C{"FETCH"}). The form of this input (and therefore the output of this method) is very disagreeable. A valuable improvement would be to enumerate the possible keys (representing them as structured objects of some sort) rather than using strings and tuples of tuples of strings and so forth. This would allow the keys to be documented more easily and would allow for a much simpler application-facing API (one not based on looking up somewhat hard to predict keys in a dict). Since C{fetchResponseList} notionally represents a flattened sequence of pairs (identifying keys followed by their associated values), collapsing such complex elements of this list as C{["BODY", ["HEADER.FIELDS", ["SUBJECT"]]]} into a single object would also greatly simplify the implementation of this method. @return: A C{dict} of the response data represented by C{pairs}. Keys in this dictionary are things like C{"RFC822.TEXT"}, C{"FLAGS"}, or C{("BODY", ("HEADER.FIELDS", ("SUBJECT",)))}. Values are entirely dependent on the key with which they are associated, but retain the same structured as produced by L{parseNestedParens}. ct|tr|jdSt|tr|Dcgc] }| c}Sycc}w)Nr)rXrrrY)thingsubthingnativeStringResponses rCr;z:IMAP4Client._parseFetchPairs..nativeStringResponseosE%'||I..E4(GLM8,X6MM)MsA TsNot enough arguments)BODYs BODY.PEEKFrrr<<>r})rYrardrrXrYrr:rrrrrrre) r]fetchResponseListrI unstructured responsePartsrmrg hasSectionr valueHead valueTailr;s @rCrkzIMAP4Client._parseFetchPairsIsL N  ./  =) X]+611# t,# Ua" :eAh5# " s#C    $u:>6;<\!_?E),< =>C /E##D)ennT.BE!BK( !-U 3$++E2!UHn$($7E )/E    &F3KE! @|##C  ! X+,CEVWW Xj= !D %//1B$ -"7 79J#&sR F- F?$G,G# G"H G;- F<;F<?G"G8;H H H c(|\}}i}|D]W}t|dk(s|ddk(s|j|d|}||vr |dg||<>||dj|dYi} i} |jD]b\} } |j | d\} }| j | ggdj|| j | ij | d| }i}t| jD]~} | | } t| jD][}||vs|dk(s| d|| <tt|| dD] }|| d|dk(s|| d||dz=n| d=| rY| | =]|r|j||r| S|S)NrUr<rrrrj) rrrzrrkrlupdaterYr#rr)r]rurequestedParts structuredrrcinforNrr` decodedInfo messageIdrI structuredMapunstructuredList flagChangesrrhs rC_cbFetchzIMAP4Client._cbFetchs  1E5zQ58x#7%%eAh6T> %azDHHQK&&uQx0  1 !% D Iv.2.C.CF1I.N +M+  " "9rd 3A 6 = =>N O   y" - 4 4] C D glln- /IY'FV[[]+ /~-$'/-3G_K *"3tIq'9#:;" ?1-a0G; $Y 21q1u9 =!"w!#I. / /    k * NKrEc d} |d} n;t|tr t|} ndjt t|} |d} n | rd|z} n|} | r|dvr|ddj|z} nd} nd} |d} nd||fz} |xrd xsd }| ||xrd xsd| | | | fz}|j d }|j t||d }|j|jdd|S)a^ Retrieve a specific section of one or more messages @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @type headerType: L{str} @param headerType: If specified, must be one of HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, or TEXT, and will determine which part of the message is retrieved. For HEADER.FIELDS and HEADER.FIELDS.NOT, C{headerArgs} must be a sequence of header names. For MIME, C{headerNumber} must be specified. @type headerNumber: L{int} or L{int} sequence @param headerNumber: The nested rfc822 index specifying the entity to retrieve. For example, C{1} retrieves the first entity of the message, and C{(2, 1, 3}) retrieves the 3rd entity inside the first entity inside the second entity of the message. @type headerArgs: A sequence of L{str} @param headerArgs: If C{headerType} is HEADER.FIELDS, these are the headers to retrieve. If it is HEADER.FIELDS.NOT, these are the headers to exclude from retrieval. @type peek: C{bool} @param peek: If true, cause the server to not set the \Seen flag on this message as a result of this command. @type offset: L{int} @param offset: The number of octets at the beginning of the result to skip. @type length: L{int} @param length: The number of octets to retrieve. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a mapping of message numbers to retrieved data, or whose errback is invoked if there is an error. z%s BODY%s[%s%s%s]%sr.)z HEADER.FIELDSzHEADER.FIELDS.NOTz (%s)rz ()z<%d.%d> UID FETCHrz.PEEKrrrrr?F) rXrrrrkrNrprrmrO)r]r\rf headerType headerNumber headerArgspeekoffsetlengthfmtnumberrpayloadextrarr_rs rC fetchSpecificzIMAP4Client.fetchSpecific sn$  F  c *&FXXc#|45F  F :%FF j$JJ%!CHHZ$88G >E 00E$ 0Xt/52vvwPUVVjj#   WUCkJ K dmmR/rEc t|jd}|xrdxsd}d|vr|d=d|d<d|vr|d=d|d<d |vr|d =d|d <|Dcgc] }t|}}|d zd j|Dcgc]}|j c}zd z}|j t ||d}|j|j|jD cgc]} | j c} d|Scc}wcc}wcc} w)NrTrRrr+T rfc822.textr/ rfc822.sizer( rfc822.headerrrrrSrr) rrNr;rr[rprrmrOr#) r]r\rtermsrr encodedTermsr_rrhs rCrzIMAP4Client._fetchcsx=''0'<38 5 l##'E- 5 l##'E- U "n%%)E/ " 388Q a(8 8|+L!AGGI+L!MMPTT   WUCkJ K dmm%FAaggi%FM 9+L&Gs C=4D D c,|j|d|||S)a  Set the flags for one or more messages. This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type flags: Any iterable of L{str} @param flags: The flags to set @type silent: L{bool} @param silent: If true, cause the server to suppress its verbose response. @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a list of the server's responses (C{[]} if C{silent} is true) or whose errback is invoked if there is an error. r_storer]r\rrrfs rCsetFlagszIMAP4Client.setFlags{s2{{8XvucBBrEc,|j|d|||S)a Add to the set flags for one or more messages. This command is allowed in the Selected state. @type messages: C{MessageSet} or L{str} @param messages: A message sequence set @type flags: Any iterable of L{str} @param flags: The flags to set @type silent: C{bool} @param silent: If true, cause the server to suppress its verbose response. @type uid: C{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a list of the server's responses (C{[]} if C{silent} is true) or whose errback is invoked if there is an error. s+FLAGSrfrhs rCaddFlagszIMAP4Client.addFlags2{{8YsCCrEc,|j|d|||S)a Remove from the set flags for one or more messages. This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type flags: Any iterable of L{str} @param flags: The flags to set @type silent: L{bool} @param silent: If true, cause the server to suppress its verbose response. @type uid: L{bool} @param uid: Indicates whether the message sequence set is of message numbers or of unique message IDs. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a list of the server's responses (C{[]} if C{silent} is true) or whose errback is invoked if there is an error. s-FLAGSrfrhs rC removeFlagszIMAP4Client.removeFlagsrlrEcht|jd}|Dcgc] }t|}}|r|dz}|xrdxsd}dj||ddj|zdzf} |j t || d } d } |sd } | j |j| d | Scc}w) NrTs.SILENTs UID STORErrrrrSrrr?)rjT)rrNr;rrprrmrO) r]r\r_rrrfr<rqrrrexpecteds rCrgzIMAP4Client._storesx=''08=> d+> >  "C$ 0yy(C ,0G)G$)NOP   WUD{K L!H dmmXt4?sB/ct|jd}|rd}nd}dj|t|g}|j t ||S)a Copy the specified messages to the specified mailbox. This command is allowed in the Selected state. @type messages: L{MessageSet} or L{str} @param messages: A message sequence set @type mailbox: L{str} @param mailbox: The mailbox to which to copy the messages @type uid: C{bool} @param uid: If true, the C{messages} refers to message UIDs, rather than message sequence numbers. @rtype: L{Deferred} @return: A deferred whose callback is invoked with a true value when the copy is successful, or whose errback is invoked if there is an error. rTsUID COPYrr)rrNrrrpr)r]r\rtrfr_rs rCr zIMAP4Client.copysV*x=''0 CCyy($7$@ABT 233rEcyz Override meNr?rs rCrzIMAP4Client.modeChangedrrEcyrsr?)r]rs rCrzIMAP4Client.flagsChangedrrEcyrsr?rs rCrzIMAP4Client.newMessagesrrErtr<)r?Nr)rNNNNNN)r<r)jrrrrr*rbr3rUr>r%r5rsrr4 STATUS_CODESrrr5r`r;rErEr/r3rHr@rLrCrVr\rYr`r^rdrcrprvr]rr|rrr rrrrrr\rrrrrrrr'rrrrGrMrUrZr^rYrrrNrrrrrrrryr;rr rrrrrrr!r#r&r)r,r0r2r4r6rkrOr^rrirkrnrgr rrr)r r*s00rCr)r)p sm DG F E EJG I'N8L*-LG ;5.*.$(,T ((  ,,.(#8-8 2*   1f"8 5K2 .=2 9*6'R,\ 07r O OS( R T!F8:    dkk'"" L!F..`  33 *$)88(:(A*=:B:9,;0A(?(?( @ 2X.T$l(Z  Xt0C6D6D6 4@G sE*r)c6t}|jd}|D]}d|vr|jdd\}} |dk(rd}n t|}|dk(rd}n t|}||cxur t|||dks||dkr t||xs|}|xs|}|j || |dk(rd}n t|}||dkr t||j |xs||S#t $r t|wxYw#t $r t|wxYw)a Parse a message set search key into a C{MessageSet}. @type s: L{bytes} @param s: A string description of an id list, for example "1:3, 4:*" @type lastMessageId: L{int} @param lastMessageId: The last message sequence id or UID, depending on whether we are parsing the list in UID or sequence id context. The caller should pass in the correct value. @rtype: C{MessageSet} @return: A C{MessageSet} that contains the ids defined in the list ,:r<rNr)rLrYrrr[rerz)rrrwrNrrirjs rCrrsR ,C GGDME $/ 19a(IC 0$;Cc(C4<Dt9D$&033'Oqd6F4ST9033,}*]T" /9AAA=Q!V033 1- .I$/J J 0,Q// 0 0,Q// 0sA0C+-%D+DD)ALLANSWEREDDELETEDDRAFTFLAGGEDNEWOLDr0SEEN UNANSWERED UNDELETEDUNDRAFT UNFLAGGEDr1)LARGERSMALLERUIDc g}|j}|r t|}|D]}||}|j}|tvr|r|j |5|dk(r-|j |t |dt |dgg|dk(s|dk(r*tjd|}|j ||g|tvr@t|trd}nt|t rd}nd}|j |||fzgt|tr|j |d |fzg |j ||g"t|dkDrd d j|zd zSd j|S) a Create a query string Among the accepted keywords are:: all : If set to a true value, search all messages in the current mailbox answered : If set to a true value, search messages flagged with \Answered bcc : A substring to search the BCC header field for before : Search messages with an internal date before this value. The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. body : A substring to search the body of the messages for cc : A substring to search the CC header field for deleted : If set to a true value, search messages flagged with \Deleted draft : If set to a true value, search messages flagged with \Draft flagged : If set to a true value, search messages flagged with \Flagged from : A substring to search the From header field for header : A two-tuple of a header name and substring to search for in that header keyword : Search for messages with the given keyword set larger : Search for messages larger than this number of octets messages : Search only the given message sequence set. new : If set to a true value, search messages flagged with \Recent but not \Seen old : If set to a true value, search messages not flagged with \Recent on : Search messages with an internal date which is on this date. The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. recent : If set to a true value, search for messages flagged with \Recent seen : If set to a true value, search for messages flagged with \Seen sentbefore : Search for messages with an RFC822 'Date' header before this date. The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. senton : Search for messages with an RFC822 'Date' header which is on this date The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. sentsince : Search for messages with an RFC822 'Date' header which is after this date. The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. since : Search for messages with an internal date that is after this date.. The given date should be a string in the format of 'DD-Mon-YYYY'. For example, '03-Mar-2003'. smaller : Search for messages smaller than this number of octets subject : A substring to search the 'subject' header for text : A substring to search the entire message for to : A substring to search the 'to' header for uid : Search only the messages in the given message set unanswered : If set to a true value, search for messages not flagged with \Answered undeleted : If set to a true value, search for messages not flagged with \Deleted undraft : If set to a true value, search for messages not flagged with \Draft unflagged : If set to a true value, search for messages not flagged with \Flagged unkeyword : Search for messages without the given keyword set unseen : If set to a true value, search for messages not flagged with \Seen @type sorted: C{bool} @param sorted: If true, the output will be sorted, alphabetically. The standard does not require it, but it makes testing this function easier. The default is zero, and this should be acceptable for any application. @rtype: L{str} @return: The formatted query string HEADERrr<KEYWORD UNKEYWORDrz"%s"z"%d"z%drr))r#_sortedr[ _SIMPLE_BOOLrrrzr _nonAtomREre _NO_QUOTESrXrLrrr)rnkwargr_r#rrrZs rCQueryrSsZ\ C ::->-E-Eg-N(N 4 ACx d# a DF w KKN7:"" JJt  8 MM$  M MM!  MrEcg}||d}|dg}|ddD]@}||}||k7r |j||||g}|}0|j|B|j||||SNrr<)rzrr)sequence predicate transformersrurtmprSrs rCsplitOnr?s F Xa[ !D A;-C ab\ aL 9 MM,,t,S1 2#CD JJqM MM$,t$S)* MrEc6g}d}d}ddd}t|D]Z\}}t|tr@|"|jt |||||d}|j t |V|Y|}\| |jt ||d|||S)a{ Turns a list of length-one strings and lists into a list of longer strings and lists. For example, ['a', 'b', ['c', 'd']] is returned as ['ab', ['cd']] @type results: L{list} of L{bytes} and L{list} @param results: The list to be collapsed @rtype: L{list} of L{bytes} and L{list} @return: A new list which is the collapsed form of C{results} Nc"t|tSrt)rXrrSs rCrTz!collapseStrings.._s Z5)rEc6tdj|Sr)rrrs rCrTz!collapseStrings..as[!-rEcRdj|Dcgc]}|d c}gScc}w)NrEr)r)rSrhs rCrTz!collapseStrings..bs$chha0!0120s $)rr<)rfrXrYrzrrrcollapseStrings)r`r begunpredtranrhrs rCrrOs D E )D - 2 D'"1 a   GGE!$4dDAB DKK* + ]E  GGEFOT489 KrEcf|j}d}gg} d}t|}||krJ|||dz}|rG|dk(r |dj|||dz|dz }5|dk(r| }|dj||dz }n|dk(r|dj|| }|dz }n|rb|dk(r]|jd|}|dk(r t d t ||dz|}|dj||d z|d z|zf|d z|z}nl|d k(s|d k(r|jg|dz }nK|d k(s|dk(r(|dj|j |dz }n|dj||dz }||krJt|dk7r t|t|dS#t$r t|wxYw)ak Parse an s-exp-like string into a more useful data structure. @type s: L{bytes} @param s: The s-exp-like string to parse @rtype: L{list} of L{bytes} and L{list} @return: A list containing the tokens present in the input. @raise MismatchedNesting: Raised if the number or placement of opening or closing parenthesis is invalid. rr<rr}rrrrrrUrr4rr[) rrrrrrerrI IndexErrorr r) r handleLiteralr contentStackrhrrr_ literalSizes rCrrqs  AG4L$#  F!e!a!e A: $++Aa!a%L9FA$Y")kGR ''*Q9 $++A.")kGFA"qDy&&q/Cby()<=="%aAn"5K $++QsQwq;9N-O,QRa+-A$Y!t) ''+FA$Y!t) $++L,<,<,>?FA $++A.FA?!eD <A"" <? ++ #""#s EFF0ctd|}td|}||j|||zj|||zz|zS)Nrr)r8r)rrrs rCr|r|sJ a B &! $C  #sSy)11"cBh? ?" DDrErrc"dt||fzS)Ns{%d} %b)rrs rCrrs CFA; &&rEceZdZdZdefdZy)rjc||_yrt)rg)r]rgs rCr`zDontQuoteMe.__init__s  rErc,t|jSrt)rrgrbs rCrzDontQuoteMe.__str__s4::rEN)rrrr`rrr?rErCrjrjsrErjs(){ %*"c\|dk(ryt|D]}|dks|dkDry|tvsyy)NrEr<rr)r9_ATOM_SPECIALS)rrs rC _needsQuoters?Cx q\ w;!g+    rEct|tr|S |jdS#t$r t j t |wxYwr)rXrrrHr5r=rr*s rCr&r&sH$ +{{=)) +  $T**+s %)Act|ts|jd}|jd}t |r t |S|S)NrrL)rXrrrNrr|rs rCrrs? dC {{9% ;;} %D4d| KrEcftd|}td|}||vxs||vxst|dkDS)N  i)r8r)rcrlfs rC _needsLiteralrs: q !B q !B 7 .bAg .Q$.rEc *g}|D]x}t|tr|jd}||jddg;t|tr&|jdt t|gqt|t r|jd|jgt|trZt|r1|jddt|fztj|g|jdt|g t|drB|j}|jddt|fztj|gW|jddt!|zdzg{d j#|d dS) a Turn a nested list structure into an s-exp-like string. Strings in C{items} will be sent as literals if they contain CR or LF, otherwise they will be quoted. References to None in C{items} will be translated to the atom NIL. Objects with a 'read' attribute will have it called on them with no arguments and the returned string will be inserted into the output as a literal. Integers will be converted to strings and inserted into the output unquoted. Instances of C{DontQuoteMe} will be converted to strings and inserted into the output unquoted. This function used to be much nicer, and only quote things that really needed to be quoted (and C{DontQuoteMe} did not exist), however, many broken IMAP4 clients were unable to deal with this level of sophistication, forcing the current behavior to be adopted for practical reasons. @type items: Any iterable @rtype: L{str} rTNrsNILs{%d}r@rrrEr<)rXrrNrzrr;rjrgrrrr delimiterr|hasattrr@rr)rpiecesrhrs rCrrsL,F H a !A 9 MM4. ) 3  MM4s1v!67 8 ; ' MM4/ * 5 !Q tWAy%8+:O:OQRST tVAY/0 Q A MM4CF9!4k6K6KQO P MM4(;A(>!>!EF G-H. 88F12J rEcjeZdZdZdZdZdZdZddZdZ dZ ddZ d Z d Z d Zd Zd ZdZdZy)MemoryAccountWithoutNamespacesNrc.||_i|_g|_yrt)r*rl subscriptionsrs rCr`z'MemoryAccountWithoutNamespaces.__init__s rEcH|j}|xjdz c_|SrQ)top_id)r]rs rC allocateIDz)MemoryAccountWithoutNamespaces.allocateID!s [[ q  rEct|j}||jvr t|| |j ||j }||j|<yrQ)r&r[rlr _emptyMailboxr)r]r*r8s rC addMailboxz)MemoryAccountWithoutNamespaces.addMailbox)sX$**,' 4>> !"4( ( <%%dDOO,=>D#trEcp|jdDcgc]}|s| }}tdt|D]&} |jdj |d|( |jdj |ycc}w#t $rY[wxYw#t $r|j dsYyYywxYw)N/r<FT)rYrrrrrr)r]pathspecpathpathsaccums rCrGz%MemoryAccountWithoutNamespaces.create2s"*.."5>$>>1c%j) E v 78    OOCHHUO ,?$    $$S)* s-BB#B! B BBB54B5ctrt)NotImplementedError)r]r*rs rCrz,MemoryAccountWithoutNamespaces._emptyMailbox@s!!rEcf|jjt|jSrt)rlrr&r[)r]r* readwrites rCr'z%MemoryAccountWithoutNamespaces.selectCs"~~!!*TZZ\":;;rEct|j}|jj|}|s t dd|j vrA|jj D]$}||k7s |j|st d|jt|j|dkDrt d|d|j|=y)NzNo such mailboxz \Noselectzf&7&7&=*W   t""4( )A -"VD61R#ST T NN4 rEc t|j}t|j}||jvr t||j |}|Dcgc]}||j ||df}}|D]\}}||jvst ||D].\}}|j||j|<|j|=0ycc}wrQ)r&r[rlr#rrr)r]rVrW inferiorsooldnews rCrUz%MemoryAccountWithoutNamespaces.rename]sW]]_-W]]_- $.. (( (''0 BKLQa7GQ78L L! ,HCdnn$&s++ ," $HC"&.."5DNN3 s# $ Ms!Ccg}|jjD]%}|j|s|j|'|Srt)rlr#rrr)r]r*rinfnames rCrz-MemoryAccountWithoutNamespaces._inferiorNamesnsG ~~**, *G!!$'  ) *rEcLt|j|jvSrt)r&r[rrs rCrhz+MemoryAccountWithoutNamespaces.isSubscribedus$**,'4+=+===rEct|j}||jvr|jj|yyrt)r&r[rrrrs rCrZz(MemoryAccountWithoutNamespaces.subscribexs9$**,' t)) )    % %d + *rEct|j}||jvrtd||jj |y)NzNot currently subscribed to )r&r[rrremovers rCr^z*MemoryAccountWithoutNamespaces.unsubscribe}sG$**,' t)) )"%A$#HI I !!$'rEc|jt|j}t|d}|Dcgc]%}|j |s||j |f'c}Scc}w)Nr)rr&r[rrrl)r]rdrrhs rCraz,MemoryAccountWithoutNamespaces.listMailboxessV!!*SYY["9:#Hc203I1x~~a7HDNN1%&IIIs A&A&rtrv)rrrrlrrr`rrrGrr'rMrUrrhrZr^rar?rErCrrsSIM F  "<!.$">, ( JrErc$eZdZdZdZdZdZy) MemoryAccountc ddggS)NrE/r?rbs rCrz#MemoryAccount.getPersonalNamespacessd }rEcyrtr?rbs rCrz!MemoryAccount.getSharedNamespacesrEcyrtr?rbs rCgetOtherNamespacesz MemoryAccount.getOtherNamespacesrrEcyrtr?rbs rCgetUserNamespaceszMemoryAccount.getUserNamespacessrEN)rrrrrrrr?rErCrrs rErr7r8 getUIDNextr9getUnseenCountrcji}|D]+}t|t|j||<-|Srt)rN_statusRequestDictr[)r8rrrSs rCstatusRequestHelperr s< A >;wt/ :;=!> HrEc|dgStjj|g}|Dcgc]\}}|xsddg|jdz!c}}Scc}}w)Nr@)rr getaddressesrY)addrrgaddresss rC parseAddrrs[ |    ;; # #TF +DGK L GRZ4 s!3 3 LL Ls$Ac  |jd}|jd}|jd}|jd}|jd|}|jd|}|jd}|jd}|jd } |jd } |jd } ||t|t||xr t||xr t||xr t|| xr t| | | f S) NTrr>r senderzreply-torDrrz in-reply-toz message-id)rrr) rheadersrr>from_rreply_torDrr in_reply_tomids rCrjrjsnnT"G ;;v Dkk)$G KK E [[5 )F{{:u-H T B T B ++e C++m,K ++l #C %&(Yx( y} y}  #   rEc>d}|jD]}|dz } |Sr)r)rrrjs rC getLineCountrs- E __    LrEc:|d|dcxk(rdk(r n|S|ddS|S)Nrr}rr<r?rs rCunquoters.tqu H2w HrEcLd}|jddjdd}dj|j}|rW|j d}|dj dd}t |dk(r|d}d}n|\}}t d |ddD}ndx}}|||fS) zJ Return a two-tuple of the main and subtype of the given message. NF content-typer;rrr<c3xK|]2}|jjjdd4yw)=r<N)rr6rY)r rSs rCrz"_getContentType..s*KQWWY__&,,S!4Ks8:)rrr splitlinesrYrdict)rattrsmmmimetypermajorminors rC_getContentTyper)s E ~ . 2 2>2 FB  !B 88C={  a( t9>GEE LE5KhqrlKK % rEct|\}}}||j}||j}|dk(r t|||S||fdk(rt||||S|dk(rt ||||St ||||S)aE Construct an appropriate type of message structure object for the given message object. @param message: A L{IMessagePart} provider @return: A L{_MessageStructure} instance of the most specific type available for the given message, determined by inspecting the MIME type of the message. multipart)rr%r6)r)r6_MultipartMessageStructure_RFC822MessageStructure_TextMessageStructure_SinglepartMessageStructure)rmainsubtyper$s rC_getMessageStructurer2s+73D'5 zz|--/ {)'7EBB 1 1&wguEE $WdGUCC*7D'5IIrEc"eZdZdZdZdZdZy)_MessageStructurez L{_MessageStructure} is a helper base class for message structure classes representing the structure of particular kinds of messages, as defined by their MIME type. c ||_||_y)z @param message: An L{IMessagePart} provider which this structure object reports on. @param attrs: A C{dict} giving the parameters of the I{Content-Type} header of the message. N)rr$)r]rr$s rCr`z_MessageStructure.__init__s  rEc |r|jd}t|dk(r|djdf}|St|dkDr@|ddDcgc]}|jddD]}|}}}|dj|g}|Sycc}}w)a Parse a I{Content-Disposition} header into a two-sequence of the disposition and a flattened list of its parameters. @return: L{None} if there is no disposition header value, a L{list} with two elements otherwise. z; r<rNr!)rYrr6)r]dispparamrSparamss rC _dispositionz_MessageStructure._disposition s ::d#D4yA~Q . K TQ)-abO5;;sA;NOa!O!OOQ 0K Ps B c|jrY|jjDcgc]\}}|t|f}}}t|Dcgc] }|D]}| c}}Sycc}}wcc}}w)z @return: The I{Content-Type} parameters, unquoted, as a flat list with each Nth element giving a parameter name and N+1th element giving the corresponding parameter value. N)r$rrrn)r]rrunquotedrSys rC_unquotedAttrsz _MessageStructure._unquotedAttrs4se ::6:jj6F6F6HIFQGAJIHI%h/;!;AA;A; ;J;s A'A-N)rrrrr`r:r>r?rErCr4r4s ( rEr4c0eZdZdZgdZdZdZdZdZy)r/zn L{_SinglepartMessageStructure} represents the message structure of a non-I{multipart/*} message. ) content-idcontent-descriptioncontent-transfer-encodingc\tj|||||_||_||_y)a @param message: An L{IMessagePart} provider which this structure object reports on. @param main: A L{str} giving the main MIME type of the message (for example, C{"text"}). @param subtype: A L{str} giving the MIME subtype of the message (for example, C{"plain"}). @param attrs: A C{dict} giving the parameters of the I{Content-Type} header of the message. N)r4r`r0r1r$)r]rr0r1r$s rCr`z$_SinglepartMessageStructure.__init__Hs+ ""4%8   rEc@|jjdg|j}|jj}|j|j }}|j }||||jd|jd|jd|gS)zN Return a list of the basic fields for a single-part message. Fr@rArB)rr_HEADERSrr0r1r>r)r]rrr'r( unquotedAttrss rC _basicFieldsz(_SinglepartMessageStructure._basicFields[s*$,,))%@$--@||##%yy$,,u++-     KK % KK- . KK3 4   rEch|j}|r|j|j|S)z Construct and return a list of the basic and extended fields for a single-part message. The list suitable to be encoded into a BODY or BODYSTRUCTURE response. )rGrz _extendedr]extendedrus rCrNz"_SinglepartMessageStructure.encodess- ""$  MM$..* + rEcfg}|jjddddd}|j|jd|j|j |jd|j|jd|j|jd|S)aw The extension data of a non-multipart body part are in the following order: 1. body MD5 A string giving the body MD5 value as defined in [MD5]. 2. body disposition A parenthesized list with the same content and function as the body disposition for a multipart body part. 3. body language A string or parenthesized list giving the body language value as defined in [LANGUAGE-TAGS]. 4. body location A string list giving the body content URI as defined in [LOCATION]. Fz content-md5content-dispositioncontent-languagecontent-location)rrrrrr:r]rurs rCrIz%_SinglepartMessageStructure._extended~s2,,))   !      gkk-01 d'' 4I(JKL gkk"456 gkk"456 rEN) rrrrrEr`rGrNrIr?rErCr/r/@s# RH& 0 'rEr/ceZdZdZdZy)r.z_ L{_TextMessageStructure} represents the message structure of a I{text/*} message. ctj|}|jt|j|r|j |j |S)a A body type of type TEXT contains, immediately after the basic fields, the size of the body in text lines. Note that this size is the size in its content transfer encoding and not the resulting size after any decoding. )r/rGrrrrrzrIrJs rCrNz_TextMessageStructure.encodesD-99$? l4<<01  MM$..* + rENrrrrrNr?rErCr.r.s  rEr.ceZdZdZdZy)r-zi L{_RFC822MessageStructure} represents the message structure of a I{message/rfc822} message. ctj||}|jjd}|j t ||j t |d|j t||S)z A body type of type MESSAGE and subtype RFC822 contains, immediately after the basic fields, the envelope structure, body structure, and size in text lines of the encapsulated message. rF)r/rNrrrrrjrr)r]rKru containeds rCrNz_RFC822MessageStructure.encodese-33D(CLL++A.  k),- &y%89 l9-. rENrSr?rErCr-r-s  rEr-c(eZdZdZdZdZdZdZy)r,zi L{_MultipartMessageStructure} represents the message structure of a I{multipart/*} message. c@tj|||||_y)aR @param message: An L{IMessagePart} provider which this structure object reports on. @param subtype: A L{str} giving the MIME subtype of the message (for example, C{"plain"}). @param attrs: A C{dict} giving the parameters of the I{Content-Type} header of the message. N)r4r`r1)r]rr1r$s rCr`z#_MultipartMessageStructure.__init__s ""4%8 rEc#zKd} |jj|}||dz }&#t$rYywxYww)zR Return an iterator over all of the sub-messages of this message. rr<N)rrr)r]rhrs rC _getPartsz$_MultipartMessageStructure._getPartssQ  ||..q1 Q  s;, ; 8;8;c|jDcgc]}t|j|}}|j|j|r|j |j |Scc}w)zW Encode each sub-message and added the additional I{multipart} fields. )rZr2rNrrr1rzrI)r]rKrrus rCrNz!_MultipartMessageStructure.encodesbEINNDTUq&q)00:UU dll#  MM$..* + Vs!A4cfg}|jjdddd}|j|j|j|j |j d|j|j dd|j|j dd|S)af The extension data of a multipart body part are in the following order: 1. body parameter parenthesized list A parenthesized list of attribute/value pairs [e.g., ("foo" "bar" "baz" "rag") where "bar" is the value of "foo", and "rag" is the value of "baz"] as defined in [MIME-IMB]. 2. body disposition A parenthesized list, consisting of a disposition type string, followed by a parenthesized list of disposition attribute/value pairs as defined in [DISPOSITION]. 3. body language A string or parenthesized list giving the body language value as defined in [LANGUAGE-TAGS]. 4. body location A string list giving the body content URI as defined in [LOCATION]. FrNrOrMN)rrrrr>r:rrPs rCrIz$_MultipartMessageStructure._extendeds,,,)) %'9;P   d))+, d'' 4I(JKL gkk"4d;< gkk"4d;< rEN)rrrrr`rZrNrIr?rErCr,r,s   rEr,c6t|j|S)ar RFC 3501, 7.4.2, BODYSTRUCTURE:: A parenthesized list that describes the [MIME-IMB] body structure of a message. This is computed by the server by parsing the [MIME-IMB] header fields, defaulting various fields as necessary. For example, a simple text message of 48 lines and 2279 octets can have a body structure of: ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 2279 48) This is represented as:: ["TEXT", "PLAIN", ["CHARSET", "US-ASCII"], None, None, "7BIT", 2279, 48] These basic fields are documented in the RFC as: 1. body type A string giving the content media type name as defined in [MIME-IMB]. 2. body subtype A string giving the content subtype name as defined in [MIME-IMB]. 3. body parameter parenthesized list A parenthesized list of attribute/value pairs [e.g., ("foo" "bar" "baz" "rag") where "bar" is the value of "foo" and "rag" is the value of "baz"] as defined in [MIME-IMB]. 4. body id A string giving the content id as defined in [MIME-IMB]. 5. body description A string giving the content description as defined in [MIME-IMB]. 6. body encoding A string giving the content transfer encoding as defined in [MIME-IMB]. 7. body size A number giving the size of the body in octets. Note that this size is the size in its transfer encoding and not the resulting size after any decoding. Put another way, the body structure is a list of seven elements. The semantics of the elements of this list are: 1. Byte string giving the major MIME type 2. Byte string giving the minor MIME type 3. A list giving the Content-Type parameters of the message 4. A byte string giving the content identifier for the message part, or None if it has no content identifier. 5. A byte string giving the content description for the message part, or None if it has no content description. 6. A byte string giving the Content-Encoding of the message body 7. An integer giving the number of octets in the message body The RFC goes on:: Multiple parts are indicated by parenthesis nesting. Instead of a body type as the first element of the parenthesized list, there is a sequence of one or more nested body structures. The second element of the parenthesized list is the multipart subtype (mixed, digest, parallel, alternative, etc.). For example, a two part message consisting of a text and a BASE64-encoded text attachment can have a body structure of: (("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT" "PLAIN" ("CHARSET" "US-ASCII" "NAME" "cc.diff") "<960723163407.20117h@cac.washington.edu>" "Compiler diff" "BASE64" 4554 73) "MIXED") This is represented as:: [["TEXT", "PLAIN", ["CHARSET", "US-ASCII"], None, None, "7BIT", 1152, 23], ["TEXT", "PLAIN", ["CHARSET", "US-ASCII", "NAME", "cc.diff"], "<960723163407.20117h@cac.washington.edu>", "Compiler diff", "BASE64", 4554, 73], "MIXED"] In other words, a list of N + 1 elements, where N is the number of parts in the message. The first N elements are structures as defined by the previous section. The last element is the minor MIME subtype of the multipart message. Additionally, the RFC describes extension data:: Extension data follows the multipart subtype. Extension data is never returned with the BODY fetch, but can be returned with a BODYSTRUCTURE fetch. Extension data, if present, MUST be in the defined order. The C{extended} flag controls whether extension data might be returned with the normal data. )r2rN)rrKs rCrr sR  $ + +H 55rEc |jDcgc]C\}}dj|jdj|jfE}}}dj|dz}t |Scc}}w)Nz: z )rrtitler"r;)rrrrs rCrrssmmo  Q 1779fkk!,,.9:; D  ;;t v %D    sAA>c#bKd} |j||dz }#t$rYywxYwwr)rr)rrhs rCsubpartsrasB A ,,q/ ! FA    s/ ,/,/cbddlmtjfddS)a Consume an interator at most a single iteration per reactor iteration. If the iterator produces a Deferred, the next iteration will not occur until the Deferred fires, otherwise the next iteration will be taken in the next reactor iteration. @rtype: C{Deferred} @return: A deferred which fires (with None) when the iterator is exhausted or whose errback is called if there is an exception. rrc t}t|tjr|j yj d|y#t $rj|Yyt$rjYywxYwr) rarXrrrmrrdrrHrH)rcr rgorhrs rCrdziterateInReactor..gosm ,QA !U^^, b!!!!R+  JJt   IIK s AB*BBN)rrrr)rhrrdrs`@@@rCrrs') A ,tH HrEcHeZdZdZeej ZddZdZ dZ y)rNc||_|tj}||_|t}||_|jj |_y)a Produce this message. @param msg: The message I am to produce. @type msg: L{IMessage} @param buffer: A buffer to hold the message in. If None, I will use a L{tempfile.TemporaryFile}. @type buffer: file-like N)rrrrrrr)r]rrrs rCr`zMessageProducer.__init__sH >++-F  (I"[[&& rEcN||_|j|jSrt)consumerr_produce)r]ris rCrzMessageProducer.beginProducings  ~~dmmo..rEc#jKjjd}d}jjr|jd}|j dddDcgc]}|j dd}}|Dcic]$\}}|j j |&}}}|jd}|/djj}|dxxd|d z cc<n'|jd r|jd r|dd }t|}jt|jd jjr{tjD]K}jd |zd zt|j j"j%dMjd |zd znZjj'} | j)j*} | r j j| dnn?j,r_j j/ddt1j j%j,j3fdyycc}wcc}}ww)NTrrr<r!boundaryz----=z ; boundary="rr}r=s --s-- rcSrtr?rs rCrTz*MessageProducer._produce..s$rE)rrrrrYr6r_uuid4hexrrr;rrrarrrrrr@ CHUNK_SIZErirrrm) r]rrlrrSrNrrrrRr+s ` rCrjzMessageProducer._producesF((%%d+ 88   !kk.1G.5mmC.@.DEQWWS!_EEE8=>fq!QWWY__&)>E>yy,H"4;;=#4#4"56'\(1+EE'&&s+0A0A#0F'"~H$X.H >'*+ 7 88   !dhh'  9x/'9:%adnnETT  JJy8+i7 8$$&AFF4??+KK%%a(J  == KK  Q "t{{+::4==IUU  =F>sAJ3"J(;J3)J-+HJ3r) rrrrp staticmethoduuiduuid4rnr`rrjr?rErCrrs$J $** %F'(/'rErc eZdZGddZGddZGddZGddZGd d ZGd d ZGd dZ GddZ GddZ GddZ GddZ GddZGddZdZdefdefdefdefd efd!efd"e fd#e fd$e fg Zd%Zd&Zd'Zd(Zd)Zd*Zd+Zd,Zd-Zej8d.Zd/Zd0Zd1Z d2Z!d3Z"y)4rceZdZdZdZy)_FetchParser.Envelopercy)Nrr?rbs rCrTz_FetchParser.Envelope.rrENrrrrrr?rErCEnvelopervs)rEryceZdZdZdZy)_FetchParser.Flagsrcy)Nrr?rbs rCrTz_FetchParser.Flags.rrENrxr?rErCFlagsr{s &rEr}ceZdZdZdZy)_FetchParser.InternalDatercy)Nrr?rbs rCrTz"_FetchParser.InternalDate.rrENrxr?rErC InternalDaters -rErceZdZdZdZy)_FetchParser.RFC822Headerr(cy)Nrbr?rbs rCrTz"_FetchParser.RFC822Header. rrENrxr?rErC RFC822Headerrs .rErceZdZdZdZy)_FetchParser.RFC822Textr+cy)Nr`r?rbs rCrTz _FetchParser.RFC822Text.$rrENrxr?rErC RFC822Textr" ,rErceZdZdZdZy)_FetchParser.RFC822Sizer/cy)Nrar?rbs rCrTz _FetchParser.RFC822Size.(rrENrxr?rErC RFC822Sizer&rrErceZdZdZdZy)_FetchParser.RFC822r%cy)Nr%r?rbs rCrTz_FetchParser.RFC822.,rrENrxr?rErCRFC822r*s 'rErceZdZdZdZy)_FetchParser.UIDrfcy)Nrfr?rbs rCrTz_FetchParser.UID.0rrENrxr?rErCrr.s $rErcHeZdZdZdZdZdZdZdZdZ dZ dZ de fdZ defdZy)_FetchParser.BodyrFNr?rc@|jjdSNrTrrrbs rCrz_FetchParser.Body.__str__=>>#**73 3rEc .d}d}d}|jrFdj|jDcgc]}t|dzjd!c}}d}|jr4|d|z|zt|jjdzdzz }nM|j r|d|z|zdzz }n2|j r|d|z|zd zz }n|jr |d|zdzz }|j|d |j|jfzz }|Scc}w) Nr<rE.r<rTr4r[sTEXT]sMIME]s<%d.%d>) rrrrNrr6rr partialBegin partialLength)r]baser separatorrSs rCrz_FetchParser.Body.__bytes__@sDDIyyyydii!P#a!e*"3"3G".E.Eg.NNQUUt i/(::t i/(::t d**  , d&7&79K9K%LLLK!"Qs$D)rrrrrWrrr6rrrrrrrrr?rErCBodyr2sG   4S 4 u rErceZdZdZdZy)_FetchParser.BodyStructurer cy)Nr r?rbs rCrTz#_FetchParser.BodyStructure.YrrENrxr?rErC BodyStructurerWs .rErc0eZdZdZdZdZdefdZdefdZ y)_FetchParser.HeaderFNrc@|jjdSrrrbs rCrz_FetchParser.Header.__str__arrEcd}|jrz|dz }|jr|dz }g}|jD]9}|j}t|r t |}|j |;|ddj |zdzz }|jr@dj |jDcgc]}|dzjc}dz|z}|Scc}w) NsHEADERs.FIELDSs.NOTrrrrr<) rrr_rr|rrrrr)r]rrrRrSs rCrz_FetchParser.Header.__bytes__dsD{{ ";;GOD%A A"1~"1IMM!$ %  & 11D88yyyytyy!I!1q5"3"3"5!IJTQTXXK"Js.C) rrrrrrrrrrr?rErCHeaderr\s) 4S 4 u rErc eZdZy)_FetchParser.TextNrrrr?rErCTextrw rErc eZdZy)_FetchParser.MIMENrr?rErCMIMErzrrErNsenvelopesflagss internaldates rfc822.headers rfc822.texts rfc822.sizesrfc822suids bodystructurec0dg|_g|_d|_y)NinitialrE)r>ru remainingrbs rCr`z_FetchParser.__init__s[  rEcp|j|z} |s |jr\|js td|jj} t |d|z|}||d}|rO|jr\||_y#t $r|jj |wxYw#||_wxYw)NzInvalid Argumentstate_)rr>rrIrNrHrr)r]rr>useds rCrz_FetchParser.parseStrings NNQ  tzzzz/0BCC (!:74E)9:1=D $%AtzzDN%JJ%%e,DNs)?B,B&B,. B,&B))B,, B5c6|dk(ry|j}|jdrX|jj|j |j |j |jfy|jdrg|jj|j |j |j |j|jfy|jdrI|jj|j |j |j fy|jdr|jjd y |jjd y) NrErsallrUsfullrsfastr) close_parenmaybe_fetch_att fetch_attr<r) r6rrurzr}rrryrr>rr)r]rrs rC state_initialz_FetchParser.state_initials; 8 GGI <<  KK  t002DOO4Et}}W  << KK  JJL%%'OO%MMOIIK   << KK  JJL%%'OO%  <<  JJ  M N +&rEc<|jdrytd)Nrr<z Missing )rrPrs rCstate_close_parenz_FetchParser.state_close_parens <<  $$rEc|r|ddjs tdd}tt|D]}|||dzjr|S|S)Nrr<zWhitespace expected, none found)isspacerPrr)r]rrhs rCstate_whitespacez_FetchParser.state_whitespacesa!A(=> > s1v AQQ<'') rEc\|jds|jjdy)Nr)rrrrrr>rzrs rCstate_maybe_fetch_attz"_FetchParser.state_maybe_fetch_atts$||D! JJ  L MrEc|j}|jD]C\}}|j|s|jj |t |cS|j }|jdr d|_d}n"|jdrd}ntd|||_ |jjd|S)Ns body.peekTrtsbodyrz!Nothing recognized in fetch_att: )got_body maybe_partial maybe_section) r6_simple_fetch_attrrurrrrrWrP pending_bodyr>rz)r]rrr*clsr+rs rCstate_fetch_attz_FetchParser.state_fetch_atts GGI// !ID#||D! ""35)4y  ! IIK << %AFD \\' "D?sCD D HI rEcR|jj|j|`yr)rurrrrs rCstate_got_bodyz_FetchParser.state_got_bodys# 4,,-  rEc^|jdsy|jjdy)Nr4r)section part_numberr<rrs rCstate_maybe_sectionz _FetchParser.state_maybe_sections'||D! 45rEs(\d+(?:\.\d+)*)\.?c|jj|}|Q|jdjdDcgc]}t |dz c}|_|j Sg|_ycc}w)Nrrr<) _partExprrgroupsrYrrNr_)r]rrrs rCstate_part_numberz_FetchParser.state_part_number se NN  # =./hhjm.A.A$.GH#a&1*HDJ557NDJ IsA7c4|j}d}|jdrd|j_|dz }n1|jdr5|j x}|j_d|_d|_|dz }n|jdr%|j|j_ |d z }n|jd r%|j|j_ |d z }n|j }|jd r d|_|d z }n%|jd r|dz }ntd|||j_|jjdt|j |j_d|_|S)Nrr[Tr<sheader]r?rstext]rsmime]sheader.fields.nots header.fieldsr=zUnhandled section contents: )finish_section header_listr)r6rrrrrrrrr6rrrPr>rzrrNr)r]rrrrs rC state_sectionz_FetchParser.state_sectionsZ GGI << &*D   # AID \\* %+/;;= 8A!!(AHAH AID \\( #%)YY[D   " AID \\( #%)YY[D   " AID A||01 ./ ">qe DEE'(D   $ JJ  M N!&tzz!2  rEc<|jds tdy)Nr[zsection must end with ]r<rrs rCstate_finish_sectionz!_FetchParser.state_finish_section7s||D!56 6rEc$|jds td|jd}|dk(r td|d|j}|Dcgc]}|j c}|j j _|dzScc}w)NrzHeader list must begin with (rr}zHeader list must end with )r<)rrPrrYr[rrr)r]rr_rrs rCstate_header_listz_FetchParser.state_header_list<s||D!;< <ffTl "99: :Ac(..">E*F1779*F  'Qw+GsB c<|jdsy|jd}|dk(r td|d|}|jdd}t |dk7r td t t |\}}||j_||j_ |dzS) Nr=rr>r}zFound < but not >r<rrz>Partial specification did not include two .-delimited integers) rrrPrYrrkrrrr)r]rr_rprNbeginrYs rCstate_maybe_partialz _FetchParser.state_maybe_partialGs||D!ffTl "9/0 0Ac( dA& u:?P C v).&*0'QwrE)#rrrryr}rrrrrrrrrrrrNrr`rrrrrrrrrrrrrrrrr?rErCrrs8 * *''..//----((%%##J// 6     E h 5 ,' <( $ $ F  =)  &'R% 2  12I#J rErc8eZdZdZdZdZdZdZdZdZ dZ y ) rrfTc||_yrtr)r]rRs rCr`zFileProducer.__init__as rEc||_|j|_tjx}|_|jj |d|S)NF)rirproducerr_onDoneregisterProducer)r]rirs rCrzFileProducer.beginProducingds@  ~~  >>++DL &&tU3rEc|d}|jrd|jfz}d|_|jsy||jj|jz}|sK|j j |jj|dx|_x|_|_y|j|y)NrEs{%d} F) firstWrite_sizerRr@rpriunregisterProducerrrr)r]r+s rCresumeProducingzFileProducer.resumeProducingks  ??tzz|o-A#DOvv   DOO, , MM , , . LL ! !$ '48 8DL 846DM LLOrEcy)z9 Pause the producer. This does nothing. Nr?rbs rCpauseProducingzFileProducer.pauseProducingzrrEcy)z8 Stop the producer. This does nothing. Nr?rbs rC stopProducingzFileProducer.stopProducingrrEc|jj}|jjdd|jj}|jj|d||z S)Nrr)rRrr)r]r+rSs rCrzFileProducer._sizesM FFKKM  Aq FFKKM  Aq1u rEN) rrrrprr`rrrrrr?rErCrr\s*JJ   rErc gd}dddd}tjd|z|}|std||j} d|j |d j d zz|d <t |d |d <t |d |d <tj|d |d |d d d d dddf S#t$rtd|wxYw)N)janfebmaraprmayjunjulaugsepoctnovdecjanuaryfebruarymarchaprilrjunejulyaugust septemberoctobernovemberdecemberz+(?P3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])z (?P\w+)z(?P\d\d\d\d))daymonyearz%(day)s-%(mon)s-%(year)szCannot parse time string r<r rrrr}) rrre groupdictindexr6rrx struct_time)rmonthsexprrrs rCrrsF6>% D +d2A6A 4QE:;; AV QuX^^%56;<%& N& qx=%6AeHah1aRQS TUU <4QE:;;r-rAr.rr/rr0rBr1r2rtwisted.protocolsr3r4twisted.pythonr5r6twisted.python.compatr7r8r9r:r;r#rrrYrzrDrJrLrrrr_SPr_CTLr r_nativeNonAtomCharsrrr LineReceiver TimeoutMixinr TimeoutErrorrPr)rrrrnrrrrrrrrrr|rrjrrr&rrrrrr r rrjrrr)r2r4r/r.r-r,rrrarrrrrrNr-r,rrr*r.r0r8 CodecInfor=r<register__all__r?rErCr\s    +""&$F550(    .$a GMMOP *(aaH 998//B0D"D"V  U5;dE 2 34$t+ $**95 RZZ11C7 8 He H H  TN%$$h&;&;TNTNn8#""$  P%$$h&;&;PPf<6r "* Nb 1 &>B  D7,tE ''%' +/. b XoJoJoJd !2"&"#  M4 ,J4//de"3eP7(9*L!2L^i6X  BCCLRRj --`,Vdj&/: , " D D6&& 6&& V  gw l K   / rE