qyMaCNc@s,dZddlmZddlmZddlmZGdddZGdddZGd d d eZ d d Z Gd ddZ Gddde Z GdddZ Gddde ZGdddZGdddeZGdddeZGdddeZGdddZGdd d ZGd!d"d"eZGd#d$d$eZGd%d&d&Zie d'6ed(6e d)6ed*6ed+6ed,6ed-6ed.6ed/6ed06ed16ed26ed36ed46ed56ed66ed76ed86ed96ZGd:d;d;Zd<S(=u;Representing and manipulating email headers via custom objects. This module provides an implementation of the HeaderRegistry API. The implementation is designed to flexibly follow RFC5322 rules. Eventually HeaderRegistry will be a public API, but it isn't yet, and will probably change some before that happens. i(uutils(uerrors(u_header_value_parsercBs|EeZdZddddddZeddZeddZedd Zed d Z d d Z ddZ ddZ dS(uAddressucCs|dk r|s|r'tdntj|\}}|r]tdj||n|jrv|jdn|j}|j}n||_ ||_ ||_ dS(uCreate an object represeting a full email address. An address can have a 'display_name', a 'username', and a 'domain'. In addition to specifying the username and domain separately, they may be specified together by using the addr_spec keyword *instead of* the username and domain keywords. If an addr_spec string is specified it must be properly quoted according to RFC 5322 rules; an error will be raised if it is not. An Address object has display_name, username, domain, and addr_spec attributes, all of which are read-only. The addr_spec and the string value of the object are both quoted according to RFC5322 rules, but without any Content Transfer Encoding. u=addrspec specified when username and/or domain also specifiedu6Invalid addr_spec; only '{}' could be parsed from '{}'iN( uNoneu TypeErroruparseru get_addr_specu ValueErroruformatu all_defectsu local_partudomainu _display_nameu _usernameu_domain(uselfu display_nameuusernameudomainu addr_specua_surest((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__init__s        uAddress.__init__cCs|jS(N(u _display_name(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu display_name6suAddress.display_namecCs|jS(N(u _username(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuusername:suAddress.usernamecCs|jS(N(u_domain(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyudomain>suAddress.domaincCsrt|j}t|t|tjkrCtj|j}n |j}|jrd|d|jS|sndS|S(uThe addr_spec (username@domain) portion of the address, quoted according to RFC 5322 rules, but with no Content Transfer Encoding. u@u<>(usetuusernameulenuparseru DOT_ATOM_ENDSu quote_stringudomain(uselfunamesetulp((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu addr_specBs  uAddress.addr_speccCsdj|j|j|jS(Nu6Address(display_name={!r}, username={!r}, domain={!r})(uformatu display_nameuusernameudomain(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__repr__RsuAddress.__repr__cCst|j}t|t|tjkrCtj|j}n |j}|r|jdkrgdn|j}dj||S|jS(Nu<>uu{} <{}>(usetu display_nameulenuparseruSPECIALSu quote_stringu addr_specuformat(uselfunamesetudispu addr_spec((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__str__Vs uAddress.__str__cCsPt|t|krdS|j|jkoO|j|jkoO|j|jkS(NF(utypeuFalseu display_nameuusernameudomain(uselfuother((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__eq__as uAddress.__eq__N( u__name__u __module__u __qualname__uNoneu__init__upropertyu display_nameuusernameudomainu addr_specu__repr__u__str__u__eq__(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuAddresss%  uAddresscBsn|EeZdZd d ddZeddZeddZddZd d Z d d Z d S(uGroupcCs+||_|rt|nt|_dS(uCreate an object representing an address group. An address group consists of a display_name followed by colon and an list of addresses (see Address) terminated by a semi-colon. The Group is created by specifying a display_name and a possibly empty list of Address objects. A Group can also be used to represent a single address that is not in a group, which is convenient when manipulating lists that are a combination of Groups and individual Addresses. In this case the display_name should be set to None. In particular, the string representation of a Group whose display_name is None is the same as the Address object, if there is one and only one Address object in the addresses list. N(u _display_nameutupleu _addresses(uselfu display_nameu addresses((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__init__ks uGroup.__init__cCs|jS(N(u _display_name(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu display_name}suGroup.display_namecCs|jS(N(u _addresses(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu addressessuGroup.addressescCsdj|j|jS(Nu'Group(display_name={!r}, addresses={!r}(uformatu display_nameu addresses(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__repr__suGroup.__repr__cCs|jdkr5t|jdkr5t|jdS|j}|dk rt|}t|t|tjkrtj|}qndj dd|jD}|rd|n|}dj ||S(Niiu, css|]}t|VqdS(N(ustr(u.0ux((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu su Group.__str__..u u{}:{};( u display_nameuNoneulenu addressesustrusetuparseruSPECIALSu quote_stringujoinuformat(uselfudispunamesetuadrstr((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__str__s$   u Group.__str__cCs>t|t|krdS|j|jko=|j|jkS(NF(utypeuFalseu display_nameu addresses(uselfuother((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__eq__su Group.__eq__N( u__name__u __module__u __qualname__uNoneu__init__upropertyu display_nameu addressesu__repr__u__str__u__eq__(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuGroupis   uGroupcBs|EeZdZdZddZddZeddZedd Zd d Z e d d Z ddZ dS(u BaseHeaderu|Base class for message headers. Implements generic behavior and provides tools for subclasses. A subclass must define a classmethod named 'parse' that takes an unfolded value string and a dictionary as its arguments. The dictionary will contain one key, 'defects', initialized to an empty list. After the call the dictionary must contain two additional keys: parse_tree, set to the parse tree obtained from parsing the header, and 'decoded', set to the string value of the idealized representation of the data from the value. (That is, encoded words are decoded, and values that have canonical representations are so represented.) The defects key is intended to collect parsing defects, which the message parser will subsequently dispose of as appropriate. The parser should not, insofar as practical, raise any errors. Defects should be added to the list instead. The standard header parsers register defects for RFC compliance issues, for obsolete RFC syntax, and for unrecoverable parsing errors. The parse method may add additional keys to the dictionary. In this case the subclass must define an 'init' method, which will be passed the dictionary as its keyword arguments. The method should use (usually by setting them as the value of similarly named attributes) and remove all the extra keys added by its parse method, and then use super to call its parent class with the remaining arguments and keywords. The subclass should also make sure that a 'max_count' attribute is defined that is either None or 1. XXX: need to better define this API. cCs{igd6}|j||tj|drJtj|d|dRs u'AddressHeader.parse..u__iter__cSs7g|]-}t|ds-td|gn|qS(u addressesN(uhasattruGroupuNone(u.0uitem((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu [s ugroupsudefectsu, cSsg|]}t|qS((ustr(u.0uitem((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu as udecoded( u isinstanceustru value_parseru addressesuappenduGroupu display_nameu all_mailboxesulistu all_defectsuhasattrujoin(uclsuvalueukwdsu address_listugroupsuaddrudefects((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuparseIs$        uAddressHeader.parsecs8t|jd|_d|_tj||dS(Nugroups(utupleupopu_groupsuNoneu _addressesusuperuinit(uselfuargsukw(u __class__(u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuinites uAddressHeader.initcCs|jS(N(u_groups(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyugroupsjsuAddressHeader.groupscCs8|jdkr1tdd|jD|_n|jS(NcSs&g|]}|jD] }|qqS((u addresses(u.0ugroupuaddress((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu qs u+AddressHeader.addresses..(u _addressesuNoneutupleu_groups(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu addressesns"uAddressHeader.addressesN( u__name__u __module__u __qualname__uNoneu max_countu staticmethodu value_parseru classmethoduparseuinitupropertyugroupsu addresses(u __locals__((u __class__u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu AddressHeader?s u AddressHeadercBs|EeZdZdZdS(uUniqueAddressHeaderiN(u__name__u __module__u __qualname__u max_count(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuUniqueAddressHeadervsuUniqueAddressHeadercBs&|EeZdZeddZdS(uSingleAddressHeadercCs;t|jdkr0tdj|jn|jdS(Niu9value of single address header {} is not a single addressi(ulenu addressesu ValueErroruformatuname(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuaddress}s uSingleAddressHeader.addressN(u__name__u __module__u __qualname__upropertyuaddress(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuSingleAddressHeader{suSingleAddressHeadercBs|EeZdZdZdS(uUniqueSingleAddressHeaderiN(u__name__u __module__u __qualname__u max_count(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuUniqueSingleAddressHeadersuUniqueSingleAddressHeadercs|EeZdZdZeejZeddZ fddZ e ddZ e dd Z e d d ZS( uMIMEVersionHeadericCs|j||d<}t||d<|dj|j|jdkrPdn|j|d<|j|d<|jdk rdj|d|d|ds u1ParameterizedMIMEHeader.parse..(u value_parserustruextendu all_defectsuparamsuNone(uclsuvalueukwdsu parse_tree((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuparses  uParameterizedMIMEHeader.parsecs)|jd|_tj||dS(Nuparams(upopu_paramsusuperuinit(uselfuargsukw(u __class__(u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuinitsuParameterizedMIMEHeader.initcCs |jjS(N(u_paramsucopy(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuparamssuParameterizedMIMEHeader.params( u__name__u __module__u __qualname__u max_countu classmethoduparseuinitupropertyuparams(u __locals__((u __class__u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuParameterizedMIMEHeaders uParameterizedMIMEHeadercsk|EeZdZeejZfddZeddZ eddZ eddZ S( uContentTypeHeadercsGtj||tj|jj|_tj|jj|_dS(N( usuperuinituutilsu _sanitizeu _parse_treeumaintypeu _maintypeusubtypeu_subtype(uselfuargsukw(u __class__(u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuinitsuContentTypeHeader.initcCs|jS(N(u _maintype(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyumaintypesuContentTypeHeader.maintypecCs|jS(N(u_subtype(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyusubtypesuContentTypeHeader.subtypecCs|jd|jS(Nu/(umaintypeusubtype(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu content_typesuContentTypeHeader.content_type( u__name__u __module__u __qualname__u staticmethoduparseruparse_content_type_headeru value_parseruinitupropertyumaintypeusubtypeu content_type(u __locals__((u __class__u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuContentTypeHeaders uContentTypeHeadercsG|EeZdZeejZfddZeddZ S(uContentDispositionHeadercsGtj|||jj}|dkr1|n tj||_dS(N(usuperuinitu _parse_treeucontent_dispositionuNoneuutilsu _sanitizeu_content_disposition(uselfuargsukwucd(u __class__(u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuinits uContentDispositionHeader.initcCs|jS(N(u_content_disposition(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyucontent_dispositionsu,ContentDispositionHeader.content_disposition( u__name__u __module__u __qualname__u staticmethoduparseru parse_content_disposition_headeru value_parseruinitupropertyucontent_disposition(u __locals__((u __class__u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuContentDispositionHeadersuContentDispositionHeadercs_|EeZdZdZeejZeddZ fddZ e ddZ S(uContentTransferEncodingHeadericCs?|j||d<}t||d<|dj|jdS(Nu parse_treeudecodedudefects(u value_parserustruextendu all_defects(uclsuvalueukwdsu parse_tree((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuparsesu#ContentTransferEncodingHeader.parsecs/tj||tj|jj|_dS(N(usuperuinituutilsu _sanitizeu _parse_treeucteu_cte(uselfuargsukw(u __class__(u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuinitsu"ContentTransferEncodingHeader.initcCs|jS(N(u_cte(uself((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuctesu!ContentTransferEncodingHeader.cte( u__name__u __module__u __qualname__u max_countu staticmethoduparseru&parse_content_transfer_encoding_headeru value_parseru classmethoduparseuinitupropertyucte(u __locals__((u __class__u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuContentTransferEncodingHeaders uContentTransferEncodingHeaderusubjectudateu resent-dateu orig-dateusenderu resent-senderutou resent-touccu resent-ccubccu resent-bccufromu resent-fromureply-tou mime-versionu content-typeucontent-dispositionucontent-transfer-encodingcBsS|EeZdZdZeed ddZddZddZ dd Z d S( uHeaderRegistryu%A header_factory and header registry.cCs8i|_||_||_|r4|jjtndS(uCreate a header_factory that works with the Policy API. base_class is the class that will be the last class in the created header class's __bases__ list. default_class is the class that will be used if "name" (see __call__) does not appear in the registry. use_default_map controls whether or not the default mapping of names to specialized classes is copied in to the registry when the factory is created. The default is True. N(uregistryu base_classu default_classuupdateu_default_header_map(uselfu base_classu default_classuuse_default_map((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__init__!s   uHeaderRegistry.__init__cCs||j|j|jj|j|j}td|j||jfiS(Nu_(uregistryugetuloweru default_classutypeu__name__u base_class(uselfunameucls((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu __getitem__9suHeaderRegistry.__getitem__cCs||||S(uCreate a header instance for header 'name' from 'value'. Creates a header instance by creating a specialized class for parsing and representing the specified header by combining the factory base_class with a specialized class from the registry or the default_class, and passing the name and value to the constructed class's constructor. ((uselfunameuvalue((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu__call__=s uHeaderRegistry.__call__NT( u__name__u __module__u __qualname__u__doc__u BaseHeaderuUnstructuredHeaderuTrueu__init__u map_to_typeu __getitem__u__call__(u __locals__((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyuHeaderRegistrys   uHeaderRegistryN(u__doc__uemailuutilsuerrorsu_header_value_parseruparseruAddressuGroupustru BaseHeaderu_reconstruct_headeruUnstructuredHeaderuUniqueUnstructuredHeaderu DateHeaderuUniqueDateHeaderu AddressHeaderuUniqueAddressHeaderuSingleAddressHeaderuUniqueSingleAddressHeaderuMIMEVersionHeaderuParameterizedMIMEHeaderuContentTypeHeaderuContentDispositionHeaderuContentTransferEncodingHeaderu_default_header_mapuHeaderRegistry(((u9/opt/alt/python33/lib64/python3.3/email/headerregistry.pyu sRZ5a  '7 %