
v^=A                 @   sK  d  d l  Z  d  d l m Z m Z m Z m Z d  d l m	 Z	 d  d l
 m Z d  d l m Z m Z d  d l m Z d  d l m Z d  d l m Z d  d	 l m Z d  d
 l m Z d  d l m Z m Z m Z d  d l m Z m Z d  d l  m! Z! d  d l" m# Z# d  d l$ m% Z% d  d l& m' Z' m( Z( e j d  Z) d e) _* e j d  Z+ e j, e+ _* d Z- d Z. Gd d   d e/  Z0 d d d d d d d d d d d  h Z1 d! d"   Z2 d# d$   Z3 Gd% d&   d&  Z4 Gd' d(   d( e4 e  Z5 Gd) d*   d* e4 e  Z6 Gd+ d,   d, e4 e  Z7 Gd- d.   d.  Z8 Gd/ d0   d0 e8  Z9 d S)1    N)charsetencoders	generatormessage_from_string)HeaderParseError)Header)Addressparser)Message)MIMEBase)MIMEMessage)MIMEMultipart)MIMEText)
formatdategetaddresses
make_msgid)BytesIOStringIO)Path)settings)DNS_NAME)	force_strpunycodezutf-8zapplication/octet-streami  c               @   s   e  Z d  Z d S)BadHeaderErrorN)__name__
__module____qualname__ r   r   :/tmp/pip-build-8lau8j11/django/django/core/mail/message.pyr   #   s   r   fromZsenderzreply-totoccbcczresent-fromzresent-senderz	resent-toz	resent-ccz
resent-bccc                s     p t  j   t |  } d | k s3 d | k rI t d | |  f   y | j d  Wng t k
 r |  j   t k r d j   f d d   t	 | f  D  } n t
 |    j   } Yn% X|  j   d k r t
 |  j   } |  | f S)	z6Forbid multi-line headers to prevent header injection.
z;Header values can't contain newlines (got %r for header %r)asciiz, c             3   s   |  ] } t  |    Vq d  S)N)sanitize_address).0addr)encodingr   r   	<genexpr>A   s    z,forbid_multi_line_headers.<locals>.<genexpr>subject)r   DEFAULT_CHARSETstrr   encodeUnicodeEncodeErrorlowerADDRESS_HEADERSjoinr   r   )namevalr)   r   )r)   r   forbid_multi_line_headers7   s    .r5   c       	      C   sP  d } t  |  t  s t |   }  y t j |   \ } } Wn+ t t t f k
 rg t d |    Yq X| r t d | |  f   | j p d } | j	 } | j
 p d } n$ |  \ } } | j d d  \ } } t | |  j   } y | j d  Wn' t k
 r!t | |  j   } Yn Xt |  } t | d | d	 | } t |  S)
zF
    Format a pair of (name, address) or an email address string.
    NzInvalid address "%s"z2Invalid address; only %s could be parsed from "%s" @   r%   usernamedomain)
isinstancetupler   r	   Zget_mailboxr   
ValueError
IndexErrorZdisplay_nameZ
local_partr:   rsplitr   r.   r/   r   r   r-   )	r(   r)   addresstokenrestnmZ	localpartr:   Zparsed_addressr   r   r   r&   J   s0    	r&   c               @   s4   e  Z d  Z d d d d  Z d d d d  Z d S)	MIMEMixinFr#   c             C   sA   t    } t j | d d } | j |  d | d | | j   S)a&  Return the entire formatted message as a string.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This overrides the default as_string() implementation to not mangle
        lines that begin with 'From '. See bug #13433 for details.
        mangle_from_Funixfromlinesep)r   r   	Generatorflattengetvalue)selfrF   rG   fpgr   r   r   	as_stringp   s    	zMIMEMixin.as_stringc             C   sA   t    } t j | d d } | j |  d | d | | j   S)a"  Return the entire formatted message as bytes.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This overrides the default as_bytes() implementation to not mangle
        lines that begin with 'From '. See bug #13433 for details.
        rE   FrF   rG   )r   r   BytesGeneratorrI   rJ   )rK   rF   rG   rL   rM   r   r   r   as_bytes}   s    	zMIMEMixin.as_bytesN)r   r   r   rN   rP   r   r   r   r   rD   o   s   rD   c               @   s   e  Z d  Z d d   Z d S)SafeMIMEMessagec             C   s/   t  | | d  \ } } t j |  | |  d  S)Nr%   )r5   r   __setitem__)rK   r3   r4   r   r   r   rR      s    zSafeMIMEMessage.__setitem__N)r   r   r   rR   r   r   r   r   rQ      s   rQ   c               @   s=   e  Z d  Z d d d d  Z d d   Z d d d  Z d S)	SafeMIMETextplainNc             C   s)   | |  _  t j |  | d | d | d  S)N_subtype_charset)r)   r   __init__)rK   Z_textrU   rV   r   r   r   rW      s    	zSafeMIMEText.__init__c             C   s2   t  | | |  j  \ } } t j |  | |  d  S)N)r5   r)   r   rR   )rK   r3   r4   r   r   r   rR      s    zSafeMIMEText.__setitem__c             C   sj   | d k rP t  | t j  rP t d d   | j   D  } | rJ t n t } t j |  | d | d  S)Nzutf-8c             s   s'   |  ] } t  | j    t k Vq d  S)N)lenr.   RFC5322_EMAIL_LINE_LENGTH_LIMIT)r'   lr   r   r   r*      s   z+SafeMIMEText.set_payload.<locals>.<genexpr>r   )r;   Charsetany
splitlinesutf8_charset_qputf8_charsetr   set_payload)rK   payloadr   Zhas_long_linesr   r   r   r`      s    	zSafeMIMEText.set_payload)r   r   r   rW   rR   r`   r   r   r   r   rS      s   rS   c               @   s4   e  Z d  Z d d d d d d  Z d d   Z d S)SafeMIMEMultipartmixedNc             K   s&   | |  _  t j |  | | | |  d  S)N)r)   r   rW   )rK   rU   boundaryZ	_subpartsr)   _paramsr   r   r   rW      s    	zSafeMIMEMultipart.__init__c             C   s2   t  | | |  j  \ } } t j |  | |  d  S)N)r5   r)   r   rR   )rK   r3   r4   r   r   r   rR      s    zSafeMIMEMultipart.__setitem__)r   r   r   rW   rR   r   r   r   r   rb      s   rb   c               @   s   e  Z d  Z d Z d Z d Z d Z d d d d d d d d d d d d 
 Z d d	 d
  Z d d   Z	 d d   Z
 d d d  Z d d d d d  Z d d d  Z d d   Z d d   Z d d   Z d d d  Z d d   Z d S)EmailMessagez"A container for email information.rT   rc   Nr6   c             C   s  | r3 t  | t  r! t d   t |  |  _ n	 g  |  _ |	 ro t  |	 t  r] t d   t |	  |  _ n	 g  |  _ | r t  | t  r t d   t |  |  _ n	 g  |  _ |
 r t  |
 t  r t d   t |
  |  _ n	 g  |  _ | p t j	 |  _
 | |  _ | pd |  _ g  |  _ | rfx: | D]2 } t  | t  rU|  j |  q0|  j |   q0W| poi  |  _ | |  _ d S)zg
        Initialize a single email message (which can be sent to multiple
        recipients).
        z%"to" argument must be a list or tuplez%"cc" argument must be a list or tuplez&"bcc" argument must be a list or tuplez+"reply_to" argument must be a list or tupler6   N)r;   r-   	TypeErrorlistr    r!   r"   reply_tor   ZDEFAULT_FROM_EMAIL
from_emailr+   bodyattachmentsr   attachextra_headers
connection)rK   r+   rk   rj   r    r"   ro   rl   headersr!   ri   
attachmentr   r   r   rW      s>    						zEmailMessage.__init__Fc             C   s2   d d l  m } |  j s+ | d |  |  _ |  j S)Nr   )get_connectionfail_silently)Zdjango.core.mailrr   ro   )rK   rs   rr   r   r   r   rr      s    	zEmailMessage.get_connectionc             C   s;  |  j  p t j } t |  j |  j |  } |  j |  } |  j | d <|  j j	 d |  j
  | d <|  j | d |  j  |  j | d |  j  |  j | d |  j  d d   |  j D } d | k r t d	 t j  | d
 <d | k r t d t  | d <x9 |  j j   D]( \ } } | j   d k r| | | <qW| S)NSubjectFromToCczReply-Toc             S   s   g  |  ] } | j     q Sr   )r0   )r'   keyr   r   r   
<listcomp>   s   	 z(EmailMessage.message.<locals>.<listcomp>date	localtimeDatez
message-idr:   z
Message-IDr   )r)   r   r,   rS   rk   content_subtype_create_messager+   rn   getrj   _set_list_header_if_not_emptyr    r!   ri   r   ZEMAIL_USE_LOCALTIMEr   r   itemsr0   )rK   r)   msgheader_namesr3   valuer   r   r   message   s"    zEmailMessage.messagec             C   s"   d d   |  j  |  j |  j D S)z
        Return a list of all recipients of the email (includes direct
        addressees as well as Cc and Bcc entries).
        c             S   s   g  |  ] } | r |  q Sr   r   )r'   emailr   r   r   ry     s   	 z+EmailMessage.recipients.<locals>.<listcomp>)r    r!   r"   )rK   r   r   r   
recipients  s    zEmailMessage.recipientsc             C   s)   |  j    s d S|  j |  j |  g  S)zSend the email message.r   )r   rr   Zsend_messages)rK   rs   r   r   r   send  s    zEmailMessage.sendc             C   s   t  | t  rF | d k s! t  | d k s3 t  |  j j |  n | d k	 sX t  | pt t j |  d pt t } | j d d  \ } } | d k r t  | t	  r y | j
   } Wn t k
 r t } Yn X|  j j | | | f  d S)a  
        Attach a file with the given filename and content. The filename can
        be omitted and the mimetype is guessed, if not provided.

        If the first parameter is a MIMEBase subclass, insert it directly
        into the resulting message attachments.

        For a text/* mimetype (guessed or specified), when a bytes object is
        specified as content, decode it as UTF-8. If that fails, set the
        mimetype to DEFAULT_ATTACHMENT_MIME_TYPE and don't decode the content.
        Nr   /r8   text)r;   r   AssertionErrorrl   append	mimetypes
guess_typeDEFAULT_ATTACHMENT_MIME_TYPEsplitbytesdecodeUnicodeDecodeError)rK   filenamecontentmimetypebasetypesubtyper   r   r   rm     s    zEmailMessage.attachc             C   sK   t  |  } | j d  ) } | j   } |  j | j | |  Wd QRXd S)al  
        Attach a file from the filesystem.

        Set the mimetype to DEFAULT_ATTACHMENT_MIME_TYPE if it isn't specified
        and cannot be guessed.

        For a text/* mimetype (guessed or specified), decode the file's content
        as UTF-8. If that fails, set the mimetype to
        DEFAULT_ATTACHMENT_MIME_TYPE and don't decode the content.
        rbN)r   openreadrm   r3   )rK   pathr   filer   r   r   r   attach_file6  s    zEmailMessage.attach_filec             C   s   |  j  |  S)N)_create_attachments)rK   r   r   r   r   r~   F  s    zEmailMessage._create_messagec             C   s   |  j  r |  j p t j } | } t d |  j d |  } |  j sN | j   r[ | j |  xF |  j  D]; } t	 | t
  r | j |  qe | j |  j |    qe W| S)NrU   r)   )rl   r)   r   r,   rb   mixed_subtyperk   is_multipartrm   r;   r   _create_attachment)rK   r   r)   body_msgrq   r   r   r   r   I  s    	z EmailMessage._create_attachmentsc             C   s   | j  d d  \ } } | d k rK |  j p3 t j } t | | |  } n | d k r | d k r t | t  r | j   } n! t | t  s t	 t
 |   } t | |  } n) t | |  } | j |  t j |  | S)z
        Convert the content, mimetype pair into a MIME attachment object.

        If the mimetype is message/rfc822, content may be an
        email.Message or EmailMessage object, as well as a str.
        r   r8   r   r   Zrfc822)r   r)   r   r,   rS   r;   rf   r   r
   r   r   rQ   r   r`   Encodersencode_base64)rK   r   r   r   r   r)   rq   r   r   r   _create_mime_attachmentW  s    z$EmailMessage._create_mime_attachmentc             C   sg   |  j  | |  } | rc y | j d  Wn! t k
 rL d d | f } Yn X| j d d d | | S)zg
        Convert the filename, content, mimetype triple into a MIME attachment
        object.
        r%   zutf-8r6   zContent-Dispositionrq   r   )r   r.   r/   
add_header)rK   r   r   r   rq   r   r   r   r   u  s    zEmailMessage._create_attachmentc             C   sV   | rR y |  j  | } Wn. t k
 rG d j d d   | D  } Yn X| | | <d S)zt
        Set msg's header, either from self.extra_headers, if present, or from
        the values argument.
        z, c             s   s   |  ] } t  |  Vq d  S)N)r-   )r'   vr   r   r   r*     s    z=EmailMessage._set_list_header_if_not_empty.<locals>.<genexpr>N)rn   KeyErrorr2   )rK   r   headervaluesr   r   r   r   r     s    !z*EmailMessage._set_list_header_if_not_empty)r   r   r   __doc__r}   r   r)   rW   rr   r   r   r   rm   r   r~   r   r   r   r   r   r   r   r   rf      s$   * rf   c                   ss   e  Z d  Z d Z d Z d d d d d d d d d d d   f d d  Z d d   Z d	 d
   Z d d   Z   S)EmailMultiAlternativesz
    A version of EmailMessage that makes it easy to send multipart/alternative
    messages. For example, including text and HTML versions of the text is
    made easier.
    alternativer6   Nc                s>   t    j | | | | | | | | |
 | 
 |	 p4 g  |  _ d S)zg
        Initialize a single email message (which can be sent to multiple
        recipients).
        N)superrW   alternatives)rK   r+   rk   rj   r    r"   ro   rl   rp   r   r!   ri   )	__class__r   r   rW     s    	zEmailMultiAlternatives.__init__c             C   s>   | d k	 s t   | d k	 s$ t   |  j j | | f  d S)z-Attach an alternative content representation.N)r   r   r   )rK   r   r   r   r   r   attach_alternative  s    z)EmailMultiAlternatives.attach_alternativec             C   s   |  j  |  j |   S)N)r   _create_alternatives)rK   r   r   r   r   r~     s    z&EmailMultiAlternatives._create_messagec             C   s}   |  j  p t j } |  j ry | } t d |  j d |  } |  j rO | j |  x' |  j D] } | j |  j |    qY W| S)NrU   r)   )	r)   r   r,   r   rb   alternative_subtyperk   rm   r   )rK   r   r)   r   r   r   r   r   r     s    		z+EmailMultiAlternatives._create_alternatives)	r   r   r   r   r   rW   r   r~   r   r   r   )r   r   r     s   r   ):r   r   r   r[   r   r   r   r   Zemail.errorsr   Zemail.headerr   Zemail.headerregistryr   r	   email.messager
   Zemail.mime.baser   Zemail.mime.messager   Zemail.mime.multipartr   Zemail.mime.textr   email.utilsr   r   r   ior   r   Zpathlibr   Zdjango.confr   Zdjango.core.mail.utilsr   Zdjango.utils.encodingr   r   r_   body_encodingr^   QPr   rY   r=   r   r1   r5   r&   rD   rQ   rS   rb   rf   r   r   r   r   r   <module>   sR   "		%