o
    [hZK                     @   s  d dl Z d dlmZ d dlZd dlZd dlmZ d dlmZm	Z	m
Z
 d dlmZmZ d dlmZ d dlZd dlZd dlm  m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mZm Z  d d
l!m"Z" d dl#m$Z$ d dl%m&Z&m'Z'm(Z( d dl%Zd dlm)Z) d dl*m+Z+m,Z, d dl-m.Z. d dlm/Z/m0Z0 ddl1m2Z2 ddl2m3Z3 e4 gZ5dd Z6G dd dej7Z8G dd de2j0Z9G dd de/Z:G dd de/Z;G dd dej7Z<G d d! d!e/Z=G d"d# d#e/Z>G d$d% d%e/Z?G d&d' d'e/Z@G d(d) d)e/ZAG d*d+ d+e/ZBG d,d- d-ej7ZCG d.d/ d/e/ZDd0eEfd1d2ZFd0eEfd3d4ZGG d5d6 d6e0ZHG d7d8 d8e0ZIG d9d: d:e0ZJG d;d< d<e0ZKG d=d> d>eZLG d?d@ d@ej7ZMG dAdB dBe0ZNG dCdD dDeZOG dEdF dFeZPdS )G    N)BackgroundTask)HTTPEndpoint)JSONResponseRedirectResponseResponse)
validatorswidgets)html5)export)settings)get_models_module
DebugTableAUTH_COOKIE_NAMEAUTH_COOKIE_VALUE)ADVANCE_SLOWEST_BATCH_SIZE)RealWorldCurrency)values_flatsave_sqlite_dbdb)Session)SESSION_CONFIGS_DICTSessionConfig)get_template_name_if_exists)AdminSessionPage	AdminView   )cbv)enqueue_admin_messagec                 C   s   | sdS |  ddS )z%Converts 'first_name' to 'first name' _ )replace)name r#   x/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/otree/views/admin.pypretty_name'   s   r%   c                       s   e Zd Ze Zdd eD Zejee	e
ddidZeje ejddgdd	d
dZe Zeje dZ fddZ fddZ  ZS )CreateSessionFormc                 C   s   g | ]
}|d  |d fqS )r"   display_namer#   ).0sr#   r#   r$   
<listcomp>0   s    zCreateSessionForm.<listcomp>classzform-select)choicesr   	render_kwr   minTzform-control w-autoZ	autofocusr+   r   r-   )widgetc                    sJ   t  j|i | | jjrd}dtj d}nd}d}|| j_|| j_d S )Nz%Number of MTurk workers (assignments)z{Since workers can return an assignment or drop out, some "spare" participants will be created: the oTree session will have z? times more participant objects than the number you enter here.zNumber of participantsr   )	super__init__is_mturkZobject_datar   ZMTURK_NUM_PARTICIPANTS_MULTIPLEnum_participantslabeldescription)selfargskwargsr7   r8   	__class__r#   r$   r4   E   s   zCreateSessionForm.__init__c                    sH   t   sdS t| jj }| }| jj| r| jjd t	| j S )NFz,Please enter a valid number of participants.)
r3   validater   session_configdataZget_lcmr6   errorsappendbool)r9   configlcmr<   r#   r$   r>   V   s   
zCreateSessionForm.validate)__name__
__module____qualname__r   valuesZsession_configsZsession_config_choiceswtformsSelectFieldvalidators_requireddictr?   IntegerFieldwtvalidatorsZDataRequiredNumberRanger6   ZBooleanFieldr5   StringField	wtwidgetsHiddenInputZ	room_namer4   r>   __classcell__r#   r#   r<   r$   r&   .   s     

r&   c                       s,   e Zd ZdZdZdd Z fddZ  ZS )CreateSessionzotree/CreateSession.htmlz/create_sessionc                 C   s   t t| jjddS )Nr5   )r5   )r&   rC   requestquery_paramsgetr9   r#   r#   r$   get_formg   s   zCreateSession.get_formc                    s   t  jddt i|}|S )NZconfigsr#   )r3   get_context_datar   rI   )r9   r;   xr<   r#   r$   r[   m   s   
zCreateSession.get_context_data)rF   rG   rH   Ztemplate_nameurl_patternrZ   r[   rT   r#   r#   r<   r$   rU   c   s
    rU   c                   @      e Zd ZdZdd ZdS )SessionSplitScreenzELaunch the session in fullscreen mode
    only used in demo mode
    c                    s&    fdd j  D }t j |dS )Nc                    s    g | ]} j jj| d qS )path)rV   base_urlr!   Z
_start_url)r(   ZparticipantrY   r#   r$   r*   ~   s    z8SessionSplitScreen.vars_for_template.<locals>.<listcomp>)sessionparticipant_urls)rc   get_participantsrM   )r9   rd   r#   rY   r$   vars_for_template}   s   
z$SessionSplitScreen.vars_for_templateN)rF   rG   rH   __doc__rf   r#   r#   r#   r$   r_   x   s    r_   c                   @      e Zd Zdd ZdS )SessionStartLinksc                 C   s   | j }| }ddlm} t|jd|j}g }|D ]}tj	
|}| jjj|d}|| qt|j|d}	|rH|	j|| j|dd |	S ddlm}
 | jjj|
d	|jd
d}|	j|t|t|dkd |	S )Nr   )ParticipantZid_in_sessionr`   )use_browser_botsrd   T)Zroom_wide_urlroomZcollapse_links)reverseZJoinSessionAnonymously)Zanonymous_code   )anonymous_urlr6   Zsplitscreen_mode_on)rc   Zget_roomotree.modelsrj   r   Zpp_setorder_bycodeotreecommonZparticipant_start_urlrV   rb   r!   rB   rM   rk   updateZget_room_wide_urlZ
otree.asgirm   Z_anonymous_codelen)r9   rc   rl   rj   Zp_codesrd   rr   Zrel_urlurlcontextrm   ro   r#   r#   r$   rf      sB   

z#SessionStartLinks.vars_for_templateNrF   rG   rH   rf   r#   r#   r#   r$   ri          ri   c                   @   sD   e Zd Ze ZejddZe Zej	e
ddddZg dZdS )	SessionEditPropertiesForm   )Zplaces3Z40)rowscolsr-   participation_feereal_world_currency_per_pointr7   commentN)rF   rG   rH   rJ   ZDecimalFieldr   r   rQ   r7   ZTextAreaFieldrM   r   field_namesr#   r#   r#   r$   r{      s    r{   c                   @   s    e Zd ZeZdd Zdd ZdS )SessionEditPropertiesc                 C   sD   | j }|j}tt|d |d |j|jdd}|jr t |j	_
|S )Nr   r   r   )r@   )rc   rD   r{   rM   r7   r   Zmturk_HITIdrR   rS   r   r2   )r9   rc   rD   formr#   r#   r$   rZ      s   zSessionEditProperties.get_formc                 C   s|   | j }|jj|_|jj|_|jj}t|jj}|j }|d ur&t	||d< |d ur.||d< ||_t
dd | jd|jdS )Nr   r   successzProperties have been updatedr   rr   )rc   r7   r@   r   r   floatr   rD   copyr   r   redirectrr   )r9   r   rc   r   Zrwc_per_pointrD   r#   r#   r$   
form_valid   s   



z SessionEditProperties.form_validN)rF   rG   rH   r{   
form_classrZ   r   r#   r#   r#   r$   r      s    r   c                   @   rh   )SessionPaymentsc                 C   sV   | j }| }d}d}|rtdd |D }|t| }t|dtjv |||jd dS )Ng        c                 s   s    | ]}|  V  qd S N)Zpayoff_plus_participation_fee)r(   ppr#   r#   r$   	<genexpr>   s    
z4SessionPayments.vars_for_template.<locals>.<genexpr>finishedr   )participantsZshow_finished_statustotal_paymentsmean_paymentr   )rc   re   sumrv   rM   r   ZPARTICIPANT_FIELDSrD   )r9   rc   r   r   r   r#   r#   r$   rf      s    z!SessionPayments.vars_for_templateNry   r#   r#   r#   r$   r      rz   r   c                   @   r^   )SessionDataAjaxz/session_data/{code}c                 C   s   t t| j}t|S r   )listr
   Zget_rows_for_data_tabrc   r   )r9   rV   rr   r~   r#   r#   r$   rX      s   zSessionDataAjax.getNrF   rG   rH   r]   rX   r#   r#   r#   r$   r          r   c                   @   rh   )SessionDatac                 C   s   | j }g }i }g }g }|jd D ]?}t|}|jj|d }t|\}	}
}|	|
 | ||< td|d D ]}t	|	|
|d}|
| |
| |
| q6qt	|t|||tjjdS )NZapp_sequence)rc   r   )pfieldsgfieldssfields)tablesZfield_headers_jsonapp_names_by_subsessionround_numbers_by_subsessionDATA_EXPORT_HASH)rc   rD   r   
Subsessionobjects_filtercountr
   Zget_fields_for_data_tabrangerM   rB   jsondumpsrs   rt   r   )r9   rc   r   Zfield_headersr   r   app_namemodels_moduleZ
num_roundsr   r   r   round_numbertabler#   r#   r$   rf     s>   


zSessionData.vars_for_templateNry   r#   r#   r#   r$   r     rz   r   c                   @   rh   )SessionMonitorc                    sL   t  }tddddddddd	d
	  fdd|D }t|t| jjtdS )Nr   ZCodeLabelProgressZAppZRoundz	Page namezWaiting forZTime)	Z_numeric_labelrr   r7   Z_current_pageZ_current_app_nameZ_round_numberZ_current_page_nameZ_monitor_noteZ_last_page_timestampc                    s   g | ]} | qS r#   r#   )r(   colZdisplay_namesr#   r$   r*   6      z4SessionMonitor.vars_for_template.<locals>.<listcomp>)column_namesZ
socket_urlr   )r
   Zget_fields_for_monitorrM   channel_utilsZsession_monitor_pathrc   rr   r   )r9   r   r   r#   r   r$   rf   (  s$   z SessionMonitor.vars_for_templateNry   r#   r#   r#   r$   r   '  rz   r   c                   @   rh   )SessionDescriptionc                 C   s   t t| jjdS )N)rD   )rM   r   rc   rD   rY   r#   r#   r$   rf   @  s   z$SessionDescription.vars_for_templateNry   r#   r#   r#   r$   r   ?  rz   r   c                       sP   e Zd ZejddidZeje	 ej
ddgddddZ fd	d
Z  ZS )AdminReportFormr+   zform-controlr   r   r.   Tr0   r1   c                   s   || _ | j  }| j  }tt||| _|d }|ds$|d |d< | j|d  }t|dd}d|  kr=|ksBn ||d< t j	|i | g }	|D ]}
|
 d| j|
  d}|	
|
|f qO|	| j_dS )	zmwe don't validate input it because we don't show the user
        an error. just coerce it to something rightr@   r   r   r   r   z (z rounds)N)rc   Z_admin_report_appsZ_admin_report_num_rounds_listrM   zipZrounds_per_apprX   intr3   r4   rB   r   r,   )r9   rc   r:   r;   Zadmin_report_appsZnum_rounds_listr@   Zrounds_in_this_appr   Zapp_name_choicesr   r7   r<   r#   r$   r4   N  s"   


zAdminReportForm.__init__)rF   rG   rH   rJ   rK   r   h5fieldsrN   rO   OptionalrP   r   r4   rT   r#   r#   r<   r$   r   D  s    r   c                       s$   e Zd Zdd Z fddZ  ZS )AdminReportc                 C   s"   t t| jj| jd}|  |S )N)r@   rc   )r   rM   rV   rW   rc   r>   r9   r   r#   r#   r$   rZ   n  s
   zAdminReport.get_formc                    s   |d }|j j}t|}|jj| j|jjd}| }t|dd }|r(||}ni }t	d|
 dg| _| }	t|	 d|	 dg}
tj|}t jd	||
d|}|||j< d|v saJ || |S )
Nr   )rc   r   vars_for_admin_report)titler~   z/admin_report.htmlz/AdminReport.html)
subsessionuser_templaterc   r#   )r   r@   r   r   Zobjects_getrc   r   Zget_user_defined_targetgetattrr   itemsZdebug_tablesZget_folder_namer   rs   rt   Zget_constantsr3   r[   rF   ru   )r9   r;   r   r   r   r   targetfuncr   Z	app_labelr   Z	Constantsrx   r<   r#   r$   r[   u  s<   



zAdminReport.get_context_data)rF   rG   rH   rZ   r[   rT   r#   r#   r<   r$   r   m  s    r   returnc                  C   sB   dd l } z| jjddd}t| dW S    dg i Y S )Nr   z'https://pypi.python.org/pypi/otree/json   )timeoutzutf-8releases)urllib.requestrV   urlopenr   loadsreaddecode)urllibfr#   r#   r$   get_json_from_pypi  s   r   c            	      C   sp   t d} tj}t }|d }g d}d}|D ]}| |}|r1dd | D }||kr1|}|}qt||dS )zNreturn a dict because it needs to be json serialized for the AJAX
    responsez^(\d+)\.(\d+)\.(\d+)$r   )r   r   r   r   c                 S   s   g | ]}t |qS r#   )r   )r(   nr#   r#   r$   r*     r   z2get_installed_and_pypi_version.<locals>.<listcomp>)Znewest	installed)recompilers   __version__r   matchgroupsrM   )	Z	semver_reZinstalled_dottedr@   r   Znewest_tupleZnewest_dottedreleaseZrelease_matchZrelease_tupler#   r#   r$   get_installed_and_pypi_version  s   

r   c                       s    e Zd ZdZ fddZ  ZS )ServerCheckz/server_checkc              	      sF   t jjj }d| v }t jdtj	tj
tj
dv t ||d|S )Npostgres>   ZDEMOZSTUDY)debugZ
auth_levelZauth_level_okZpypi_resultsis_postgresbackend_namer#   )rs   ZdatabaseZenginerw   Zget_backend_namelowerr3   r[   r   DEBUGZ
AUTH_LEVELr   )r9   r;   r   r   r<   r#   r$   r[     s   zServerCheck.get_context_data)rF   rG   rH   r]   r[   rT   r#   r#   r<   r$   r     s    r   c                   @   r^   )AdvanceSessionz/AdvanceSession/{code}c                 C   s   t jt|d}|  tdS )Nr   ok)r   Z
get_or_404r   Zadvance_last_place_participantsr   )r9   rV   rr   rc   r#   r#   r$   post  s   zAdvanceSession.postNrF   rG   rH   r]   r   r#   r#   r#   r$   r     r   r   c                   @   r^   )Sessionsz	/sessionsc                 C   sF   t | jjd}tjd|dtj 	 }t
||tjdddS )NarchivedF)Zis_demor   T)r   )
is_archivesessionsZarchived_sessions_exist)rC   rV   rW   rX   r   r   rq   idZdescallrM   Zobjects_exists)r9   r   r   r#   r#   r$   rf     s   
zSessions.vars_for_templateN)rF   rG   rH   r]   rf   r#   r#   r#   r$   r     r   r   c                   @   r^   )ToggleArchivedSessionsz/ToggleArchivedSessionsc                 C   s>   |   }|d}ttj|D ]}|j |_q| dS )Nrc   r   )Zget_post_datagetlistr   r   rr   in_r   r   )r9   rV   Z	post_dataZ	code_listrc   r#   r#   r$   r     s
   

zToggleArchivedSessions.postNr   r#   r#   r#   r$   r     r   r   c                   @   r^   )SaveDBz/SaveDBc                 C   s0   dd l }dd l}d|jv rt  tt| S )Nr   Zdevserver_inner)sysosargvr   r   strgetpid)r9   rV   r   r   r#   r#   r$   r     s
   
zSaveDB.postNr   r#   r#   r#   r$   r     r   r   c                       s,   e Zd Ze Ze Z fddZ  ZS )	LoginFormc                    s@   t   sdS | jjtjkr| jjtjkrdS | jj	d dS )NFTzLogin failed)
r3   r>   usernamer@   r   ADMIN_USERNAMEpasswordADMIN_PASSWORDrA   rB   rY   r<   r#   r$   r>     s   
zLoginForm.validate)	rF   rG   rH   rJ   rQ   r   r   r>   rT   r#   r#   r<   r$   r   
  s    r   c                   @   s$   e Zd ZdZeZdd Zdd ZdS )Loginz/loginc                 C   s4   g }dD ]}t t|d s|| d qt|dS )N)r   r   z is undefined)warnings)r   r   rB   rM   )r9   r   Zsettingr#   r#   r$   rf     s   
zLogin.vars_for_templatec                 C   s   t | jjt< | dS )NZ	DemoIndex)r   rV   rc   r   r   r   r#   r#   r$   r   &  s   
zLogin.form_validN)rF   rG   rH   r]   r   r   rf   r   r#   r#   r#   r$   r     s
    r   c                   @   r^   )Logoutz/logoutc                 C   s   |j t= t|dddS )Nr   .  status_code)rc   r   r   Zurl_forr9   rV   r#   r#   r$   rX   .  s   z
Logout.getNr   r#   r#   r#   r$   r   +  r   r   c                   @   r^   )RedirectToDemo/c                 C   s   t dddS )Nz/demor   r   )r   r   r#   r#   r$   rX   6  s   zRedirectToDemo.getN)rF   rG   rH   Zurl_namerX   r#   r#   r#   r$   r  3  r   r  )Qr   Zstarlette.backgroundr   r   rJ   Zstarlette.endpointsr   Zstarlette.responsesr   r   r   r   rO   r   rR   Zwtforms.fieldsr	   r   rs   Zotree.bots.browserZotree.channels.utilsZchannelsutilsr   Zotree.commonrp   Zotree.views.cbvr
   r   r   r   r   r   Zotree.constantsr   Zotree.currencyr   Zotree.databaser   r   r   r   Zotree.sessionr   r   Zotree.templatingr   r   r   r   r   r   ZInputRequiredrL   r%   ZFormr&   rU   r_   ri   r{   r   r   r   r   r   r   r   r   rM   r   r   r   r   r   r   r   r   r   r   r  r#   r#   r#   r$   <module>   sj    
5+)#)3