o
    [h:                     @   s  d dl 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mZ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 d dl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$ e%dZ&eG dd dZ'e j(dd Z)defddZ*G dd de"Z+edg dZ,dee, fddZ-d ee, dee.ee, f fd!d"Z/G d#d$ d$e"Z0d%e.de.fd&d'Z1d(ee d ee, fd)d*Z2G d+d, d,e"Z3G d-d. d.e"Z4G d/d0 d0e"Z5dS )1    N)defaultdict
namedtuple)	dataclass)datetime)Decimal)ListDictUnionOptional)Request)Response)settings)values_flatdb)SessionParticipant)
TurkClient
MTurkError)ibis_loader)AdminSessionPage   )enqueue_admin_messageotreec                   @   sf   e Zd ZU eeef ed< eed< eed< eed< eed< eed< eed< e	ed< d	Z
ee ed
< d	S )MTurkSettingskeywordstitledescriptionframe_heighttemplateminutes_allotted_per_assignmentexpiration_hoursqualification_requirementsNgrant_qualification_id)__name__
__module____qualname__r	   strlist__annotations__intfloatr   r"   r
    r+   r+   x/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/otree/views/mturk.pyr      s   
 r   c               
   c   sR    zdV  W dS  t y( }  ztjddd tdt|  W Y d} ~ dS d} ~ ww )a  Alternative to get_mturk_client, for when we need exception handling
    in admin views, we should pass it, so that we can show the user the message
    without crashing.
    for participant-facing views and commandline tools, should use get_mturk_client.
    NzMTurk errorT)exc_infodanger)r   loggererrorr   repr)excr+   r+   r,   ReportMTurkErrors%   s   r3   requestc                 C   s4   | j j }d|v r|ddd }|dv rdS dS )z_This method validates if oTree are published on a public domain
    because mturk need it

    :r   r   )	localhostz	127.0.0.1FT)urlhostnamelowersplit)r4   hostr+   r+   r,   in_public_domain3   s   r<   c                   @   s8   e Zd ZeeeddoeeddZdd Zdd ZdS )MTurkCreateHITZAWS_ACCESS_KEY_IDNZAWS_SECRET_ACCESS_KEYc                 C   sD   | j }|jd }tjdk}| jo|}t||jd | || j|dS )Nmturk_hit_settingsUSDparticipation_fee)mturk_settingsr@   mturk_num_workersmturk_readyaws_keys_existis_usd)sessionconfigr   ZREAL_WORLD_CURRENCY_CODErD   dictrB   )selfrF   rA   rE   rC   r+   r+   r,   vars_for_templateJ   s   


z MTurkCreateHIT.vars_for_templatec              
   C   sZ  | j }t|  d}t|s|sd}t|S tdi |jd }| jj	d|j
d}|j}t|ttfr:d|}tdj|j|j|d}	|j|j|| tt|jd	 d
|j td|j d|j
|	d	}
|sq|j|
d< t ) t j!|
|dd }|d |_"|d |_#||_$|d |_%|j&pd|_'W d    n1 sw   Y  | j(d|j
dS )Nuse_sandboxzSoTree must run on a public domain for Mechanical Turk (e.g. not a localhost server)r>   Z
MTurkStartcodez, zotree/MTurkHTMLQuestion.html)Zuser_templater   	start_urlr@   <   i  zotree_{})	ZTitleDescriptionKeywordsZMaxAssignmentsZRewardZAssignmentDurationInSecondsZLifetimeInSecondsUniqueRequestTokenZQuestionZQualificationRequirementsrK   ZHITHITIdZ
HITGroupIdZ
Expiration r=   r+   ))rF   boolget_post_datagetr<   r   r   rG   r4   Zurl_forrM   r   
isinstancer'   tuplejoinr   loadrenderr   r   r   r   rB   r&   r*   r   r)   r    formatr!   r3   r   Z
create_hitmturk_HITIdZmturk_HITGroupIdmturk_use_sandboxmturk_expirationr"   Zmturk_qual_idredirect)rI   r4   rM   rF   rK   msgrA   rN   r   Zhtml_questionZmturk_hit_parametershitr+   r+   r,   post[   sV   





zMTurkCreateHIT.post)	r#   r$   r%   rV   getattrr   rD   rJ   re   r+   r+   r+   r,   r=   B   s    
r=   
Assignment	worker_idassignment_idstatusanswerreturnc             	   C   sv   g }t | dg dd}	 tj||d}|d s	 |S |d D ]}|t|d |d |d	 |d
 d q|d |d< q)Nd   )	SubmittedApprovedRejected)rT   Z
MaxResultsZAssignmentStatusesTrS   ZAssignmentsWorkerIdAssignmentIdZAssignmentStatusZAnswerrh   Z	NextToken)rH   r   Zlist_assignments_for_hitappendrg   )hit_idrK   Zassignmentsargsresponsedr+   r+   r,   get_all_assignments   s,   ry   all_assignmentsc                 C   s(   t t}| D ]}||j |j q|S N)r   r'   rk   rt   ri   )rz   workers_by_status
assignmentr+   r+   r,   get_workers_by_status   s   r~   c                   @   s   e Zd Zdd ZdS )MTurkSessionPaymentsc                    s  | j   jstddS t < t j jd}t jt	j
d kd}dd |D }t|t| }|D ]}tjt|dd jd	 q4W d    n1 sMw   Y  t| fd
d}|d}|d}|d}	|	||fD ]}
t|
| qntd|||	 jd |dS )NF)	published)ru   rK   mturk_assignment_idc                 S   s   g | ]
}|j d kr|jqS )ro   )rk   rj   ).0ar+   r+   r,   
<listcomp>   s    z:MTurkSessionPayments.vars_for_template.<locals>.<listcomp>zEAuto-rejecting because this assignment was not found in our database.rs   ZRequesterFeedbackrS   c                    s   t  jtj|  S r{   )r'   pp_setfilterr   mturk_worker_idin_)rk   rF   r|   r+   r,   get_participants_by_status   s
   zJMTurkSessionPayments.vars_for_template.<locals>.get_participants_by_statusrp   rq   ro   Tr@   )r   participants_approvedparticipants_rejectedparticipants_not_reviewedr@   auto_rejects)rF   r_   rH   r3   ry   r`   r   r   r   r   r   setr   reject_assignmentr~   add_answersrG   )rI   rz   Zassignment_ids_in_dbZsubmitted_assignment_idsr   rj   r   r   r   r   lstr+   r   r,   rJ      sV   
z&MTurkSessionPayments.vars_for_templateN)r#   r$   r%   rJ   r+   r+   r+   r,   r      s    r   xmlc                 C   sl   | sdS ddl m} || }|D ]"}|d jdkr3t|d j}z	|d d W   S    Y  dS qdS )NrU   r   )ElementTreeZtaskAnswersr   Zcompletion_code)Z	xml.etreer   Z
fromstringtextjsonloads)r   r   rootZansZanswer_datar+   r+   r,   get_completion_code   s   
r   participantsc                 C   s>   i }|D ]}|j ||j< q| D ]}d|_t||j |_qd S )NF)rl   ri   Z
_is_frozenr   r   Zmturk_answers_formatted)r   rz   Zanswersr}   pr+   r+   r,   r     s   r   c                   @      e Zd ZdZdZdd ZdS )PayMTurk	only POSTz/PayMTurk/{code}c                 C   sn  t jt|d}d}d}|  }| jd|jd}|jtj	
|d}|D ]r}	|	j|}
z2|
dkrOtjt|	j	|	jdt|
d|	j	|	jdd|jd	 tjt|	jd
|jd	 |d7 }W q& ty } z,d|	 t|}td| t| |d7 }|dkr|W  Y d }~  S W Y d }~q&d }~ww d|}|dkr|d|7 }td| |S td| |S )NrL   r   r   workersz{0:.2f}z{}_{}z	Thank you)rr   rs   ZBonusAmountrR   ZReasonrS   )rs   r   zACould not pay {} because of an error communicating with MTurk: {}r.   
   zSuccessfully made {} payments.z {} payments failed.warningsuccess)r   
get_or_404r   rW   rb   rM   r   r   r   r   r   getlistpayoffZto_real_world_currencyr   Z
send_bonusrH   r   r^   r   r`   Zapprove_assignment	ExceptionZ_numeric_labelr&   r   r/   r0   )rI   r4   rM   rF   Zsuccessful_paymentsZfailed_paymentsZ	post_dataZpayment_page_responser   r   r   erc   r+   r+   r,   re     s`   






zPayMTurk.postNr#   r$   r%   __doc__Zurl_patternre   r+   r+   r+   r,   r         r   c                   @   r   )RejectMTurkz	POST onlyz/RejectMTurk/{code}c                 C   s   t jt|d}t , |jtj| 	 
dD ]}tjt|jdd|jd qtdd W d    n1 s9w   Y  | jd|dS )	NrL   r   rU   r   rS   r   z!Rejected the selected assignmentsr   )r   r   r   r3   r   r   r   r   r   rW   r   r   r   rH   r   r`   r   rb   )rI   r4   rM   rF   r   r+   r+   r,   re   b  s   zRejectMTurk.postNr   r+   r+   r+   r,   r   ]  r   r   c                   @   r   )MTurkExpireHITr   z/MTurkExpireHIT/{code}c                 C   sr   t jt|d}t   tddd }tjt|j	|d|j
d ||_W d    n1 s-w   Y  | jd|dS )NrL   i  r   )rT   ZExpireAtrS   r=   )r   r   r   r3   r   	timestampr   Zupdate_expirationrH   r_   r`   ra   rb   )rI   r4   rM   rF   Z
expirationr+   r+   r,   re   }  s   	zMTurkExpireHIT.postNr   r+   r+   r+   r,   r   x  r   r   )6
contextlibr   loggingcollectionsr   r   dataclassesr   r   decimalr   typingr   r   r	   r
   Zstarlette.requestsr   Zstarlette.responsesr   r   r   Zotree.databaser   r   Zotree.modelsr   r   Zotree.mturk_clientr   r   Zotree.templatingr   Zotree.views.cbvr   Zcbvr   	getLoggerr/   r   contextmanagerr3   r<   r=   rg   ry   r&   r~   r   r   r   r   r   r   r+   r+   r+   r,   <module>   sN    

P
	>	G