JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrJFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3RbrB  fE@sdZddddgZddlZddlZdZdZd Zd d d d dddddddddddddddddddd gZd!d"d#d$d%d&d'gZddddd(d)d*d(d+d*d,d+d-d,d.Z d/dZ d0d1Z d2dZ d3dZ d4dZGd5d6d6ZGd7d8d8eZdS)9zcEmail address parsing code. Lifted directly from rfc822.py. This should eventually be rewritten. mktime_tz parsedate parsedate_tzquoteN z, ZjanZfebZmarZaprZmayZjunZjulZaugsepoctZnovZdecZjanuaryZfebruaryZmarchZaprilZjuneZjulyZaugustZ septemberZoctoberZnovemberZdecemberZmonZtueZwedZthuZfriZsatZsunipii iiDi)ZUTZUTCZGMTZZASTZADTZESTZEDTZCSTZCDTZMSTZMDTZPSTZPDTcCs,t|}|sdS|ddkr$d|d<t|S)zQConvert a date string to a time tuple. Accounts for military timezones. N r) _parsedate_tztuple)dataZresr5/opt/alt/python37/lib64/python3.7/email/_parseaddr.pyr-s  c Cs|sdS|}|sdS|dds6|dtkr>|d=n.|dd}|dkrl|d|dd|d<t|dkr|dd}t|dkr||dd}t|dkr|d}|d}|d kr|d}|dkr|d|||dg|dd<n |d t|d krdS|dd }|\}}}}}|}|tkrb||}}|tkrbdSt |d}|d kr|d 8}|d dkr|dd }|d }|dkr||}}|d dkr|dd }|d s||}}|d dkr|dd }|d }t|dkr,|\} } d} n~t|dkrF|\} } } ndt|dkrd|dkr|dd}t|dkr|\} } d} nt|dkr|\} } } ndSy,t |}t |}t | } t | } t | } Wnt k rdSX|dkr|dkr |d7}n|d7}d} | }|tkr4t|} n>y t |} Wnt k rVYnX| dkrr|drrd} | r| dkrd } | } nd} | | dd| dd} |||| | | ddd | g S)aConvert date to extended time tuple. The last (additional) element is the time zone offset in seconds, except if the timezone was specified as -0000. In that case the last element is None. This indicates a UTC timestamp that explicitly declaims knowledge of the source timezone, as opposed to a +0000 timestamp that indicates the source timezone really was UTC. Nr,-+r :0.dDilii<)splitendswithlower _daynamesrfindlenfindappend _monthnamesindexisdigitint ValueErrorupper _timezones startswith)riZstuffsZddZmmZyyZtmZtzZthhZtmmZtssZtzoffsetZtzsignrrrr 9s     "                       r cCs&t|}t|tr|ddS|SdS)z&Convert a time string to a time tuple.Nr )r isinstancer )rtrrrrs  cCs<|ddkr"t|dddSt|}||dSdS)zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r N)r)timeZmktimecalendarZtimegm)rr4rrrrs  cCs|ddddS)zPrepare string to be used in a quoted string. Turns backslash and double quote characters into quoted pairs. These are the only characters that need to be quoted inside a quoted string. Does not add the surrounding double quotes. \z\\"z\")replace)strrrrrsc@s|eZdZdZddZddZddZdd Zd d Zd d Z ddZ dddZ ddZ ddZ ddZdddZddZdS) AddrlistClassaAddress parser class by Ben Escoto. To understand what this class does, it helps to have a copy of RFC 2822 in front of you. Note: this class interface is deprecated and may be removed in the future. Use email.utils.AddressList instead. cCsZd|_d|_d|_d|_|j|j|_|j|j|j|_|jdd|_||_g|_ dS)zInitialize a new instance. `field' is an unparsed address header field, containing one or more addresses. z ()<>@,:;."[]rz z rrN) specialsposLWSZCRFWSatomendsr: phraseendsfield commentlist)selfrCrrr__init__szAddrlistClass.__init__cCsg}x|jt|jkr|j|j|jdkr^|j|jdkrN||j|j|jd7_q|j|jdkr|j|qPqWt|S)z&Skip white space and extract comments.z r() r>r&rCr?r(rD getcomment EMPTYSTRINGjoin)rEZwslistrrrgotonextszAddrlistClass.gotonextcCs>g}x4|jt|jkr8|}|r,||7}q|dqW|S)zVParse all addresses. Returns a list containing all of the addresses. )rr)r>r&rC getaddressr()rEresultZadrrr getaddrlists zAddrlistClass.getaddrlistcCsg|_||j}|j}|}|g}|jt|jkr\|rXt|j|dfg}n^|j|jdkr||_||_|}t|j|fg}n$|j|jdkr g}t|j}|jd7_x|jt|jkr||j|kr|j|jdkr|jd7_P|| }qWn|j|jdkrz| }|jrht|dd|jd |fg}nt||fg}n@|rt|j|dfg}n"|j|j|j kr|jd7_||jt|jkr|j|jd kr|jd7_|S) zParse the next address.rz.@rr; getphraselistr&rCSPACErJ getaddrspecrL getrouteaddrr=)rEZoldposZoldclplistZ returnlistZaddrspecZfieldlenZ routeaddrrrrrLsL &$zAddrlistClass.getaddresscCs|j|jdkrdSd}|jd7_|d}x|jt|jkr|rV|d}n~|j|jdkrx|jd7_Pn\|j|jdkr|jd7_d}n8|j|jd kr|jd7_n|}|jd7_P|q4W|S) zParse a route address (Return-path value). This method just skips all the route stuff and returns the addrspec. rPNFrr>@Tr)rCr>rKr& getdomainrT)rEZ expectrouteZadlistrrrrUAs. zAddrlistClass.getrouteaddrcCsXg}|x|jt|jkrd}|j|jdkrh|rJ|dsJ||d|jd7_d}nd|j|jdkr|dt|n<|j|j|j kr|r|ds|Pn|| |}|r|r||qW|jt|jks|j|jdkrt |S|d|jd7_|| }|sJt St ||S) zParse an RFC 2822 addr-spec.TrrrFr9z"%s"rX)rKr>r&rCstrippopr(rgetquoterAgetatomrIrJrY)rEZaslistZ preserve_wsZwsZdomainrrrrTas: $  zAddrlistClass.getaddrspeccCsg}x|jt|jkr|j|j|jkr8|jd7_q|j|jdkrZ|j|q|j|jdkrz||q|j|jdkr|jd7_|dq|j|jdkrtS|j|j|j krPq|| qWt |S)z-Get the complete domain name from an address.rrG[rrX) r>r&rCr?rDr(rHgetdomainliteralrIrAr]rJ)rEZsdlistrrrrYs" zAddrlistClass.getdomainTcCs|j|j|krdSdg}d}|jd7_x|jt|jkr|rZ||j|jd}np|j|j|kr||jd7_PnN|r|j|jdkr||q.n(|j|jdkrd}n||j|j|jd7_q.Wt|S)aParse a header fragment delimited by special characters. `beginchar' is the start character for the fragment. If self is not looking at an instance of `beginchar' then getdelimited returns the empty string. `endchars' is a sequence of allowable end-delimiting characters. Parsing stops when one of these is encountered. If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed within the parsed fragment. rFrrGr8T)rCr>r&r(rHrIrJ)rEZ begincharZendcharsZ allowcommentsZslistrrrr getdelimiteds( zAddrlistClass.getdelimitedcCs|dddS)z1Get a quote-delimited fragment from self's field.r9z" F)r`)rErrrr\szAddrlistClass.getquotecCs|dddS)z7Get a parenthesis-delimited fragment from self's field.rGz) T)r`)rErrrrHszAddrlistClass.getcommentcCsd|dddS)z!Parse an RFC 2822 domain-literal.z[%s]r^z] F)r`)rErrrr_szAddrlistClass.getdomainliteralNcCshdg}|dkr|j}xH|jt|jkr\|j|j|kr:Pn||j|j|jd7_qWt|S)aParse an RFC 2822 atom. Optional atomends specifies a different set of end token delimiters (the default is to use self.atomends). This is used e.g. in getphraselist() since phrase endings must not include the `.' (which is legal in phrases).rNr)rAr>r&rCr(rIrJ)rErAZatomlistrrrr]szAddrlistClass.getatomcCsg}x|jt|jkr|j|j|jkr8|jd7_q|j|jdkrX||q|j|jdkrz|j|q|j|j|jkrPq|| |jqW|S)zParse a sequence of RFC 2822 phrases. A phrase is a sequence of words, which are in turn either RFC 2822 atoms or quoted-strings. Phrases are canonicalized by squeezing all runs of continuous whitespace into one space. rr9rG) r>r&rCr@r(r\rDrHrBr])rErVrrrrRszAddrlistClass.getphraselist)T)N)__name__ __module__ __qualname____doc__rFrKrNrLrUrTrYr`r\rHr_r]rRrrrrr<s; & % r<c@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) AddressListz@An AddressList encapsulates a list of parsed RFC 2822 addresses.cCs&t|||r||_ng|_dS)N)r<rFrN addresslist)rErCrrrrFs  zAddressList.__init__cCs t|jS)N)r&rf)rErrr__len__szAddressList.__len__cCsBtd}|jdd|_x$|jD]}||jkr |j|q W|S)N)rerfr()rEothernewaddrxrrr__add__s   zAddressList.__add__cCs*x$|jD]}||jkr|j|qW|S)N)rfr()rErhrjrrr__iadd__s  zAddressList.__iadd__cCs2td}x$|jD]}||jkr|j|qW|S)N)rerfr()rErhrirjrrr__sub__s   zAddressList.__sub__cCs*x$|jD]}||jkr|j|qW|S)N)rfremove)rErhrjrrr__isub__s  zAddressList.__isub__cCs |j|S)N)rf)rEr*rrr __getitem__%szAddressList.__getitem__N) rarbrcrdrFrgrkrlrmrorprrrrres re)rd__all__r6r7rSrIZ COMMASPACEr)r$r/rr rrrr<rerrrrs8   w   /