o
    [h:                     @   sT  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
 d dlmZmZ d dl	mZ d dlmZmZmZmZmZ d d	lmZ d d
lmZmZ d dlmZmZmZ dd Zdd Zdd Z G dd de!Z"h dZ#G dd de$Z%dee defddZ&e&e
j'e
j(Z)G dd de*Z+dddddd d!efd"d#Z,G d$d% d%e!Z-d&d' Z.dS )(    )defaultdict)Decimal)reduce)ListDict)settings)dbdbq)common)get_models_moduleget_builtin_constantvalidate_alphanumericget_bots_moduleget_constants)RealWorldCurrency)ParticipantSession)BaseConstants	get_rolesget_rolec                 C   s   |r|| | } }|s| S )z8Return greatest common divisor using Euclid's Algorithm. abr   r   t/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/otree/session.pygcd   s   r   c                 C   s   | | t | | S )zReturn lowest common multiple.)r   r   r   r   r   lcm   s   r   c                  G   s
   t t| S )zReturn lcm of args.)r   r   )argsr   r   r   lcmm!   s   
r   c                   @      e Zd ZdS )SessionConfigErrorN__name__
__module____qualname__r   r   r   r   r    &       r    >   app_sequencenum_demo_participantsdocnamedisplay_namec                   @   s   e Zd ZedefddZedef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 )SessionConfigreturnc                 C      | d S )Nr&   r   selfr   r   r   r&   6      zSessionConfig.app_sequencec                 C   r-   )Nparticipation_feer   r.   r   r   r   r1   :   r0   zSessionConfig.participation_feec                 C   s2   g }| d D ]}t |dpd}|| qt| S )Nr&   players_per_group   )r   appendr   )r/   Zmin_multiple_listapp_nameZmin_multipler   r   r   get_lcm>   s
   zSessionConfig.get_lcmc                 C   s4   d}| d D ]}t |}|jj}t|t|}q|S )Nr3   r&   )r   Z	PlayerBotcasesmaxlen)r/   Z	num_casesr5   Zbots_moduler7   r   r   r   get_num_bot_casesF   s   zSessionConfig.get_num_bot_casesc                 C   s   dD ]}|| vrd| }t |qdD ]}|| vr#d| }t |qt| d dd | d }t|tt|krEd	}t || d t|d
krQd}t || d| d  | dd t| d | d< d S )N)r1   real_world_currency_per_pointz#SESSION_CONFIG_DEFAULTS is missing )r)   r&   r'   zSession config is missing r)   zsettings.SESSION_CONFIGS name)Zidentifier_descriptionr&   zsettings.SESSION_CONFIGS: app_sequence of "{}" must not contain duplicate elements. If you want multiple rounds, you should set num_rounds.r   z7settings.SESSION_CONFIGS: app_sequence cannot be empty.r*   r(    r1   )r    r   r9   setformat
setdefaultr   )r/   kmsgr&   r   r   r   cleanN   s0   

zSessionConfig.cleanc                 C   s^   g }| d D ]&}t |d}t|}|dkrd||}n|}t|dd|d}|| q|S )Nr&   
num_roundsr3   z{} ({} rounds)r(   r<   )r(   r)   )r   r   r>   getattrr4   )r/   r&   r5   rC   models_moduleZformatted_app_nameZsubsssnr   r   r   app_sequence_displayp   s   

z"SessionConfig.app_sequence_displayc                 C   s   dg}t jr|d |S )Nr1   r;   )r   Z
USE_POINTSr4   )r/   fieldsr   r   r   builtin_editable_fields   s   
z%SessionConfig.builtin_editable_fieldsc                        fdd   D S )Nc                    s<   g | ]\}}|t vr|  vrt|ttttfv r|qS r   )NON_EDITABLE_FIELDSrH   typeboolintfloatstr).0r@   vr.   r   r   
<listcomp>   s    z8SessionConfig.custom_editable_fields.<locals>.<listcomp>)itemsr.   r   r.   r   custom_editable_fields   s   
z$SessionConfig.custom_editable_fieldsc                 C   s   |   |   S )N)rH   rT   r.   r   r   r   editable_fields      zSessionConfig.editable_fieldsc                 C   s   d | d |S )Nz{}.{}r)   )r>   )r/   
field_namer   r   r   html_field_name   rV   zSessionConfig.html_field_namec                 C   s   | | }|  |}d|g}t|trd|rdndg}n1t|tr-dddd|d	g}n!t|ttfrAd	dd
ddt|g}nt|trNdd|d	g}d|d|| }|S )Nz	name='{}'ztype='checkbox'checkedr<   ztype='number'requiredzstep='1'z
value='{}'zclass='form-control'z
step='any'ztype='text'z6
        <tr><td><b>{}</b><td><input {}></td>
         )	rX   r>   
isinstancerL   rM   rN   r   rO   join)r/   rW   Zexisting_valuerX   Z
base_attrsattrshtmlr   r   r   editable_field_html   s@   




z!SessionConfig.editable_field_htmlc                    rI   )Nc                       g | ]}  |qS r   r`   rP   r@   r.   r   r   rR          z>SessionConfig.builtin_editable_fields_html.<locals>.<listcomp>)rH   r.   r   r.   r   builtin_editable_fields_html      z*SessionConfig.builtin_editable_fields_htmlc                    rI   )Nc                    ra   r   rb   rc   r.   r   r   rR      rd   z=SessionConfig.custom_editable_fields_html.<locals>.<listcomp>)rT   r.   r   r.   r   custom_editable_fields_html   rf   z)SessionConfig.custom_editable_fields_htmlN)r"   r#   r$   propertylistr&   r   r1   r6   r:   rB   rF   rH   rT   rU   rX   r`   re   rg   r   r   r   r   r+   3   s     "*r+   SESSION_CONFIGSSESSION_CONFIG_DEFAULTSc                 C   sV   i }| D ]$}t |}|| |  |d }||v r$d| }t||||< q|S )Nr)   zDuplicate SESSION_CONFIG name: )r+   updaterB   r    )rj   rk   SESSION_CONFIGS_DICTZconfig_dictZ
config_objZconfig_namerA   r   r   r   get_session_configs_dict   s   


rn   c                   @   r   )CreateSessionInvalidArgsNr!   r   r   r   r   ro      r%   ro   r<   NF)label	room_nameis_mturkis_demomodified_session_config_fieldsr,   c          -         s  d}zt |  }W n ty   d}	t|	| d w t| }|p#i }
|
 t@ }|r3td| ||
 |	  |
 }|d u rJt|d}n|| r[d|d ||}	t|	t|||||dt t  zyjfdd	ttd
|d
 D }t| t  ttttjjktjtjtj }d}|d D ]}t|}t|}t|d}||7 }ttd
|d
 }||t |j! 7 }|j" |j#}|j$}t%|} fdd	|D }t| t  t& j'dddd}|(d}|d u s ) r|}t*|| }g }|D ]\}}td
|d
 D ]}|+||||d q(qt| t&|j'dd }t,t} |D ]}!| |!j- +|!j qQg }"|D ]9\}}t.|}#d}$| | D ])}%td
|d
 D ]}&||$ }'|"+||||'d |%|&t/|#|&d |$d
7 }$qyqpqbt|" qt&tj'dtj0|i 1 D ]}(|(2 })t3|)dd }*|*r|*|( q4  |d urddl5m6}+ |+| },|,7 t  W S  t8y   t9  w )Nr   z:Session config "{}" not found in settings.SESSION_CONFIGS.z6The following session config fields are not editable:    zSSession Config {}: Number of participants ({}) is not a multiple of group size ({})r)   )configrp   rs   num_participantsrr   c                    s   g | ]	}t | d qS ))id_in_sessionsessionZ_session_code)r   )rP   rx   )ry   session_coder   r   rR   (  s    z"create_session.<locals>.<listcomp>r3   r&   rC   c                    s   g | ]} |d qS ))round_numberry   r   )rP   r{   )
Subsessionry   r   r   rR   U  s    
)ry   r{   idr2   )ry   subsession_idr{   id_in_subsessionr   )ry   r~   r{   Zparticipant_idgroup_idid_in_groupZ_roleZcreating_session)	ROOM_DICT):rm   KeyErrorro   r>   r+   copykeysrJ   rl   rB   r6   r8   r   r   addcommitcoderi   rangeZadd_allqueryr   r]   filterr}   Zorder_byZwith_entitiesallr
   Zget_pages_moduler   r   r9   Zpage_sequencer|   GroupPlayerr   r	   Z	filter_byZget_normalizedZ_has_group_by_arrival_timerM   r4   r   r~   r   r   Z_max_page_indexZget_subsessionsZget_user_defined_targetrD   Z_set_admin_report_app_namesZ
otree.roomr   Zset_session	Exceptiondelete)-Zsession_config_namerw   rp   rq   rr   rs   rt   Znum_subsessionsZsession_configrA   Zmodified_configZbad_keysZsession_lcmZparticipantsZparticipant_valuesZ	num_pagesr5   Zviews_modulerE   rC   Zround_numbersr   r   Z	ConstantsZsubsessionsZppgZnum_groups_per_roundZgroups_to_createZss_idZss_rdr   groupsZgroups_lookupgroupZplayers_to_createZrolesZparticipant_indexr   r   ZparticipantZ
subsessiontargetfuncr   roomr   )r|   ry   rz   r   create_session   s  


	









r   c                   @   r   )CreateSessionErrorNr!   r   r   r   r   r     r%   r   c               
   K   s0   zt di | W S  ty } zt|d}~ww )zf
    catch it at an inner level,
    so we can give smaller tracebacks on 'creating session' page
    Nr   )r   r   r   )kwargsexcr   r   r    create_session_traceback_wrapper  s   r   )/collectionsr   decimalr   	functoolsr   typingr   r   Zotreer   Zotree.databaser   r	   r
   Zotree.commonr   r   r   r   r   Zotree.currencyr   Zotree.modelsr   r   Zotree.constantsr   r   r   r   r   r   r   r    rJ   dictr+   rn   rj   rk   rm   
ValueErrorro   r   r   r   r   r   r   r   <module>   sL    	 
	
 P