Example #1
0
    def vars_for_template(self):
        field_names = otree.export.get_field_names_for_live_update(Participant)
        display_names = {
            '_id_in_session': 'Spiller ID',
            'code': 'Kode',
            'label': 'Label',
            '_current_page': 'Side',
            '_current_app_name': 'Spil',
            '_round_number': 'Runde',
            '_current_page_name': 'Side navn',
            'status': 'Status',
            '_last_page_timestamp': 'Tid på siden',
        }

        callable_fields = {'status', '_id_in_session', '_current_page'}

        column_names = [display_names[col] for col in field_names]

        advance_users_button_text = (
            "Denne knap fremrykker alle spillere en side."
        )

        participants = self.session.participant_set.filter(visited=True)
        rows = []

        for participant in participants:
            row = {}
            for field_name in field_names:
                value = getattr(participant, field_name)
                if field_name in callable_fields:
                    value = value()
                row[field_name] = value
            rows.append(row)

        self.context_json = rows

        page_url_active = {"next_page": "active"}

        session = self.session
        room = session.get_room()

        session_start_urls = [
            self.request.build_absolute_uri(participant._start_url())
            for participant in session.get_participants()
        ]

        app = dict(SessionConfig(self.session.config))

        return dict(
            column_names=column_names,
            advance_users_button_text=advance_users_button_text,
            page_url_active=page_url_active,
            room_wide_url=room.get_room_wide_url(self.request),
            num_participants=len(session_start_urls),
            game_name=app
        )
Example #2
0
    def initialize_session(self, session_pk, case_number):
        self.prune()
        self.participants_by_session[session_pk] = []

        session = Session.objects.get(pk=session_pk)
        if case_number is None:
            # choose one randomly
            from otree.session import SessionConfig
            config = SessionConfig(session.config)
            num_cases = config.get_num_bot_cases()
            case_number = random.choice(range(num_cases))

        bots = make_bots(session_pk=session_pk,
                         case_number=case_number,
                         use_browser_bots=True)
        for bot in bots:
            self.participants_by_session[session_pk].append(
                bot.participant_code)
            self.browser_bots[bot.participant_code] = bot
Example #3
0
    def initialize_session(self, session_pk, case_number):
        self.prune()
        self.participants_by_session[session_pk] = []

        session = Session.objects.get(pk=session_pk)
        if case_number is None:
            # choose one randomly
            from otree.session import SessionConfig
            config = SessionConfig(session.config)
            num_cases = config.get_num_bot_cases()
            case_number = random.choice(range(num_cases))

        bots = make_bots(
            session_pk=session_pk, case_number=case_number, use_browser_bots=True
        )
        for bot in bots:
            self.participants_by_session[session_pk].append(
                bot.participant_code)
            self.browser_bots[bot.participant_code] = bot
Example #4
0
    def initialize_session(self, session_pk):
        self.prune()
        self.participants_by_session[session_pk] = []

        session = Session.objects.get(pk=session_pk)
        # choose one randomly
        from otree.session import SessionConfig
        config = SessionConfig(session.config)
        num_cases = config.get_num_bot_cases()
        # choose bot case number randomly...maybe reconsider this?
        # we can only run one.
        case_number = random.choice(range(num_cases))

        bots = get_bots(session_pk=session_pk, case_number=case_number)
        for bot in bots:
            self.participants_by_session[session_pk].append(
                bot.participant_code)
            self.browser_bots[bot.participant_code] = bot
        return {'ok': True}
Example #5
0
    def initialize_session(self, session_pk):
        self.prune()
        self.participants_by_session[session_pk] = []

        session = Session.objects.get(pk=session_pk)
        # choose one randomly
        from otree.session import SessionConfig
        config = SessionConfig(session.config)
        num_cases = config.get_num_bot_cases()
        # choose bot case number randomly...maybe reconsider this?
        # we can only run one.
        case_number = random.choice(range(num_cases))

        bots = get_bots(session_pk=session_pk, case_number=case_number)
        for bot in bots:
            self.participants_by_session[session_pk].append(
                bot.participant_code)
            self.browser_bots[bot.participant_code] = bot
        return {'ok': True}
Example #6
0
    def handle_file(self, path):
        new_conf = CustomOtreeConfig.from_yaml(path).get_otree_config()

        config_obj = SessionConfig(settings.SESSION_CONFIG_DEFAULTS)
        config_obj.update(new_conf)
        config_obj.clean()
        SESSION_CONFIGS_DICT[new_conf['name']] = config_obj
Example #7
0
def get_rows_for_wide_csv():

    sessions = Session.objects.order_by('id')
    session_cache = {row.id: row for row in sessions}

    session_config_fields = set()
    for session in sessions:
        for field_name in SessionConfig(session.config).editable_fields():
            session_config_fields.add(field_name)
    session_config_fields = list(session_config_fields)

    participants = Participant.objects.order_by('id').values()
    if not participants:
        # 1 empty row
        return [[]]

    session_fields = get_field_names_for_csv(Session)
    participant_fields = get_field_names_for_csv(Participant)
    participant_fields.append('payoff_plus_participation_fee')
    header_row = [
        'participant.{}'.format(fname) for fname in participant_fields
    ]
    header_row += ['session.{}'.format(fname) for fname in session_fields]
    header_row += [
        'session.config.{}'.format(fname) for fname in session_config_fields
    ]
    rows = [header_row]
    for participant in participants:
        session = session_cache[participant['session_id']]
        participant[
            'payoff_plus_participation_fee'] = get_payoff_plus_participation_fee(
                session, participant)
        row = [
            sanitize_for_csv(participant[fname])
            for fname in participant_fields
        ]

        row += [
            sanitize_for_csv(getattr(session, fname))
            for fname in session_fields
        ]
        row += [
            sanitize_for_csv(session.config.get(fname))
            for fname in session_config_fields
        ]
        rows.append(row)

    # heuristic to get the most relevant order of apps
    app_sequences = collections.Counter()
    for session in sessions:
        # we loaded the config earlier
        app_sequence = session.config['app_sequence']
        app_sequences[tuple(app_sequence)] += session.num_participants
    most_common_app_sequence = app_sequences.most_common(1)[0][0]

    # can't use settings.INSTALLED_OTREE_APPS, because maybe the app
    # was removed from SESSION_CONFIGS.
    app_names_with_data = set()
    for session in sessions:
        for app_name in session.config['app_sequence']:
            app_names_with_data.add(app_name)

    apps_not_in_popular_sequence = [
        app for app in app_names_with_data
        if app not in most_common_app_sequence
    ]

    order_of_apps = list(
        most_common_app_sequence) + apps_not_in_popular_sequence

    rounds_per_app = OrderedDict()
    for app_name in order_of_apps:
        models_module = get_models_module(app_name)
        agg_dict = models_module.Subsession.objects.all().aggregate(
            Max('round_number'))
        highest_round_number = agg_dict['round_number__max']

        if highest_round_number is not None:
            rounds_per_app[app_name] = highest_round_number
    for app_name in rounds_per_app:
        for round_number in range(1, rounds_per_app[app_name] + 1):
            new_rows = get_rows_for_wide_csv_round(app_name, round_number,
                                                   sessions)
            for i in range(len(rows)):
                rows[i].extend(new_rows[i])
    return rows
Example #8
0
 def get_context_data(self, **kwargs):
     context = super(SessionDescription, self).get_context_data(**kwargs)
     context['config'] = SessionConfig(self.session.config)
     return context
Example #9
0
 def vars_for_template(self):
     return dict(config=SessionConfig(self.session.config))
Example #10
0
def get_rows_for_wide_csv(session_code):
    if session_code:
        sessions = [Session.objects_get(code=session_code)]
    else:
        sessions = dbq(Session).order_by('id').all()
    session_fields = get_fields_for_csv(Session)
    participant_fields = get_fields_for_csv(Participant)

    session_ids = [session.id for session in sessions]
    pps = (Participant.objects_filter(
        Participant.session_id.in_(session_ids)).order_by(
            Participant.id).all())
    session_cache = {row.id: row for row in sessions}

    session_config_fields = set()
    for session in sessions:
        for field_name in SessionConfig(session.config).editable_fields():
            session_config_fields.add(field_name)
    session_config_fields = list(session_config_fields)

    if not pps:
        # 1 empty row
        return [[]]

    header_row = [f'participant.{fname}' for fname in participant_fields]
    header_row += [f'session.{fname}' for fname in session_fields]
    header_row += [
        f'session.config.{fname}' for fname in session_config_fields
    ]
    rows = [header_row]

    for pp in pps:
        session = session_cache[pp.session_id]
        row = [getattr(pp, fname) for fname in participant_fields]
        row += [getattr(session, fname) for fname in session_fields]
        row += [session.config.get(fname) for fname in session_config_fields]
        rows.append(row)

    order_of_apps = _get_best_app_order(sessions)

    rounds_per_app = OrderedDict()
    for app_name in order_of_apps:
        try:
            models_module = get_models_module(app_name)
        except ModuleNotFoundError:
            # this should only happen with devserver because on production server,
            # you would need to resetdb after renaming an app.
            logger.warning(
                f'Cannot export data for app {app_name}, which existed when the session was run '
                f'but no longer exists.')
            continue

        highest_round_number = dbq(
            func.max(models_module.Subsession.round_number)).scalar()

        if highest_round_number is not None:
            rounds_per_app[app_name] = highest_round_number
    for app_name in rounds_per_app:
        for round_number in range(1, rounds_per_app[app_name] + 1):
            new_rows = get_rows_for_wide_csv_round(app_name, round_number,
                                                   sessions)
            for i in range(len(rows)):
                rows[i].extend(new_rows[i])

    return [[sanitize_for_csv(v) for v in row] for row in rows]
Example #11
0
 def get_context_data(self, **kwargs):
     context = super(SessionDescription, self).get_context_data(**kwargs)
     config_obj = SessionConfig(self.session.config)
     context.update(config_obj.get_info())
     return context
Example #12
0
def get_rows_for_wide_csv():

    sessions = Session.objects.order_by('id').annotate(
        num_participants=Count('participant')).values()
    session_cache = {row['id']: row for row in sessions}

    session_config_fields = set()
    for row in sessions:
        config = json_loads(row['config'])
        config = SessionConfig(config)
        for field_name in config.editable_fields():
            session_config_fields.add(field_name)
        # store it for later, when we need app_sequence
        row['config'] = config
    session_config_fields = list(session_config_fields)

    participants = Participant.objects.order_by('id').values()
    if not participants:
        # 1 empty row
        return [[]]

    payoff_cache = get_payoff_cache()
    payoff_plus_participation_fee_cache = get_payoff_plus_participation_fee_cache(payoff_cache)

    session_fields = get_field_names_for_csv(Session)
    participant_fields = get_field_names_for_csv(Participant)
    participant_fields += ['payoff', 'payoff_plus_participation_fee']
    header_row = ['participant.{}'.format(fname) for fname in participant_fields]
    header_row += ['session.{}'.format(fname)
                   for fname in session_fields]
    header_row += ['session.config.{}'.format(fname)
                   for fname in session_config_fields]
    rows = [header_row]
    for participant in participants:
        participant['payoff'] = payoff_cache[participant['id']]
        participant['payoff_plus_participation_fee'] = payoff_plus_participation_fee_cache[participant['id']]
        row = [sanitize_for_csv(participant[fname]) for fname in participant_fields]
        session = session_cache[participant['session_id']]
        row += [sanitize_for_csv(session[fname]) for fname in session_fields]
        config = session['config']
        row += [sanitize_for_csv(config.get(fname)) for fname in session_config_fields]
        rows.append(row)

    # heuristic to get the most relevant order of apps
    app_sequences = collections.Counter()
    for session in sessions:
        # we loaded the config earlier
        app_sequence = session['config']['app_sequence']
        app_sequences[tuple(app_sequence)] += session['num_participants']
    most_common_app_sequence = app_sequences.most_common(1)[0][0]

    apps_not_in_popular_sequence = [
        app for app in settings.INSTALLED_OTREE_APPS
        if app not in most_common_app_sequence]

    order_of_apps = list(most_common_app_sequence) + apps_not_in_popular_sequence

    rounds_per_app = OrderedDict()
    for app_name in order_of_apps:
        models_module = get_models_module(app_name)
        agg_dict = models_module.Subsession.objects.all().aggregate(Max('round_number'))
        highest_round_number = agg_dict['round_number__max']

        if highest_round_number is not None:
            rounds_per_app[app_name] = highest_round_number
    for app_name in rounds_per_app:
        for round_number in range(1, rounds_per_app[app_name] + 1):
            new_rows = get_rows_for_wide_csv_round(app_name, round_number, sessions)
            for i in range(len(rows)):
                rows[i].extend(new_rows[i])
    return rows
Example #13
0
def get_rows_for_wide_csv():

    sessions = Session.objects.order_by('id').annotate(
        num_participants=Count('participant')).values()
    session_cache = {row['id']: row for row in sessions}

    session_config_fields = set()
    for row in sessions:
        config = json_loads(row['config'])
        config = SessionConfig(config)
        for field_name in config.editable_fields():
            session_config_fields.add(field_name)
        # store it for later, when we need app_sequence
        row['config'] = config
    session_config_fields = list(session_config_fields)

    participants = Participant.objects.order_by('id').values()
    if not participants:
        # 1 empty row
        return [[]]

    payoff_cache = get_payoff_cache()
    payoff_plus_participation_fee_cache = get_payoff_plus_participation_fee_cache(
        payoff_cache)

    session_fields = get_field_names_for_csv(Session)
    participant_fields = get_field_names_for_csv(Participant)
    participant_fields += ['payoff', 'payoff_plus_participation_fee']
    header_row = [
        'participant.{}'.format(fname) for fname in participant_fields
    ]
    header_row += ['session.{}'.format(fname) for fname in session_fields]
    header_row += [
        'session.config.{}'.format(fname) for fname in session_config_fields
    ]
    rows = [header_row]
    for participant in participants:
        participant['payoff'] = payoff_cache[participant['id']]
        participant[
            'payoff_plus_participation_fee'] = payoff_plus_participation_fee_cache[
                participant['id']]
        row = [
            sanitize_for_csv(participant[fname])
            for fname in participant_fields
        ]
        session = session_cache[participant['session_id']]
        row += [sanitize_for_csv(session[fname]) for fname in session_fields]
        config = session['config']
        row += [
            sanitize_for_csv(config.get(fname))
            for fname in session_config_fields
        ]
        rows.append(row)

    # heuristic to get the most relevant order of apps
    app_sequences = collections.Counter()
    for session in sessions:
        # we loaded the config earlier
        app_sequence = session['config']['app_sequence']
        app_sequences[tuple(app_sequence)] += session['num_participants']
    most_common_app_sequence = app_sequences.most_common(1)[0][0]

    apps_not_in_popular_sequence = [
        app for app in settings.INSTALLED_OTREE_APPS
        if app not in most_common_app_sequence
    ]

    order_of_apps = list(
        most_common_app_sequence) + apps_not_in_popular_sequence

    rounds_per_app = OrderedDict()
    for app_name in order_of_apps:
        models_module = get_models_module(app_name)
        agg_dict = models_module.Subsession.objects.all().aggregate(
            Max('round_number'))
        highest_round_number = agg_dict['round_number__max']

        if highest_round_number is not None:
            rounds_per_app[app_name] = highest_round_number
    for app_name in rounds_per_app:
        for round_number in range(1, rounds_per_app[app_name] + 1):
            new_rows = get_rows_for_wide_csv_round(app_name, round_number,
                                                   sessions)
            for i in range(len(rows)):
                rows[i].extend(new_rows[i])
    return rows
Example #14
0
def get_rows_for_wide_csv(session_code):
    if session_code:
        sessions = [Session.objects.get(code=session_code)]
    else:
        sessions = Session.objects.order_by('id')
    participants = (
        Participant.objects.filter(session__in=sessions).order_by('id').values()
    )
    session_cache = {row.id: row for row in sessions}

    session_config_fields = set()
    for session in sessions:
        for field_name in SessionConfig(session.config).editable_fields():
            session_config_fields.add(field_name)
    session_config_fields = list(session_config_fields)

    if not participants:
        # 1 empty row
        return [[]]

    session_fields = get_field_names_for_csv(Session)
    participant_fields = get_field_names_for_csv(Participant)
    participant_fields.append('payoff_plus_participation_fee')
    header_row = ['participant.{}'.format(fname) for fname in participant_fields]
    header_row += ['session.{}'.format(fname) for fname in session_fields]
    header_row += ['session.config.{}'.format(fname) for fname in session_config_fields]
    rows = [header_row]
    for participant in participants:
        session = session_cache[participant['session_id']]
        participant[
            'payoff_plus_participation_fee'
        ] = get_payoff_plus_participation_fee(session, participant)
        row = [sanitize_for_csv(participant[fname]) for fname in participant_fields]

        row += [sanitize_for_csv(getattr(session, fname)) for fname in session_fields]
        row += [
            sanitize_for_csv(session.config.get(fname))
            for fname in session_config_fields
        ]
        rows.append(row)

    # heuristic to get the most relevant order of apps
    app_sequences = collections.Counter()
    for session in sessions:
        # we loaded the config earlier
        app_sequence = session.config['app_sequence']
        app_sequences[tuple(app_sequence)] += session.num_participants
    most_common_app_sequence = app_sequences.most_common(1)[0][0]

    # can't use settings.INSTALLED_OTREE_APPS, because maybe the app
    # was removed from SESSION_CONFIGS.
    app_names_with_data = set()
    for session in sessions:
        for app_name in session.config['app_sequence']:
            app_names_with_data.add(app_name)

    apps_not_in_popular_sequence = [
        app for app in app_names_with_data if app not in most_common_app_sequence
    ]

    order_of_apps = list(most_common_app_sequence) + apps_not_in_popular_sequence

    rounds_per_app = OrderedDict()
    for app_name in order_of_apps:
        try:
            models_module = get_models_module(app_name)
        except ModuleNotFoundError:
            # this should only happen with devserver because on production server,
            # you would need to resetdb after renaming an app.
            logger.warning(
                f'Cannot export data for app {app_name}, which existed when the session was run '
                f'but no longer exists.'
            )
            continue
        agg_dict = models_module.Subsession.objects.all().aggregate(Max('round_number'))
        highest_round_number = agg_dict['round_number__max']

        if highest_round_number is not None:
            rounds_per_app[app_name] = highest_round_number
    for app_name in rounds_per_app:
        for round_number in range(1, rounds_per_app[app_name] + 1):
            new_rows = get_rows_for_wide_csv_round(app_name, round_number, sessions)
            for i in range(len(rows)):
                rows[i].extend(new_rows[i])
    return rows
Example #15
0
 def get_context_data(self, **kwargs):
     context = super(SessionDescription, self).get_context_data(**kwargs)
     config_obj = SessionConfig(self.session.config)
     context.update(config_obj.get_info())
     return context