Skip to content

Experiment views

experiment.views

get_associated_blocks(pk_list)

get all the experiment objects registered in an Experiment field

Source code in experiment/views.py
134
135
136
def get_associated_blocks(pk_list):
    """get all the experiment objects registered in an Experiment field"""
    return [Block.objects.get(pk=pk) for pk in pk_list]

get_block(request, slug)

Get block data from active block with given :slug DO NOT modify session data here, it will break participant_id system (/participant and /block/ are called at the same time by the frontend)

Source code in experiment/views.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def get_block(request: HttpRequest, slug: str) -> JsonResponse:
    """Get block data from active block with given :slug
    DO NOT modify session data here, it will break participant_id system
       (/participant and /block/<slug> are called at the same time by the frontend)"""
    block = block_or_404(slug)
    class_name = ""
    active_language = get_language()

    if active_language.startswith("zh"):
        class_name = "chinese"

    participant = get_participant(request)
    session = Session(block=block, participant=participant)

    playlist = block.playlists.first()
    if playlist:
        session.playlist = playlist

    session.save()

    # create data
    block_data = {
        **serialize_block(block),
        "theme": serialize_theme(block.theme_config) if block.theme_config else None,
        "class_name": class_name,  # can be used to override style
        "rounds": block.rounds,
        "bonus_points": block.bonus_points,
        "playlists": [
            {"id": playlist.id, "name": playlist.name}
            for playlist in block.playlists.all()
        ],
        "feedback_info": block.get_rules().feedback_info(),
        "loading_text": _("Loading"),
        "session_id": session.id,
    }

    response = JsonResponse(block_data, json_dumps_params={"indent": 4})

    return response

get_experiment(request, slug)

check which Phase objects are related to the Experiment with the given slug retrieve the phase with the lowest order (= current_phase) return the next block from the current_phase without a finished session except if Phase.dashboard = True, then all blocks of the current_phase will be returned as an array (also those with finished session)

Source code in experiment/views.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def get_experiment(
    request: HttpRequest,
    slug: str,
) -> JsonResponse:
    """
    check which `Phase` objects are related to the `Experiment` with the given slug
    retrieve the phase with the lowest order (= current_phase)
    return the next block from the current_phase without a finished session
    except if Phase.dashboard = True,
    then all blocks of the current_phase will be returned as an array (also those with finished session)
    """

    try:
        experiment = Experiment.objects.get(slug=slug, active=True)
    except Experiment.DoesNotExist:
        raise Http404("Experiment does not exist or is not active")
    except Exception as e:
        logger.error(e)
        return JsonResponse(
            {"error": "Something went wrong while fetching the experiment. Please try again later."},
            status=500,
        )

    request.session[EXPERIMENT_KEY] = slug
    participant = get_participant(request)

    phases = list(experiment.phases.order_by("index").all())
    if not len(phases):
        return JsonResponse(
            {"error": "This experiment does not have phases and blocks configured"},
            status=500,
        )
    times_played_key = 'f"{slug}-xplayed"'
    times_played = request.session.get(times_played_key, 0)
    for phase in phases:
        serialized_phase = serialize_phase(phase, participant, times_played)
        if serialized_phase:
            return JsonResponse(
                {**serialize_experiment(experiment), **serialized_phase}
            )
    # if no phase was found, start from scratch by incrementing times_pleyd
    times_played += 1
    request.session[times_played_key] = times_played
    serialized_phase = serialize_phase(phases[0], participant, times_played)
    return JsonResponse({**serialize_experiment(experiment), **serialized_phase})

validate_block_playlist(request, rules_id)

Validate the playlist of an experiment based on the used rules

Source code in experiment/views.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
def validate_block_playlist(request: HttpRequest, rules_id: str) -> JsonResponse:
    """
    Validate the playlist of an experiment based on the used rules
    """

    if request.method != "POST":
        return JsonResponse({"status": "error", "message": "Only POST requests are allowed"})

    if not request.body:
        return JsonResponse({"status": "error", "message": "No body found in request"})

    if request.content_type != "application/json":
        return JsonResponse({"status": "error", "message": "Only application/json content type is allowed"})

    json_body = json.loads(request.body)
    playlist_ids = json_body.get("playlists", [])
    playlists = Playlist.objects.filter(id__in=playlist_ids)

    if not playlists:
        return JsonResponse({"status": "error", "message": "The block must have a playlist."})

    rules = BLOCK_RULES[rules_id]()

    if not rules.validate_playlist:
        return JsonResponse({"status": "warn", "message": "This rulesset does not have a playlist validation."})

    playlist_errors = []

    for playlist in playlists:
        errors = rules.validate_playlist(playlist)
        if errors:
            playlist_errors.append({"playlist": playlist.name, "errors": errors})

    if playlist_errors:
        return JsonResponse(
            {"status": "error", "message": "There are errors in the playlist.", "errors": playlist_errors}
        )

    return JsonResponse({"status": "ok", "message": "The playlist is valid."})