o
    [h&                     @   s   d dl Z d dl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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mZ d dlmZ d dlmZ d dlmZ e dZ e Z!G dd deej"j#Z$dS )    N)datetime)Column)relationship)sqltypes)Response)settings)auto_advance_group)random_chars_8random_chars_join_codeget_admin_secret_codeget_builtin_constant)NoResultFound	MixinVars)RoomToSession)get_template_name_if_exists)TemplateLoadErrorotreec                   @   s  e Zd ZU dZeejjedZ	ee
d< edddddd	Zeejdd
ZeededdddZeeddd
Zeeddd
ZeejddZdd ZeejddZeejdd
ZeedddZeejdddZeejZeededddZeejddZ eejddZ!eedddZ"eej#Z$eej#e%j%dZ&dd Z'dZ(dd Z)e*dd Z+e*dd Z,e*d d! Z-d"d# Z.d$d% Z/d&d' Z0d(d) Z1d*d+ Z2d,d- Z3d.d/ Z4d0d1 Z5d2d3 Z6d4d5 Z7d6d7 Z8d8d9 Z9d:d; Z:d<S )=SessionZotree_session)defaultconfigZParticipantsessionZdynamiczall, delete-orphanT)Zback_populatesZlazyZcascadeZpassive_deletes)nullable   F)r   r   uniqueindexi,  c                 C   s   | j sJ t| jtj S N)is_mturkintnum_participantsr   ZMTURK_NUM_PARTICIPANTS_MULTIPLEself r!   {/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/otree/models/session.pymturk_num_workers:   s   
zSession.mturk_num_workers2    )r   r      )r   r   r      c                 C   sV   t   }|| j }|d }|dkr| dS |dkrdS |d }|dkr)| dS dS )NiQ    z	 days agoz	1 day agoi  z
 hours agoz< 1 hour ago)time_created)r    nowdeltadaysZ	num_hoursr!   r!   r"   _created_readablea   s   


zSession._created_readablez1 You can define it in the SESSION_FIELDS setting.c                 C   s   | j S r   )coder   r!   r!   r"   __unicode__p   s   zSession.__unicode__c                 C   
   | j d S )aThis method is deprecated from public API,
        but still useful internally (like data export)participation_feer   r   r!   r!   r"   r3   s      
zSession.participation_feec                 C   r1   )r2   real_world_currency_per_pointr4   r   r!   r!   r"   r6   y   r5   z%Session.real_world_currency_per_pointc                 C   s   | j ddS )Nuse_browser_botsF)r   getr   r!   r!   r"   r7      s   zSession.use_browser_botsc                 C   s&   | j drddl}||  dS dS )z
        It's for any exogenous data:
        - participant labels (which are not passed in through REST API)
        - participant vars
        - session vars (if we enable that)
        mock_exogenous_datar   N)r   r8   Z
shared_outr9   )r    Z
user_utilsr!   r!   r"   r9      s   zSession.mock_exogenous_datac                 C   sJ   g }| j d }|D ]}tj|}|jj| dd}|t| q	|S )Napp_sequencer   Zround_number)	r   r   commonget_models_moduleZ
SubsessionZobjects_filterorder_byextendlist)r    lstr:   Zappmodels_moduleZsubsessionsr!   r!   r"   get_subsessions   s   
zSession.get_subsessionsc                 C   s   t | jdS )NZid_in_session)r@   pp_setr>   r   r!   r!   r"   get_participants   s   zSession.get_participantsc                 C   s   | j rdnd}d|| jS )NZworkersandboxZwwwz-https://{}.mturk.com/mturk/preview?groupId={})mturk_use_sandboxformatmturk_HITGroupId)r    Z	subdomainr!   r!   r"   mturk_worker_url   s   zSession.mturk_worker_urlc                 C   s   | j o	| j t k S r   )mturk_expirationr)   r   r!   r!   r"   mturk_is_expired   s   zSession.mturk_is_expiredc                 C   s   | j o|   S r   )mturk_HITIdrK   r   r!   r!   r"   mturk_is_active   s   zSession.mturk_is_activec                    s   |   }tdd |D   fdd|D dtjj } dkr0|D ]}|d |  q"dS |D ]}|  |  tjj	j
t|jddid q2dS )	zthe problem with using the test client to make get/post requests is
        (1) this request already has the global asyncio.lock
        (2) there are apparently some issues with async/await and event loops.
        c                 S   s   g | ]}|j qS r!   Z_index_in_pages.0pr!   r!   r"   
<listcomp>   s    z;Session.advance_last_place_participants.<locals>.<listcomp>c                    s   g | ]	}|j  kr|qS r!   rN   rO   Zlast_place_page_indexr!   r"   rR      s    Nr   Zauto_advancedT)groupdata)rE   minr   	constantsZADVANCE_SLOWEST_BATCH_SIZEZ
initializeZ_visit_current_pageZ_submit_current_pageZchannelsutilsZsync_group_sendr   r/   )r    ZparticipantsZlast_place_participantsrQ   r!   rS   r"   advance_last_place_participants   s&   



z'Session.advance_last_place_participantsc                 C   s:   ddl m} ztj| dj}|| W S  ty   Y d S w )Nr   )	ROOM_DICTr;   )Z
otree.roomrZ   r   Zobjects_get	room_namer   )r    rZ   r[   r!   r!   r"   get_room   s   
zSession.get_roomc                 C   s   | j d ||  S )zFor a participant who has the given payoff,
        return their payoff_plus_participation_fee
        Useful to define it here, for data export
        r3   )r   Zto_real_world_currency)r    Zpayoffr!   r!   r"   "_get_payoff_plus_participation_fee   s   z*Session._get_payoff_plus_participation_feec              	   C   s   g }g }| j d D ]-}tj|}zt| d| dg W n	 ty(   Y q	w || |t|d q	d|| _	ddd |D | _
d S )Nr:   z/admin_report.htmlz/AdminReport.htmlZ
num_rounds;c                 s   s    | ]}t |V  qd S r   )str)rP   nr!   r!   r"   	<genexpr>  s    z6Session._set_admin_report_app_names.<locals>.<genexpr>)r   r   r<   r=   r   r   appendr   join_admin_report_app_names_admin_report_num_rounds)r    Zadmin_report_app_namesZnum_rounds_listZapp_namerB   r!   r!   r"   _set_admin_report_app_names   s   
z#Session._set_admin_report_app_namesc                 C   s   | j dS )Nr^   )rd   splitr   r!   r!   r"   _admin_report_apps  s   zSession._admin_report_appsc                 C   s   dd | j dD S )Nc                 S   s   g | ]}t |qS r!   )r   )rP   numr!   r!   r"   rR   	  s    z9Session._admin_report_num_rounds_list.<locals>.<listcomp>r^   )re   rg   r   r!   r!   r"   _admin_report_num_rounds_list  s   z%Session._admin_report_num_rounds_listc                 C   s
   t | jS r   )boolrd   r   r!   r!   r"   has_admin_report  s   
zSession.has_admin_reportN);__name__
__module____qualname__Z__tablename__r   r   databaseZ_PickleFielddictr   __annotations__r   rD   stStringlabelr	   r/   rL   rH   Booleanr   r#   rF   FloatrJ   Zmturk_qual_idZarchivedTextcommentr
   Z_anonymous_codeZis_demord   re   Integerr   r)   r*   r.   Z_SETATTR_NO_FIELD_HINTr0   propertyr3   r6   r7   r9   rC   rE   rI   rK   rM   rY   r\   r]   rf   rh   rj   rl   r!   r!   r!   r"   r       sx   
 




&	r   )%loggingr)   r   Z
sqlalchemyr   Zsqlalchemy.ormr   Zsqlalchemy.sqlr   rs   Zstarlette.responsesr   Zotree.commonr   Zotree.constantsZotree.databaser   Zotree.channels.utilsr   r	   r
   r   r   r   r   Zotree.models_concreter   Zotree.templatingr   Zotree.templating.loaderr   	getLoggerloggerZADMIN_SECRET_CODErp   Z
SSPPGModelr   r!   r!   r!   r"   <module>   s(    
