o
    ›¨ÊhÊ(  ã                   @   s¬   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 z
d dlmZmZ W n ey;   ed	d	d
�‚w G dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    )Úabsolute_importé   )ÚAnymailBaseBackendÚBasePayloadé   )ÚAnymailAPIErrorÚAnymailImproperlyInstalledÚAnymailConfigurationError)ÚAnymailRecipientStatus)Úget_anymail_setting)Ú	SparkPostÚSparkPostExceptionÚ	sparkpost)Úmissing_packageÚbackendc                       s<   e Zd ZdZdZ‡ fdd„Zdd„ Zdd„ Zd	d
„ Z‡  Z	S )ÚEmailBackendzA
    SparkPost Email Backend (using python-sparkpost client)
    r   c              
      s°   t t| ƒjdi |¤Ž td| j|ddd�| _td| j|dd�}i }|dur6| d¡r0|dd… }t|ƒ|d	< zt| jfi |¤Ž| _	W dS  t
yW } ztd
t|ƒ ƒ‚d}~ww )z!Init options from Django settingsÚapi_keyTN)Úesp_nameÚkwargsÚ
allow_bareÚdefaultÚapi_url)r   r   r   ú/éÿÿÿÿÚbase_uriz¹Error initializing SparkPost: %s
You may need to set ANYMAIL = {'SPARKPOST_API_KEY': ...} or ANYMAIL_SPARKPOST_API_KEY in your Django settings, or SPARKPOST_API_KEY in your environment.© )Úsuperr   Ú__init__r   r   r   ÚendswithÚ_FullSparkPostEndpointr   Úspr   r	   Ústr)Úselfr   r   Úextra_sparkpost_paramsÚerr©Ú	__class__r   úL/var/www/html/env/lib/python3.10/site-packages/anymail/backends/sparkpost.pyr      s(   ÿ
ýÿ€þzEmailBackend.__init__c                 C   s   t ||| ƒS ©N)ÚSparkPostPayload)r"   ÚmessageÚdefaultsr   r   r'   Úbuild_message_payload3   s   z"EmailBackend.build_message_payloadc                 C   sd   |  ¡ }z| jjjdi |¤Ž}W |S  ty1 } ztt|ƒ| ||t|dd ƒt|dd ƒd�‚d }~ww )NÚresponseÚstatus)r   Úemail_messageÚpayloadr-   Ústatus_coder   )Úget_api_paramsr    ÚtransmissionsÚsendr   r   r!   Úgetattr)r"   r0   r*   Úparamsr-   r$   r   r   r'   Úpost_to_esp6   s   ú

ý€ÿzEmailBackend.post_to_espc           
   
      s°   z|d }|d }|d }W n t tfy* } ztdt|ƒ|f | ||d�‚d }~ww t|jƒ}||kr;|dkr;d}	n||krF|dkrFd}	nd	}	t||	d
�‰ ‡ fdd„|jD ƒS )NÚtotal_accepted_recipientsÚtotal_rejected_recipientsÚidz,%s in SparkPost.transmissions.send result %r)r   r/   r0   r   ÚqueuedÚrejectedÚunknown)Ú
message_idr.   c                    s   i | ]}|j ˆ “qS r   )Ú	addr_spec)Ú.0Ú	recipient©Úrecipient_statusr   r'   Ú
<dictcomp>Y   s    z7EmailBackend.parse_recipient_status.<locals>.<dictcomp>)ÚKeyErrorÚ	TypeErrorr   r!   ÚlenÚall_recipientsr
   )
r"   r-   r0   r*   Úacceptedr<   Útransmission_idr$   Úrecipient_countr.   r   rB   r'   Úparse_recipient_statusB   s&   þ€ÿ

z#EmailBackend.parse_recipient_status)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r,   r7   rL   Ú__classcell__r   r   r%   r'   r      s    r   c                   @   s¼   e Z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d!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-S ).r)   c                 C   s   i | _ g | _g | _i | _d S r(   )r6   rH   Ú	to_emailsÚ
merge_data)r"   r   r   r'   Úinit_payload]   s   
zSparkPostPayload.init_payloadc              	   C   sØ   g }t | jƒdkr:| jD ],}dd|jii}|jr|j|d d< z
| j|j |d< W n	 ty2   Y nw | |¡ qndd„ | jD ƒ}|rI|| jd< | j d	d ¡rid
D ]}z| j| s^| j|= W qR tyh   Y qRw | jS )Nr   ÚaddressÚemailÚnameÚsubstitution_datac                 S   ó   g | ]}|j ‘qS r   ©rU   ©r@   rV   r   r   r'   Ú
<listcomp>s   ó    z3SparkPostPayload.get_api_params.<locals>.<listcomp>Ú
recipientsÚtemplate)ÚsubjectÚtextÚhtml)	rG   rS   rR   r?   Údisplay_namerE   Úappendr6   Úget)r"   r^   rV   ÚrcptÚcontent_paramr   r   r'   r2   c   s4   
ÿø

€ÿzSparkPostPayload.get_api_paramsc                 C   s   d  dd„ |D ƒ¡| jd< d S )Nú, c                 S   rY   r   rZ   r[   r   r   r'   r\   …   r]   z8SparkPostPayload.set_from_email_list.<locals>.<listcomp>Ú
from_email©Újoinr6   ©r"   Úemailsr   r   r'   Úset_from_email_list‚   s   z$SparkPostPayload.set_from_email_listc                 C   s    |r|| _ |  j|7  _d S d S r(   )rR   rH   rl   r   r   r'   Úset_to‡   s   þzSparkPostPayload.set_toc                 C   ó.   |rdd„ |D ƒ| j d< |  j|7  _d S d S )Nc                 S   rY   r   rZ   r[   r   r   r'   r\   Ž   r]   z+SparkPostPayload.set_cc.<locals>.<listcomp>Úcc©r6   rH   rl   r   r   r'   Úset_ccŒ   ó   þzSparkPostPayload.set_ccc                 C   rp   )Nc                 S   rY   r   rZ   r[   r   r   r'   r\   “   r]   z,SparkPostPayload.set_bcc.<locals>.<listcomp>Úbccrr   rl   r   r   r'   Úset_bcc‘   rt   zSparkPostPayload.set_bccc                 C   ó   || j d< d S )Nr`   ©r6   )r"   r`   r   r   r'   Úset_subject–   ó   zSparkPostPayload.set_subjectc                 C   s&   |rd  dd„ |D ƒ¡| jd< d S d S )Nrh   c                 S   rY   r   rZ   r[   r   r   r'   r\   œ   r]   z1SparkPostPayload.set_reply_to.<locals>.<listcomp>Úreply_torj   rl   r   r   r'   Úset_reply_to™   s   þzSparkPostPayload.set_reply_toc                 C   s   |rt |ƒ| jd< d S d S )NÚcustom_headers)Údictr6   )r"   Úheadersr   r   r'   Úset_extra_headersž   s   ÿz"SparkPostPayload.set_extra_headersc                 C   rw   )Nra   rx   ©r"   Úbodyr   r   r'   Úset_text_body¢   rz   zSparkPostPayload.set_text_bodyc                 C   s"   d| j v r
|  d¡ || j d< d S )Nrb   zmultiple html parts)r6   Úunsupported_featurer�   r   r   r'   Úset_html_body¥   s   

zSparkPostPayload.set_html_bodyc                 C   sD   |j r	d}|j}nd}|jpd}| j |g ¡ |j||jdœ¡ d S )NÚinline_imagesÚattachmentsÚ )ÚtyperW   Údata)ÚinlineÚcidrW   r6   Ú
setdefaultrd   ÚmimetypeÚ
b64content)r"   Ú
attachmentÚparamrW   r   r   r'   Úadd_attachment«   s   
ýzSparkPostPayload.add_attachmentc                 C   s   |j | jd< d S )NÚreturn_path)r?   r6   )r"   rV   r   r   r'   Úset_envelope_sender¹   ó   z$SparkPostPayload.set_envelope_senderc                 C   rw   )NÚmetadatarx   )r"   r–   r   r   r'   Úset_metadata¼   rz   zSparkPostPayload.set_metadatac              	   C   s@   z|j dd� ¡ | jd< W d S  ttfy   || jd< Y d S w )Nr   )ÚmicrosecondÚ
start_time)ÚreplaceÚ	isoformatr6   ÚAttributeErrorrF   )r"   Úsend_atr   r   r'   Úset_send_at¿   s
   ÿzSparkPostPayload.set_send_atc                 C   s@   t |ƒdkr|d | jd< t |ƒdkr|  d| ¡ d S d S d S )Nr   Úcampaignr   zmultiple tags (%r))rG   r6   r„   )r"   Útagsr   r   r'   Úset_tagsÅ   s   ýzSparkPostPayload.set_tagsc                 C   rw   )NÚtrack_clicksrx   )r"   r¢   r   r   r'   Úset_track_clicksË   rz   z!SparkPostPayload.set_track_clicksc                 C   rw   )NÚtrack_opensrx   )r"   r¤   r   r   r'   Úset_track_opensÎ   rz   z SparkPostPayload.set_track_opensc                 C   rw   )Nr_   rx   )r"   Útemplate_idr   r   r'   Úset_template_idÑ   s   z SparkPostPayload.set_template_idc                 C   s
   || _ d S r(   )rS   )r"   rS   r   r   r'   Úset_merge_dataÕ   s   
zSparkPostPayload.set_merge_datac                 C   rw   )NrX   rx   )r"   Úmerge_global_datar   r   r'   Úset_merge_global_dataØ   rz   z&SparkPostPayload.set_merge_global_datac                 C   s   | j  |¡ d S r(   )r6   Úupdate)r"   Úextrar   r   r'   Úset_esp_extraÜ   r•   zSparkPostPayload.set_esp_extraN)rM   rN   rO   rT   r2   rn   ro   rs   rv   ry   r|   r€   rƒ   r…   r’   r”   r—   rž   r¡   r£   r¥   r§   r¨   rª   r­   r   r   r   r'   r)   \   s.    r)   c                   @   s    e Zd ZdZddgZdd„ ZdS )r   am  A string-like object that allows using a complete SparkPost API endpoint url as base_uri:

        sp = SparkPost(api_key, base_uri=_FullSparkPostEndpoint('https://api.sparkpost.com/api/labs'))

    Works around SparkPost.__init__ code `self.base_uri = base_uri + '/api/v' + version`,
    which makes it difficult to simply copy and paste full API endpoints from SparkPost's docs
    (https://developers.sparkpost.com/api/index.html#header-api-endpoints) -- and completely
    prevents using the labs API endpoint (which has no "v" in it).

    Should work with all python-sparkpost releases through at least v1.3.6.
    z/api/vÚ1c                 C   sF   | j d }| j dd … | _ ||kr| j r| S t| ƒS td| ||f ƒ‚)Nr   r   z„This version of Anymail is not compatible with this version of python-sparkpost.
(_FullSparkPostEndpoint(%r) expected %r but got %r))Ú_expectr!   Ú
ValueError)r"   ÚotherÚexpectedr   r   r'   Ú__add__î   s   
ÿÿz_FullSparkPostEndpoint.__add__N)rM   rN   rO   rP   r¯   r³   r   r   r   r'   r   à   s    r   N)Ú
__future__r   Úbaser   r   Ú
exceptionsr   r   r	   r*   r
   Úutilsr   r   r   r   ÚImportErrorr   r)   r!   r   r   r   r   r'   Ú<module>   s    ÿN 