o
    ›¨ÊhÏ:  ã                   @   s”   d dl Z d dlmZ d dlZd dlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZ dd	lmZmZmZmZ G d
d„ deƒZG dd„ de	ƒZdS )é    N)Úquote)ÚCaseInsensitiveDicté   )ÚAnymailRequestsBackendÚRequestsPayloadé   )ÚAnymailConfigurationErrorÚAnymailRequestsAPIErrorÚAnymailWarning)ÚAnymailRecipientStatus)ÚBASIC_NUMERIC_TYPESÚget_anymail_settingÚ	timestampÚupdate_deepc                       s<   e Zd ZdZdZ‡ fdd„Zdd„ Zdd„ Zd	d
„ Z‡  Z	S )ÚEmailBackendz'
    SendGrid v3 API Email Backend
    ÚSendGridc                    sÀ   | j }td||ddd�}td||ddd�}|s|rtdƒ‚td||dd�| _td	||dd
�| _td||dd
�| _td||dd
�| _td||dd
�}| d¡sR|d7 }tt	| ƒj
|fi |¤Ž dS )z!Init options from Django settingsÚusernameNT)Úesp_nameÚkwargsÚdefaultÚ
allow_bareÚpasswordz•SendGrid v3 API doesn't support username/password auth; Please change to API key.
(For legacy v2 API, use anymail.backends.sendgrid_v2.EmailBackend.)Úapi_key)r   r   r   Úgenerate_message_id)r   r   r   Úmerge_field_formatÚworkaround_name_quote_bugÚapi_urlzhttps://api.sendgrid.com/v3/ú/)r   r   r   r   r   r   r   ÚendswithÚsuperr   Ú__init__)Úselfr   r   r   r   r   ©Ú	__class__© úK/var/www/html/env/lib/python3.10/site-packages/anymail/backends/sendgrid.pyr       s.   ÿÿÿÿÿ
zEmailBackend.__init__c                 C   s   t ||| ƒS ©N)ÚSendGridPayload)r!   ÚmessageÚdefaultsr$   r$   r%   Úbuild_message_payload5   s   z"EmailBackend.build_message_payloadc                 C   s(   |j dk s
|j dkrt|||| d�‚d S )NéÈ   i,  )Úemail_messageÚpayloadÚresponseÚbackend)Ústatus_coder	   ©r!   r.   r-   r(   r$   r$   r%   Úraise_for_status8   s
   ÿÿzEmailBackend.raise_for_statusc                    s"   t |jdd�‰ ‡ fdd„|jD ƒS )NÚqueued)Ú
message_idÚstatusc                    s   i | ]}|j ˆ “qS r$   )Ú	addr_spec)Ú.0Ú	recipient©r5   r$   r%   Ú
<dictcomp>C   s    z7EmailBackend.parse_recipient_status.<locals>.<dictcomp>)r   r4   Úall_recipientsr1   r$   r9   r%   Úparse_recipient_status=   s   z#EmailBackend.parse_recipient_status)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r    r*   r2   r<   Ú__classcell__r$   r$   r"   r%   r      s    !r   c                       sâ   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Ze	d4dd„ƒZ
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Z‡  ZS )5r'   c                    s„   g | _ |j| _|j| _d | _|j| _d | _d | _| di ¡}d|j |d< d|d< d|d< t	t
| ƒj|||g|¢R d|i|¤Ž d S )NÚheadersz	Bearer %sÚAuthorizationzapplication/jsonzContent-TypeÚAccept)r;   r   r   r4   r   Ú
merge_dataÚmerge_global_dataÚpopr   r   r'   r    )r!   r(   r)   r/   Úargsr   Úhttp_headersr"   r$   r%   r    H   s$   þÿ
þzSendGridPayload.__init__c                 C   s   dS )Nz	mail/sendr$   ©r!   r$   r$   r%   Úget_api_endpointY   s   z SendGridPayload.get_api_endpointc                 C   s   i gt ƒ dœ| _d S )N)ÚpersonalizationsrB   )r   ÚdatarJ   r$   r$   r%   Úinit_payload\   s   þzSendGridPayload.init_payloadc                 C   s4   | j r|  ¡  |  ¡  | jd s| jd= |  | j¡S )zJPerforms any necessary serialization on self.data, and returns the result.rB   )r   Úset_anymail_idÚbuild_merge_datarM   Úserialize_jsonrJ   r$   r$   r%   Úserialize_datab   s   
zSendGridPayload.serialize_datac                 C   s&   t t ¡ ƒ| _| j| j di ¡d< dS )z>Ensure message has a known anymail_id for later event trackingÚcustom_argsÚ
anymail_idN)ÚstrÚuuidÚuuid4r4   rM   Ú
setdefaultrJ   r$   r$   r%   rO   n   s   zSendGridPayload.set_anymail_idc              	      s¦  | j pd‰ | jdurut| jd ƒdksJ ‚| jd  ¡ }| d¡}tƒ }|D ]:}| ¡ }|g|d< z| j|d  }‡ fdd„| ¡ D ƒ|d	< | | 	¡ ¡}W n	 t
yW   Y nw | jd  |¡ q&| j du rutd
d„ |D ƒƒrut dt¡ | jdurÍ| j di ¡ ‡ fdd„| j ¡ D ƒ¡ ‡ fdd„| j 	¡ D ƒ}| jd D ]}| d	i ¡‰ˆ ‡fdd„|D ƒ¡ qŸ| j du rÏtdd„ | j 	¡ D ƒƒrÑt dt¡ dS dS dS dS )z?Set personalizations[...]['substitutions'] and data['sections']z{}NrL   r   ÚtoÚemailc                    ó   i | ]
\}}ˆ   |¡|“qS r$   ©Úformat©r7   ÚfieldrM   ©r   r$   r%   r:   „   s    ÿz4SendGridPayload.build_merge_data.<locals>.<dictcomp>Úsubstitutionsc                 s   ó   � | ]}|  ¡ V  qd S r&   ©Úisalnum©r7   r_   r$   r$   r%   Ú	<genexpr>‹   ó   € z3SendGridPayload.build_merge_data.<locals>.<genexpr>z½Your SendGrid merge fields don't seem to have delimiters, which can cause unexpected results with Anymail's merge_data. Search SENDGRID_MERGE_FIELD_FORMAT in the Anymail docs for more info.Úsectionsc                    r[   r$   r\   r^   r`   r$   r%   r:   ”   s    
ÿÿc                    s   g | ]}ˆ   |¡‘qS r$   r\   re   r`   r$   r%   Ú
<listcomp>�   s    ÿz4SendGridPayload.build_merge_data.<locals>.<listcomp>c                    s   i | ]	}|ˆ vr||“qS r$   r$   re   )ra   r$   r%   r:   ¡   s    ÿc                 s   rb   r&   rc   re   r$   r$   r%   rf   ¥   rg   zÄYour SendGrid global merge fields don't seem to have delimiters, which can cause unexpected results with Anymail's merge_data. Search SENDGRID_MERGE_FIELD_FORMAT in the Anymail docs for more info.)r   rE   ÚlenrM   rG   ÚsetÚcopyÚitemsÚunionÚkeysÚKeyErrorÚappendÚallÚwarningsÚwarnr
   rF   rX   Úupdate)r!   Úbase_personalizationsÚto_listÚ
all_fieldsr8   ÚpersonalizationÚrecipient_dataÚglobal_fieldsr$   )r   ra   r%   rP   t   sV   





ÿÿü
þ
	ÿ
ÿüìz SendGridPayload.build_merge_dataFc                 C   s8   d| j i}| jr|rdt| jƒ |d< |S | j|d< |S )z8Converts EmailAddress to SendGrid API {email, name} dictrZ   z"%s"Úname)r6   Údisplay_nameÚrfc822_quote)rZ   r   Úobjr$   r$   r%   Úemail_object°   s   

ÿzSendGridPayload.email_objectc                 C   s   |   |¡| jd< d S )NÚfrom)r€   rM   )r!   rZ   r$   r$   r%   Úset_from_email¿   s   zSendGridPayload.set_from_emailc                    sN   |dv sJ ‚|r%ˆ j ‰‡ ‡fdd„|D ƒˆ jd d |< ˆ  j|7  _d S d S )N)rY   ÚccÚbccc                    s   g | ]}ˆ   |ˆ¡‘qS r$   )r€   )r7   rZ   ©r!   r   r$   r%   ri   É   s    z2SendGridPayload.set_recipients.<locals>.<listcomp>rL   r   )r   rM   r;   )r!   Úrecipient_typeÚemailsr$   r…   r%   Úset_recipientsÂ   s   ÿúzSendGridPayload.set_recipientsc                 C   s   |dkr|| j d< d S d S )NÚ Úsubject©rM   )r!   rŠ   r$   r$   r%   Úset_subjectÌ   s   ÿzSendGridPayload.set_subjectc                 C   s>   t |ƒdkr|  d¡ t |ƒdkr|  |d ¡| jd< d S d S )Nr   zmultiple reply_to addressesr   Úreply_to)rj   Úunsupported_featurer€   rM   )r!   r‡   r$   r$   r%   Úset_reply_toÐ   s
   
ÿzSendGridPayload.set_reply_toc                 C   s"   | j d  dd„ | ¡ D ƒ¡ d S )NrB   c                 S   ó(   i | ]\}}|t |tƒrt|ƒn|“qS r$   ©Ú
isinstancer   rU   ©r7   ÚkÚvr$   r$   r%   r:   Ú   ó    ÿÿz5SendGridPayload.set_extra_headers.<locals>.<dictcomp>)rM   ru   rm   )r!   rB   r$   r$   r%   Úset_extra_headers×   s   þz!SendGridPayload.set_extra_headersc                 C   ó*   |dkr| j  dg ¡ d|dœ¡ d S d S )Nr‰   Úcontentz
text/plain©ÚtypeÚvalue©rM   rX   rq   ©r!   Úbodyr$   r$   r%   Úset_text_bodyß   s   þÿzSendGridPayload.set_text_bodyc                 C   r˜   )Nr‰   r™   z	text/htmlrš   r�   rž   r$   r$   r%   Úset_html_bodyë   s   þÿzSendGridPayload.set_html_bodyc                 C   s   | j  dg ¡ ||dœ¡ d S )Nr™   rš   r�   )r!   r™   Úmimetyper$   r$   r%   Úadd_alternativeõ   s   þzSendGridPayload.add_alternativec                 C   sF   |j |j|jpddœ}|jrd|d< |j|d< | j dg ¡ |¡ d S )Nr‰   )r™   r›   ÚfilenameÚinlineÚdispositionÚ
content_idÚattachments)Ú
b64contentr¢   r|   r¥   ÚcidrM   rX   rq   )r!   Ú
attachmentÚattr$   r$   r%   Úadd_attachmentü   s   ý
zSendGridPayload.add_attachmentc                 C   s   dd„ |  ¡ D ƒ| jd< d S )Nc                 S   r�   r$   r‘   r“   r$   r$   r%   r:     r–   z0SendGridPayload.set_metadata.<locals>.<dictcomp>rS   )rm   rM   )r!   Úmetadatar$   r$   r%   Úset_metadata  s   þzSendGridPayload.set_metadatac                 C   s   t t|ƒƒ| jd< d S )NÚsend_at)Úintr   rM   )r!   r°   r$   r$   r%   Úset_send_at  s   zSendGridPayload.set_send_atc                 C   ó   || j d< d S )NÚ
categoriesr‹   )r!   Útagsr$   r$   r%   Úset_tags  ó   zSendGridPayload.set_tagsc                 C   ó   d|i| j  di ¡d< d S )NÚenableÚtracking_settingsÚclick_tracking©rM   rX   )r!   Útrack_clicksr$   r$   r%   Úset_track_clicks  s   ÿz SendGridPayload.set_track_clicksc                 C   r¸   )Nr¹   rº   Úopen_trackingr¼   )r!   Útrack_opensr$   r$   r%   Úset_track_opens  s   ÿzSendGridPayload.set_track_opensc                 C   r³   )NÚtemplate_idr‹   )r!   rÂ   r$   r$   r%   Úset_template_id%  r·   zSendGridPayload.set_template_idc                 C   ó
   || _ d S r&   )rE   )r!   rE   r$   r$   r%   Úset_merge_data(  s   
zSendGridPayload.set_merge_datac                 C   rÄ   r&   )rF   )r!   rF   r$   r$   r%   Úset_merge_global_data-  s   
z%SendGridPayload.set_merge_global_datac                 C   s0   |  d| j¡| _d|v rtdƒ‚t| j|ƒ d S )Nr   z	x-smtpapizÍYou are attempting to use SendGrid v2 API-style x-smtpapi params with the SendGrid v3 API. Please update your `esp_extra` to the new API, or use 'anymail.backends.sendgrid_v2.EmailBackend' for the old API.)rG   r   r   r   rM   )r!   Úextrar$   r$   r%   Úset_esp_extra1  s   ÿzSendGridPayload.set_esp_extra)F)r=   r>   r?   r    rK   rN   rR   rO   rP   Ústaticmethodr€   r‚   rˆ   rŒ   r�   r—   r    r¡   r£   r­   r¯   r²   r¶   r¾   rÁ   rÃ   rÅ   rÆ   rÈ   rA   r$   r$   r"   r%   r'   F   s6    <


r'   )rV   Úemail.utilsr   r~   rs   Úrequests.structuresr   Úbase_requestsr   r   Ú
exceptionsr   r	   r
   r(   r   Úutilsr   r   r   r   r   r'   r$   r$   r$   r%   Ú<module>   s    9