U
    mf-E                     @   s  d dl 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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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dZ*de*_+edZ,ej-e,_+dZ.dZ/G dd de0Z1ddddddddd d!d"hZ2d#d$ Z3d%d& Z4G d'd( d(Z5G d)d* d*e5eZ6G d+d, d,e5eZ7G d-d. d.e5eZ8G d/d0 d0Z9G d1d2 d2e9Z:dS )3    Ncharset)encoders)	generatormessage_from_string)HeaderParseError)Header)Addressparser)Message)MIMEBase)MIMEMessage)MIMEMultipart)MIMEText)
formataddr
formatdategetaddresses
make_msgid)BytesIOStringIO)Path)settings)DNS_NAME)	force_strpunycodeutf-8zapplication/octet-streami  c                   @   s   e Zd ZdS )BadHeaderErrorN)__name__
__module____qualname__ r    r    </tmp/pip-unpacked-wheel-siwebuq3/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s"d|kr2td|| f z|d W nN tk
r   |  tkr|d fddt	|fD }nt
|  }Y nX |  dkrt
| }| |fS )	z6Forbid multi-line headers to prevent header injection.
z;Header values can't contain newlines (got %r for header %r)ascii, c                 3   s   | ]}t | V  qd S N)sanitize_address).0addrencodingr    r!   	<genexpr>C   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"    


r;   c           
   
   C   sP  d}t | tst| } zt| \}}W n& tttfk
rN   td|  Y qX |rdtd|| f |jpld}|j	}|j
p|d}n| \}}|dd\}}|| | }d|ksd|krtd	z|d
 t| }W n" tk
r   t|| }Y nX z|d
 W n$ tk
r,   t|| }Y nX t|}t||d}	t||	jf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&   r'   z7Invalid address; address parts cannot contain newlines.r(   )usernamedomain)
isinstancetupler   r
   Zget_mailboxr   
ValueError
IndexErrorZdisplay_nameZ
local_partr@   rsplitr4   r   r5   r   r	   r   Z	addr_spec)
r-   r/   addresstokenrestnmZ	localpartr@   Zaddress_partsZparsed_addressr    r    r!   r+   N   s>    



r+   c                   @   s    e Zd ZdddZd	ddZdS )
	MIMEMixinFr&   c                 C   s,   t  }tj|dd}|j| ||d | 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.
        Fmangle_from_unixfromlinesep)r   r   	GeneratorflattengetvalueselfrN   rO   fpgr    r    r!   	as_string{   s    zMIMEMixin.as_stringc                 C   s,   t  }tj|dd}|j| ||d | 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.
        FrK   rM   )r   r   BytesGeneratorrQ   rR   rS   r    r    r!   as_bytes   s    zMIMEMixin.as_bytesN)Fr&   )Fr&   )r   r   r   rW   rY   r    r    r    r!   rJ   z   s   
rJ   c                   @   s   e Zd Zdd ZdS )SafeMIMEMessagec                 C   s"   t ||d\}}t| || d S )Nr(   )r;   r   __setitem__rT   r9   r:   r    r    r!   r[      s    zSafeMIMEMessage.__setitem__N)r   r   r   r[   r    r    r    r!   rZ      s   rZ   c                   @   s(   e Zd Zd	ddZdd Zd
ddZdS )SafeMIMETextplainNc                 C   s   || _ tj| |||d d S )N)_subtype_charset)r/   r   __init__)rT   Z_textr_   r`   r    r    r!   ra      s    zSafeMIMEText.__init__c                 C   s$   t ||| j\}}t| || d S r*   )r;   r/   r   r[   r\   r    r    r!   r[      s    zSafeMIMEText.__setitem__c                 C   sJ   |dkr6t |tjs6tdd | D }|r2tnt}tj| ||d d S )Nr   c                 s   s   | ]}t | tkV  qd S r*   )lenr4   RFC5322_EMAIL_LINE_LENGTH_LIMIT)r,   liner    r    r!   r0      s   z+SafeMIMEText.set_payload.<locals>.<genexpr>r   )rA   Charsetany
splitlinesutf8_charset_qputf8_charsetr   set_payload)rT   payloadr   Zhas_long_linesr    r    r!   rj      s    zSafeMIMEText.set_payload)r^   N)N)r   r   r   ra   r[   rj   r    r    r    r!   r]      s   
r]   c                   @   s   e Zd ZdddZdd ZdS )SafeMIMEMultipartmixedNc                 K   s   || _ tj| |||f| d S r*   )r/   r   ra   )rT   r_   boundaryZ	_subpartsr/   _paramsr    r    r!   ra      s    zSafeMIMEMultipart.__init__c                 C   s$   t ||| j\}}t| || d S r*   )r;   r/   r   r[   r\   r    r    r!   r[      s    zSafeMIMEMultipart.__setitem__)rm   NNN)r   r   r   ra   r[   r    r    r    r!   rl      s          
rl   c                
   @   s   e Zd ZdZdZdZdZdddZd d	d
Zdd Z	dd Z
d!ddZ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.r^   rm   Nr<   c                 C   s  |r"t |trtdt|| _ng | _|	rJt |	tr>tdt|	| _ng | _|rrt |trftdt|| _ng | _|
rt |
trtdt|
| _ng | _|ptj	| _
|| _|pd| _g | _|r|D ]$}t |tr| | q| j|  q|pi | _|| _dS )g
        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 tupler<   N)rA   r3   	TypeErrorlistr#   r$   r%   reply_tor   ZDEFAULT_FROM_EMAIL
from_emailr1   bodyattachmentsr   attachextra_headers
connection)rT   r1   rv   ru   r#   r%   rz   rw   headersr$   rt   
attachmentr    r    r!   ra      s>    






zEmailMessage.__init__Fc                 C   s$   ddl m} | js||d| _| jS )Nr   )get_connection)fail_silently)Zdjango.core.mailr}   rz   )rT   r~   r}   r    r    r!   r}      s    zEmailMessage.get_connectionc                 C   s   | j p
tj}t| j| j|}| |}| j|d< | j	d| j
|d< | |d| j | |d| j | |d| j dd | jD }d|krttjd	|d
< d|krttd|d< | j D ]\}}| dkr|||< q|S )NSubjectFromToCczReply-Toc                 S   s   g | ]}|  qS r    )r6   )r,   keyr    r    r!   
<listcomp>  s     z(EmailMessage.message.<locals>.<listcomp>date)	localtimeDatez
message-id)r@   z
Message-IDr"   )r/   r   r2   r]   rv   content_subtype_create_messager1   ry   getru   _set_list_header_if_not_emptyr#   r$   rt   r   ZEMAIL_USE_LOCALTIMEr   r   itemsr6   )rT   r/   msgheader_namesr9   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S r    r    )r,   emailr    r    r!   r   "  s      z+EmailMessage.recipients.<locals>.<listcomp>)r#   r$   r%   )rT   r    r    r!   
recipients  s    zEmailMessage.recipientsc                 C   s   |   sdS | || gS )zSend the email message.r   )r   r}   Zsend_messages)rT   r~   r    r    r!   send$  s    zEmailMessage.sendc                 C   s   t |tr0|dk	s|dk	r"td| j| n|dkrBtdnp|pVt|d pVt}|dd\}}|dkrt |t	rz|
 }W n tk
r   t}Y nX | 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.
        NzLcontent and mimetype must not be given when a MIMEBase instance is provided.zcontent must be provided.r   /r>   text)rA   r   rC   rw   append	mimetypes
guess_typeDEFAULT_ATTACHMENT_MIME_TYPEsplitbytesdecodeUnicodeDecodeError)rT   filenamecontentmimetypebasetypesubtyper    r    r!   rx   ,  s*    



zEmailMessage.attachc              	   C   s:   t |}|d}| }| |j|| W 5 Q R X d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readrx   r9   )rT   pathr   filer   r    r    r!   attach_fileT  s    zEmailMessage.attach_filec                 C   s
   |  |S r*   )_create_attachmentsrT   r   r    r    r!   r   d  s    zEmailMessage._create_messagec                 C   sr   | j rn| jptj}|}t| j|d}| js2| r<|| | j D ]*}t	|t
r\|| qB|| j|  qB|S N)r_   r/   )rw   r/   r   r2   rl   mixed_subtyperv   is_multipartrx   rA   r   _create_attachment)rT   r   r/   body_msgr|   r    r    r!   r   g  s    


z EmailMessage._create_attachmentsc                 C   s   | dd\}}|dkr2| jp"tj}t|||}nd|dkrx|dkrxt|trV| }nt|tslt	t
|}t||}nt||}|| t| |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   r>   r   r   Zrfc822)r   r/   r   r2   r]   rA   rp   r   r   r   r   rZ   r   rj   Encodersencode_base64)rT   r   r   r   r   r/   r|   r    r    r!   _create_mime_attachmentu  s    





z$EmailMessage._create_mime_attachmentc                 C   sR   |  ||}|rNz|d W n tk
r<   dd|f}Y nX |jdd|d |S )zg
        Convert the filename, content, mimetype triple into a MIME attachment
        object.
        r(   r   r<   zContent-Dispositionr|   )r   )r   r4   r5   
add_header)rT   r   r   r   r|   r    r    r!   r     s      zEmailMessage._create_attachmentc                 C   sH   |rDz| j | }W n( tk
r:   ddd |D }Y nX |||< dS )zt
        Set msg's header, either from self.extra_headers, if present, or from
        the values argument.
        r)   c                 s   s   | ]}t |V  qd S r*   )r3   )r,   vr    r    r!   r0     s     z=EmailMessage._set_list_header_if_not_empty.<locals>.<genexpr>N)ry   KeyErrorr8   )rT   r   headervaluesr   r    r    r!   r     s    z*EmailMessage._set_list_header_if_not_empty)
r<   r<   NNNNNNNN)F)F)NNN)N)N)r   r   r   __doc__r   r   r/   ra   r}   r   r   r   rx   r   r   r   r   r   r   r    r    r    r!   rp      s4             
6


(

rp   c                       s>   e Zd ZdZdZd fdd	Zdd Zd	d
 Zdd Z  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.
    alternativer<   Nc                    s,   t  |||||||||
|
 |	p$g | _dS )rq   N)superra   alternatives)rT   r1   rv   ru   r#   r%   rz   rw   r{   r   r$   rt   	__class__r    r!   ra     s    zEmailMultiAlternatives.__init__c                 C   s,   |dks|dkrt d| j||f dS )z-Attach an alternative content representation.Nz+Both content and mimetype must be provided.)rC   r   r   )rT   r   r   r    r    r!   attach_alternative  s    z)EmailMultiAlternatives.attach_alternativec                 C   s   |  | |S r*   )r   _create_alternativesr   r    r    r!   r     s    z&EmailMultiAlternatives._create_messagec                 C   sT   | j p
tj}| jrP|}t| j|d}| jr4|| | jD ]}|| j|  q:|S r   )	r/   r   r2   r   rl   alternative_subtyperv   rx   r   )rT   r   r/   r   r   r    r    r!   r     s     

z+EmailMultiAlternatives._create_alternatives)r<   r<   NNNNNNNNN)
r   r   r   r   r   ra   r   r   r   __classcell__r    r    r   r!   r     s"               r   );r   r   r   re   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   r   ior   r   pathlibr   Zdjango.confr   Zdjango.core.mail.utilsr   Zdjango.utils.encodingr   r   ri   body_encodingrh   QPr   rc   rC   r   r7   r;   r+   rJ   rZ   r]   rl   rp   r   r    r    r    r!   <module>   sZ   

, s