HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/blueprints/widgets/__pycache__/rest_api.cpython-310.pyc
o

�we�Q�@s:ddlZddlmZddlZddlZddlZddlZddlm	m
Zddlm
Z
mZmZmZmZddlmZddlmZmZddlmZmZddlmZddlmZdd	lmZdd
l m!Z!ddl"m#Z#m$Z$ddl%m&Z&m'Z'dd
l(m)Z)ddl*m+Z+ddl,m-Z-m.Z.ddl/m0Z0m1Z1m2Z2ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9ddl:m;Z;ddl<m=Z=ddl>m?Z?ddl@mAZAddlBmCZCedeDdd�ZEdZFdOdd�ZGeEjHdd gd!�ed"d#���ZIeEjHdd$gd!�ed%d&���ZJeEjHd'd$gd!�ed(d)���ZKeEjHd*d$gd!�ed+d,���ZLeEjHd-d$d.gd!�ed/d0���ZMeEjHd1d gd!�ed2d3���ZNeEjHd1d4gd!�ed5d6���ZOeEjHd7d gd!�ee;d8d9����ZPeEjHd:d gd!�e�d;d<���ZQeEjHd=d$gd!�e'jRe�d>d?����ZSeEjHd@d$gd!�e'jRe�dAdB����ZTeEjHdCd gd!�e'jRe�dDdE����ZUdFdG�ZVeEjHdHd gd!�e-dIdJ���ZWdKdL�ZXdMdN�ZYdS)P�N)�uuid4)�request�jsonify�
make_response�	Blueprint�current_app)�cross_origin)�current_user�login_required)�and_�or_)�IntegrityError)�	load_only)�
NoResultFound)�text)�func�case)�db�csrf)�subaccount_client)�	bw_client)�rest_method�rest_partnership_account�)�Widget�AgentAssignment�User)�BandwidthRouting�Routing�add_widget_lead�phonecall_inprogress�NoAgentsException�after_call_events)�subscription_required)�Phone)�Lead)�Agent)�Subscription�widgets_api�	templates)�template_folderi�Q��cCstt|d�|�S)z9 Build an Ajax response with the given message and code. )�error)rr)�message�
error_code�r/�G/home/arjun/projects/buyercall/buyercall/blueprints/widgets/rest_api.py�
json_error-sr1z
/api/outbound�GET)�methodscCs�tj�dd�}ttj�dd��}tj�dd�}ttj�dd��}ttj�d	d
��}|dkr/d
}tj}tjr8tj}gd�}tj	�
td
dddd���tj|k�}t
j	�t
j|k��t
jt�d��d���t
j���}|}	|rzd�|�}
|�tj�|
��}	|	�|tj|jjkf��tjtjt|jj�d�dfg|jjd��d�tjtj tj!�}	|	}|t"t#|��vr�d�|||�}|�$t%|��}|�&|��'|�}dd�|�(�D�}
tj)}|
D]}|r�t*|j+�|d<q�d|d<q�t,tjd|	�-�|�-�|
d�S)z5
    Retrieves all widgets for the current user.
    z
search[value]�zorder[0][column]�-1z
order[0][dir]�asc�startr�length�c���)�id�name�
lead_count�
created_on�
updated_on�enabledr;r<r>r?r@rr=z%{}%N��else_�{} {}cs&g|]��fdd�tt���D��qS)csi|]}|�|�qSr/r/)�.0�i��rowr/r0�
<dictcomp>qsz*get_widgets.<locals>.<listcomp>.<dictcomp>)�range�len)rDr/rFr0�
<listcomp>ps�zget_widgets.<locals>.<listcomp>�F�draw)rM�recordsFiltered�recordsTotal�data).r�args�get�intr	�partnership_account_id�is_viewing_partnership�'get_user_viewing_partnership_account_idr�query�optionsr�filterr%�
with_entities�widget_guidr�sum�label�group_by�subquery�formatr<�ilike�	outerjoin�guid�cr;rr=�is_r>r?r@rIrJ�order_byr�offset�limit�all�subscription�bool�usage_over_limitr�count)�search�order�	directionrgrhrT�columns�total�leads�filtered�pattern�sorted_�
order_predrPrjrGr/r/r0�get_widgets2s�������
�����
�rx�POSTc
Cstt��}t��}t|d�|d<||d<tj}tjrtj}t	j
�t	j|k���}|j
�dd�}d�dd�|D��}tj
�tj|k���d}|dkrPt|�}nd	�|�}td
�||�|||d|d�}tj�|�tj
�tj|dktj|k���}	|	r�|	|_tj��t|j|jd
�S)z^
    Creates a new widget.
    Returns the ID of the newly created database row, as JSON.
    r<rc� r4css�|]	}|��r|VqdS�N)�isalnum)rD�er/r/r0�	<genexpr>�s�zadd_widget.<locals>.<genexpr>rrz0{}z{}{}@inbound.buyercall.com)�emailrTrcr<rX�fromNumberId�r;r<)�strrr�get_json�fix_namer	rTrUrVrrWrY�first�company�replace�joinrrmr`r�session�addr$r;�inbound�commitrr<)
rcrXrT�user_object�company_before_format�company_after_format�widget_count�widget_count_string�widget�phoner/r/r0�
add_widget�sN

����


���
r�z/api/outbound/disable/<int:id_>cC�Ptj}tjr	tj}tj�tdd���tj	|ktj|k��
�}d|_tj
��dS)Nr;r@Fr4�r	rTrUrVrrWrXrrYr;r�r@rr�r���id_rTr�r/r/r0�disable_widget����
r�z/api/outbound/enable/<int:id_>cCr�)Nr;r@Tr4r�r�r/r/r0�
enable_widget�r�r�z/api/outbound/delete/<int:id_>�DELETEcCsTtj}tjr	tj}tj�td���tj	|ktj|k��
�}tj�
|�tj��dS)Nr;r4)r	rTrUrVrrWrXrrYr;r�rr��deleter�r�r/r/r0�
delete_widget�s��
r�z/api/outbound/<int:id>cCs�z8tj}tjr
tj}tj�ttj|ktj|k���	�}|j
|jd<|j|jd<|j|jd<|j
|jd<t|j�WStyFtdd�YSw)z. Retrieves a single widget with the given ID. r<rcr;r�zWidget not found.�)r	rTrUrVrrWrYrr;�oner<rXrc�
inbound_idrrr)r;rTr�r/r/r0�
get_widget�s"���r��PUTcCs�t��}tj}tjr
tj}tj�t	tj
|ktj|k����}|d|_||_
tj�tj
|dktj|k���}|r=||_nd\|_|_tj��t|j
|jd�S)z% Changes a widget with the given id. r<r�)NNr�)rr�r	rTrUrVrrWrYrr;r�r<rXr$r�r�r�rr�r�r)r;�jsonrTr�r�r/r/r0�
change_widgets*��
��
r�z/api/outbound/phonenumberscCsdtj}tjr	tj}tj�tjtj	tj
tj��tj|ktj	�
d�tj�d����}tdd�|D�d�S)zc Retrieves the list of all phone numbers which the user is entitled to use
    in his widgets.
    )�tracking�priorityFcSs*g|]}|d|d|d|dd��qS)rr��)r;�type�number�
friendly_namer/)rD�nr/r/r0rK4s�z phonenumbers.<locals>.<listcomp>)rP)r	rTrUrVrr�rWr$r;r��phonenumberr�rY�in_�is_deactivatedrerir)rT�resultr/r/r0�phonenumbers s	

��
�r�z/api/outbound/settings/<guid>cCs�zYddlm}tj�tj��|j�jtjj��	tj
|k���}|js%WdS|jj
}|s0|jjj
}|jr?t�d�|j��WdSt|j�}|j|d<dD]	}||vrT||=qKt|�WStygtdd	�YSw)
zA Called by the deployed widget to retrieve display settings.
    r��PartnershipAccount)zWidget disabled.i�z5Available minutes exceeded for partnership_account {})zAvailable minutes exceeded.i��agentsAvailable)
�agents�scheduleTimezone�days�
availableFrom�availableTo�recordCalls�retryRouting�routeInSequence�
routeRandomly�routeSimultaneously�	voicemail�voicemailMessage�whisperMessagez,Widget not found, or has no agents assigned.r�)�'buyercall.blueprints.partnership.modelsr�rrWr��partnership_account�partnershipr��attrrYrcr�r@rjrl�log�infor`rT�dictrX�agents_availablerrr)rcr�r�rjr��keyr/r/r0�get_settings9sH�����



�
��r�z	/api/callcCspddlm}tj�d�}t��}|r2tj�t	tj
f��tt	jf��
tj��
|j��tj|k���}n
t�d�tdd�St�d�|��|du�r3z+|rVd	|vrV|d	d
vs`d|vrs|dd
vrst�dt|j�d
t|j�d�Wnt�dt|j�d
t|j�d�tdd�YS|jj}|s�|jjj}|jr�t�d�|j��tdd�Szkt|fi|��}|r�tdd�WSt|fi|��}ddlm }m}|j�|j!|jk���}|j�|j!|j"k���}	|j#j$dk�rt%|	j!d�}
t�d�t&|
��'||�nt�d�|j(}t)||	j!�}
t*|
��'||�Wnt+�y+tdd|j!d�YSwtd|j!d�Stdd�S)z� The endpoint that gets called when the lead presses 'Talk!' on the
    widget.

    Receives the widget GUID as a query string parameter, and the user's data
    in the JSON body.
    rr�rc�No guid providedF��successz#The call widget json request is: {}N�	firstName�r4rz�phoneNumberz(No lead fields provided for call widget � - �.z0partnership_account {} has exceeded their quota.T)�Partnershipr�r��voicezCalling Bandwidth number...zCalling Twilio number...�
ERR_NO_AGENTS)r��code�lead_id)r��callId),r�r�rrQrRr�rrWrbr�assignmentsr&�agentr�r�r�rYrcr�r�r,rr�r`r�r<rjrl�warningrTr rr�r;�partnership_idr�r�rr�	call_lead�twilio_subaccount_sidrrr!)r�rcr�r�rj�lead_on_call�leadr��partner_account�partner�client�subaccount_sidr/r/r0�callhsp
�� �


&�&
�
�

��
r�z/api/save_leadc
Cs�tj�d�}t��}|rtj�tj|k���}n
t	�
d�tdd�St	�d�
|��|dur�z?|r;d|vr;|ddvsYd	|vrE|d	dvsYd
|vrO|d
dvsYd|vrl|ddvrlt	�
dt|j�d
t|j�d�Wnt	�
dt|j�d
t|j�d�tdd�YSt|fddi|��}zt||�Wnty�}z
t	�
t���WYd}~nd}~wwtdd�Stdd�S)z� Saves the lead information in the database.

    Receives the widget GUID as a query string parameter, and the user's data in the JSON body.
    rcr�Fr�z/The after hours call widget json request is: {}Nr�r��lastNamer��emailAddressz#No lead fields provided for widget r�r��status�missedT)rrQrRr�rrWrYrcr�r�r,rr�r`r�r<rr"�	Exception�	traceback�
format_exc)rcr�r�r�r}r/r/r0�	save_lead�s6


&�&��

r�z/api/call_status/<int:lead_id>c
Cs�tjtjdtjddd�}z|�d�|��}|dkr!tdd�WS|dkr,td	dd
�WSWntyD}zt�	d�WYd}~nd}~wwtd	d�S)N�REDIS_CONFIG_URL�REDIS_CONFIG_PORTT)�host�port�decode_responsesz	CONNECT{}�1)�callConnectr5F)r�r,z2Cannot retrieve lead status - is Redis accessible?)
�redis�StrictRedisr�configrRr`rr�r�r,)r��redis_db�connectr}r/r/r0�call_status�s"����
r�csz�fdd�}��dd��dd��dd�}tj�ttj�|d�����}td	d
�|D��}|�D]
}||vr:|Sq0dS)zp Queries the database for all names starting with `old_name` and ensures
    no name clash is taking place.
    c3s*��Vt�d�D]	}d��|�Vq	dS)Nr�rC)�	itertoolsrmr`)rE��old_namer/r0�name_generator�s
��z fix_name.<locals>.name_generator�\z\\�%z\%�_z\_css�|]}|jVqdSr{)r<)rDr�r/r/r0r~s�zfix_name.<locals>.<genexpr>N)	r�rrWrYrr<�likeri�set)r�r�escaped_name�same_name_widgets�db_namesr<r/r�r0r��s���
��r�z/api/v1/outboundcCstj�tjtjk��tjt�	d��
d���tj���}t
j�tddddd���t
jtjk��|t
j|jjkf��t
jt
jt|jj�d�d	fg|jjd
��
d�t
jt
jt
j���}g}|D]}|�t|j|j|j|j|j|jd��q\tt|d��}d
|jd<|S)zV
    External REST API endpoint.

    Retrieves all widgets for the current user.
    rr=r;r<r>r?r@NrrA)r;r�r=r>r?r@)�outboundzno-cachez
Cache-Control) r%rWrYrTrr;rZr[rr\r]r^r_rrXrrbrcrdr<rr=rer>r?r@ri�appendr�rr�headers)rs�all_outboundrP�o�responser/r/r0�get_outboundsZ
����
����
�
�	
rcCs�tjtjdtjdd�}d|}|�dt|�dt|�|�dt|�dt|�|�dt|�dt|�|�d	t|�dt|�d
S)z� Sets a custom message to be used as the whisper message. The custom message will mostly be used for setting
        vehicle details. The remaining fields that are set are specifically for the notification mail.
    r�r��r�r�z" . . Vehicle information is . . . zCUSTOM_LEAD_MESSAGE:r�zCUSTOM_LEAD_YEAR:zCUSTOM_LEAD_MAKE:zCUSTOM_LEAD_MODEL:N�r�r�rr��setexr��DAYS)r��vehicle_details�vehicle_year�vehicle_make�
vehicle_modelr�r/r/r0�set_custom_agent_lead_textFs�rcCs8tjtjdtjdd�}|�dt|�dt|�dS)zH Saves the xml content in memory to be forwarded to CRM if need be.
    r�r�rzCUSTOM_LEAD_XML:r�Nr)r��
email_textr�r/r/r0�set_lead_xmlUs�r)r+)Zr��uuidr�loggingr�r��sysr��xml.etree.ElementTree�etree�ElementTree�et�flaskrrrrr�
flask_corsr�flask_loginr	r
�
sqlalchemyrr�sqlalchemy.excr
�sqlalchemy.ormr�sqlalchemy.orm.excr�sqlalchemy.sqlr�sqlalchemy.sql.expressionrr�buyercall.extensionsrr�buyercall.lib.util_twilior�buyercall.lib.util_bandwidthr�buyercall.lib.util_restrr�modelsrrr�routingrrrr r!r"�'buyercall.blueprints.billing.decoratorsr#�(buyercall.blueprints.phonenumbers.modelsr$�!buyercall.blueprints.leads.modelsr%�"buyercall.blueprints.agents.modelsr&�0buyercall.blueprints.billing.models.subscriptionr'�__name__r(rr1�routerxr�r�r�r�r�r�r�r��exemptr�r�r�r�rrrr/r/r/r0�<module>s� 
M4-I+/