U
    5øi‹C  ã                   @   sª  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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-d.„ d.ƒZ9G d/d0„ d0e9ƒZ:dS )1é    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-gcyiijx6/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r¨t
|ƒ ¡ }| |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>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    
 r:   c           
   
   C   sP  d}t | tƒs€t| ƒ} zt | ¡\}}W n& tttfk
rN   td|  ƒ‚Y q˜X |rdtd|| f ƒ‚|jpld}|j	}|j
p|d}n| \}}| dd¡\}}|| | }d|ks´d|kr¼t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?   Úrsplitr3   r   r4   r   r   r   Z	addr_spec)
r,   r.   ÚaddressÚtokenÚrestÚnmZ	localpartr?   Zaddress_partsZparsed_addressr   r   r    r*   J   sB    
ÿÿ

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©ÚselfrM   rN   ÚfpÚgr   r   r    Ú	as_stringx   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.
        FrJ   rL   )r   r   ÚBytesGeneratorrP   rQ   rR   r   r   r    Úas_bytes…   s    zMIMEMixin.as_bytesN)Fr%   )Fr%   )r   r   r   rV   rX   r   r   r   r    rI   w   s   
rI   c                   @   s   e Zd Zdd„ ZdS )ÚSafeMIMEMessagec                 C   s"   t ||dƒ\}}t | ||¡ d S )Nr'   )r:   r   Ú__setitem__©rS   r8   r9   r   r   r    rZ   •   s    zSafeMIMEMessage.__setitem__N)r   r   r   rZ   r   r   r   r    rY   “   s   rY   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__)rS   Z_textr^   r_   r   r   r    r`   �   s    zSafeMIMEText.__init__c                 C   s$   t ||| jƒ\}}t | ||¡ d S r)   )r:   r.   r   rZ   r[   r   r   r    rZ   ¡   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)   )Úlenr3   ÚRFC5322_EMAIL_LINE_LENGTH_LIMIT)r+   Úliner   r   r    r/   §   s   ÿz+SafeMIMEText.set_payload.<locals>.<genexpr>)r   )r@   ÚCharsetÚanyÚ
splitlinesÚutf8_charset_qpÚutf8_charsetr   Úset_payload)rS   Úpayloadr   Zhas_long_linesr   r   r    ri   ¥   s    þzSafeMIMEText.set_payload)r]   N)N)r   r   r   r`   rZ   ri   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   r`   )rS   r^   ÚboundaryZ	_subpartsr.   Ú_paramsr   r   r    r`   ³   s    zSafeMIMEMultipart.__init__c                 C   s$   t ||| jƒ\}}t | ||¡ d S r)   )r:   r.   r   rZ   r[   r   r   r    rZ   ·   s    zSafeMIMEMultipart.__setitem__)rl   NNN)r   r   r   r`   rZ   r   r   r   r    rk   ±   s   
rk   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]   rl   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 | _|
ršt |
tƒrŽtdƒ‚t|
ƒ| _ng | _|p¨tj	| _
|| _|p¸d| _g | _|rð|D ]$}t |tƒrä|  |¡ qÊ| j|Ž  qÊ|pöi | _|| _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)r@   r2   Ú	TypeErrorÚlistr"   r#   r$   Úreply_tor   ZDEFAULT_FROM_EMAILÚ
from_emailr0   ÚbodyÚattachmentsr   ÚattachÚextra_headersÚ
connection)rS   r0   ru   rt   r"   r$   ry   rv   Úheadersr#   rs   Ú
attachmentr   r   r    r`   Â   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|   ry   )rS   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rœttjd	�|d
< d|kr²ttd�|d< | j ¡ D ]\}}| ¡ dkr¼|||< q¼|S )NÚSubjectÚFromÚToÚCczReply-Toc                 S   s   g | ]}|  ¡ ‘qS r   )r5   )r+   Úkeyr   r   r    Ú
<listcomp>   s     z(EmailMessage.message.<locals>.<listcomp>Údate)Ú	localtimeÚDatez
message-id)r?   z
Message-IDr!   )r.   r   r1   r\   ru   Úcontent_subtypeÚ_create_messager0   rx   Úgetrt   Ú_set_list_header_if_not_emptyr"   r#   rs   r   ZEMAIL_USE_LOCALTIMEr   r   Úitemsr5   )rS   r.   ÚmsgÚheader_namesr8   Ú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$   )rS   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)rS   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r t |t	ƒr z| 
¡ }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)r@   r   rB   rv   ÚappendÚ	mimetypesÚ
guess_typeÚDEFAULT_ATTACHMENT_MIME_TYPEÚsplitÚbytesÚdecodeÚUnicodeDecodeError)rS   ÚfilenameÚcontentÚmimetypeÚbasetypeÚsubtyper   r   r    rw     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Úreadrw   r8   )rS   ÚpathrŸ   Úfilerž   r   r   r    Úattach_fileB  s    zEmailMessage.attach_filec                 C   s
   |   |¡S r)   )Ú_create_attachments©rS   rŒ   r   r   r    rˆ   R  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.   )rv   r.   r   r1   rk   Úmixed_subtyperu   Úis_multipartrw   r@   r   Ú_create_attachment)rS   rŒ   r.   Úbody_msgr{   r   r   r    r¨   U  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   r1   r\   r@   ro   r�   r
   r   r   rY   r   ri   ÚEncodersÚencode_base64)rS   rž   rŸ   r    r¡   r.   r{   r   r   r    Ú_create_mime_attachmentc  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±   r3   r4   Ú
add_header)rS   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)   )r2   )r+   Úvr   r   r    r/   ˜  s     z=EmailMessage._set_list_header_if_not_empty.<locals>.<genexpr>N)rx   ÚKeyErrorr7   )rS   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.   r`   r|   r�   r‘   r’   rw   r§   rˆ   r¨   r±   r­   rŠ   r   r   r   r    ro   ¼   s,            þ
,


$

ro   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 )rp   N)Úsuperr`   Úalternatives)rS   r0   ru   rt   r"   r$   ry   rv   rz   r»   r#   rs   ©Ú	__class__r   r    r`   ¤  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.)rB   r»   r•   )rS   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   r1   r»   rk   Úalternative_subtyperu   rw   r±   )rS   rŒ   r.   r®   r¹   r   r   r    r¿   º  s    

z+EmailMultiAlternatives._create_alternatives)r;   r;   NNNNNNNNN)
r   r   r   r·   rÀ   r`   r¾   rˆ   r¿   Ú__classcell__r   r   r¼   r    r¸   œ  s              þr¸   );r–   r�   r   rd   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   rh   Úbody_encodingrg   ÚQPr˜   rb   rB   r   r6   r:   r*   rI   rY   r\   rk   ro   r¸   r   r   r   r    Ú<module>   sV   

õ- a