o
    ˷eP                     @   sb  d dl Z d dlZd dlZ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 d dlZd dl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  d dlm!Z! e"e#Z$dd Z%efddZ&dd Z'dd Z(e%dd Z)ee%ddG dd de	Z*edd Z+eeddG d d! d!e
Z,dS )"    N)method_decorator)csrf_exempt)TemplateViewView)RemovedInDjangoSES20Warning)urlopen)URLError)HttpResponseHttpResponseBadRequest)require_POST)cache)PermissionDenied)render)settings)signals)utilsc                    s    fdd}|S )z)
    Limit a view to superuser only.
    c                    s"   | j jst | g|R i |S N)useris_superuserr   )requestargskwargs	view_func G/var/www/ideatree/venv/lib/python3.10/site-packages/django_ses/views.py_inner#   s   zsuperuser_only.<locals>._innerr   )r   r   r   r   r   superuser_only   s   r   c                 C   sp   t | }g }|r|tj}nd}|d D ]}|r(|d }||||d< || q|jdd d |S )zw
    Parse the output of ``SESConnection.get_send_statistics()`` in to an
    ordered list of 15-minute summaries.
    NSendDataPoints	Timestampc                 S   s   | d S )Nr   r   )xr   r   r   <lambda>=   s    zstats_to_list.<locals>.<lambda>)key)	copydeepcopytimezoner   	TIME_ZONE	normalize
astimezoneappendsort)
stats_dictlocalizeresult
datapoints
current_tzdputc_dtr   r   r   stats_to_list*   s   
r2   c                 C   s   t dd | d D S )zd
    Parse the output of ``SESConnection.list_verified_emails()`` and get
    a list of emails.
    c                 S   s   g | ]}|qS r   r   ).0emailr   r   r   
<listcomp>G   s    z emails_parse.<locals>.<listcomp>VerifiedEmailAddresses)sorted)emails_dictr   r   r   emails_parseB   s   r9   c                 C   sX   d}d}d}d}| D ]}||d 7 }||d 7 }||d 7 }||d 7 }q
||||dS )zi
    Summarize the bounces, complaints, delivery attempts and rejects from a
    list of datapoints.
    r   Bounces
ComplaintsDeliveryAttemptsRejects)r:   r;   r<   r=   r   )
stats_data	t_bouncest_complaintst_delivery_attempts	t_rejectsr0   r   r   r   	sum_statsJ   s   rC   c                 C   s   t dt d}t|}|r|S tjdtjtj	tj
tjtjtjd}| }| }| }t|}t|}t|}	d||d |d |d |d  |d ||	tjd	d

}
t| d|
}t||d |S ).
    Graph SES send statistics over time.
    zRThis view will be removed in future versions. Consider using DashboardView insteadvhash:django_ses_statssesaws_access_key_idaws_secret_access_keyaws_session_tokenregion_nameendpoint_urlconfigSES StatisticsMax24HourSendSentLast24HoursMaxSendRateT
titler.   24hour_quota24hour_sent24hour_remainingpersecond_rateverified_emailssummary
access_key
local_timedjango_ses/send_stats.html  )warningswarnDeprecationWarningr   getboto3clientr   
ACCESS_KEY
SECRET_KEYSESSION_TOKENAWS_SES_REGION_NAMEAWS_SES_REGION_ENDPOINT_URLAWS_SES_CONFIGget_send_quotalist_verified_email_addressesget_send_statisticsr9   r2   rC   r   set)r   	cache_keycached_viewses_conn
quota_dictverified_emails_dictstatsrX   ordered_datarY   extra_contextresponser   r   r   	dashboarda   sH   

rw   dispatch)namec                       s0   e Zd ZdZdZ fddZ fddZ  ZS )DashboardViewrD   r\   c           
         s   t  jd	i |}tjdtjtjtjtjtj	tj
d}| }| }| }t|}t|}t|}	|d||d |d |d |d  |d ||	tjdd
 |S )
NrF   rG   rN   rO   rP   rQ   TrR   r   )superget_context_datarb   rc   r   rd   re   rf   rg   rh   ri   rj   rk   rl   r9   r2   rC   update)
selfr   contextrp   rq   rr   rs   rX   rt   rY   	__class__r   r   r|      s>   
zDashboardView.get_context_datac                    sF   d}t |}|r|S t j|g|R i | }t ||d |S )NrE   r]   )r   ra   r{   r   rm   )r~   r   r   r   rn   ro   rv   r   r   r   ra      s   
zDashboardView.get)__name__
__module____qualname____doc__template_namer|   ra   __classcell__r   r   r   r   rz      s
    %rz   c              
   C   s  t dt | j}z
t|d}W n ty. } zt	d| t
 W  Y d}~S d}~ww tjrGt|sGtjd|dd|id t S |dd	v rtjd
|dd|id |d}z
t|  W t S  ty } ztjd|d|idd W Y d}~t S d}~ww |ddkr\z	t|d }W n ty } ztj	d|d|id W Y d}~t S d}~ww |d}|d}|dkr|di }|d}	|d}
|d}tjd|	|
|d|id tjjt|||d t S |dkr#|di }|d}	|d}tjd|	|d|id tjjt|||d t S |d krP|d!i }|d}	|d"}tjd#|	|d|id tjjt|||d$ t S tj	d%d|id t S tjd&|dd|id t S )'a  
    Handle a bounced email via an SNS webhook.

    Parse the bounced message and send the appropriate signal.
    For bounce messages the bounce_received signal is called.
    For complaint messages the complaint_received signal is called.
    See: http://docs.aws.amazon.com/sns/latest/gsg/json-formats.html#http-subscription-confirmation-json
    See: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monitor-using-event-publishing.html

    In addition to email bounce requests this endpoint also supports the SNS
    subscription confirmation request. This request is sent to the SNS
    subscription endpoint when the subscription is registered.
    See: http://docs.aws.amazon.com/sns/latest/gsg/Subscribe.html

    For the format of the SNS subscription confirmation request see this URL:
    http://docs.aws.amazon.com/sns/latest/gsg/json-formats.html#http-subscription-confirmation-json

    SNS message signatures are verified by default. This functionality can
    be disabled by setting AWS_SES_VERIFY_EVENT_SIGNATURES to False.
    However, this is not recommended.
    See: http://docs.amazonwebservices.com/sns/latest/gsg/SendMessageToHttp.verify.signature.html
    zviews.handle_bounce is deprecated. You can use SESEventWebhookView instead. It handles send, open, click events in addition to bounce, complaint, delivery and subscription confirmation events.utf-8#Received bounce with bad JSON: "%s"N*Received unverified notification: Type: %sTypenotificationextra)SubscriptionConfirmationUnsubscribeConfirmationz0Received subscription confirmation: TopicArn: %sTopicArnSubscribeURLz$Could not confirm subscription: "%s"T)r   exc_infoNotificationMessagemail	eventTypeBouncebounce
feedbackId
bounceTypebounceSubTypezOReceived bounce notification: feedbackId: %s, bounceType: %s, bounceSubType: %s)sendermail_obj
bounce_objraw_message	Complaint	complaintcomplaintFeedbackTypezAReceived complaint notification: feedbackId: %s, feedbackType: %s)r   r   complaint_objr   DeliverydeliverydeliveryFeedbackTypez@Received delivery notification: feedbackId: %s, feedbackType: %s)r   r   delivery_objr   Received unknown event&Received unknown notification type: %s)r^   r_   r   bodyjsonloadsdecode
ValueErrorloggerwarningr
   r   VERIFY_BOUNCE_SIGNATURESr   verify_bounce_messageinfora   r	   r   readr   errorr   bounce_receivedsendhandle_bouncecomplaint_receiveddelivery_received)r   raw_jsonr   esubscribe_urlmessager   
event_typer   feedback_idbounce_typebounce_subtyper   feedback_typer   r   r   r   r      s   
	he	X




A


,



r   c                   @   sx   e Zd 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S )SESEventWebhookViewaS  
    Handle a email sending event via an SNS webhook.

    Parse the event message and send the appropriate signal.
    <eventType> -> <signal>
    bounce -> bounce_received
    complaint -> complaint_received
    delivery -> delivery_received
    send -> send_received
    open -> open_received
    click -> click_received
    See: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monitor-sending-activity.html
    See: http://docs.aws.amazon.com/sns/latest/gsg/json-formats.html#http-subscription-confirmation-json
    See: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/monitor-using-event-publishing.html

    In addition to email bounce requests this endpoint also supports the SNS
    subscription confirmation request. This request is sent to the SNS
    subscription endpoint when the subscription is registered.
    See: http://docs.aws.amazon.com/sns/latest/gsg/Subscribe.html

    For the format of the SNS subscription confirmation request see this URL:
    http://docs.aws.amazon.com/sns/latest/gsg/json-formats.html#http-subscription-confirmation-json

    SNS message signatures are verified by default. This functionality can
    be disabled by setting AWS_SES_VERIFY_EVENT_SIGNATURES to False.
    However, this is not recommended.
    See: http://docs.amazonwebservices.com/sns/latest/gsg/SendMessageToHttp.verify.signature.html
    c           	   
   O   s  |j }z
t|d}W n ty) } ztd| tdW  Y d }~S d }~ww tj	rC| 
|sCtjd|dd|id tdS |dd	krR| | t S |dd
kra| | t S |ddkrz	t|d }W n ty } ztjd|d|id W Y d }~t S d }~ww |d}|dkr| || t S |dkr| || t S |dkr| || t S |dkr| || t S |dkr| || t S |dkr| || t S | || t S | | t S )Nr   z)Received notification with bad JSON: "%s"z5The request body could not be deserialized. Bad JSON.r   r   r   r   zSignature verification failed.r   r   r   r   r   r   r   r   r   SendOpenClick)r   r   r   r   r   r   r   r
   r   VERIFY_EVENT_SIGNATURESverify_event_messager   ra    handle_subscription_confirmationhandle_unsubscribe_confirmationr   handle_complainthandle_deliveryhandle_sendhandle_openhandle_clickhandle_unknown_event_type handle_unknown_notification_typer	   )	r~   r   r   r   r   r   r   r   r   r   r   r   post  sn   
!



zSESEventWebhookView.postc                 C   s
   t |S r   )r   r   r~   r   r   r   r   r     s   
z(SESEventWebhookView.verify_event_messagec                 C      t jd|dd|id d S )Nr   r   r   r   r   r   ra   r   r   r   r   r        
z4SESEventWebhookView.handle_unknown_notification_typec                 C   s   t | d S r   )r   confirm_sns_subscriptionr   r   r   r   r     s   z4SESEventWebhookView.handle_subscription_confirmationc                 C   r   )Nz/Received unsubscribe confirmation: TopicArn: %sr   r   r   r   r   r   r   r   r     r   z3SESEventWebhookView.handle_unsubscribe_confirmationc                 C      | j dtj||d d S )Nr   
event_namesignalr   r   )_handle_eventr   r   r~   r   r   r   r   r   r        
z!SESEventWebhookView.handle_bouncec                 C   r   )Nr   r   )r   r   r   r   r   r   r   r     r   z$SESEventWebhookView.handle_complaintc                 C   r   )Nr   r   )r   r   r   r   r   r   r   r     r   z#SESEventWebhookView.handle_deliveryc                 C   r   )Nr   r   )r   r   send_receivedr   r   r   r   r     r   zSESEventWebhookView.handle_sendc                 C   r   )Nopenr   )r   r   open_receivedr   r   r   r   r     r   zSESEventWebhookView.handle_openc                 C   r   )Nclickr   )r   r   click_receivedr   r   r   r   r     r   z SESEventWebhookView.handle_clickc           
      C   sv   | d}| |i }| d}| d}tjd|||d|id t| j|| jjd}	||	d| < |jd	i |	 d S )
Nr   r   r   z:Received %s notification: feedbackId: %s, feedbackType: %sr   r   )r   r   r   z%s_objr   )ra   r   r   dictr   r   r   r   )
r~   r   r   r   r   r   	event_objr   r   signal_kwargsr   r   r   r     s"   


z!SESEventWebhookView._handle_eventc                 C   s   t jdd|id d S )Nr   r   r   )r   r   r   r   r   r   r   3  s   z-SESEventWebhookView.handle_unknown_event_typeN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   z  s    ;		r   )-r   r^   rb   pytzdjango.utils.decoratorsr   django.views.decorators.csrfr   django.views.generic.baser   r   django_ses.deprecationr   urllib.requestr   urllib.errorr   r#   loggingdjango.httpr	   r
   django.views.decorators.httpr   django.core.cacher   django.core.exceptionsr   django.shortcutsr   
django_sesr   r   r   	getLoggerr   r   r   r2   r9   rC   rw   rz   r   r   r   r   r   r   <module>   sD    


16
 
0