pearmut 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pearmut/app.py +25 -21
- pearmut/assignment.py +184 -0
- pearmut/cli.py +37 -19
- pearmut/static/assets/style.css +168 -0
- pearmut/static/dashboard.bundle.js +1 -1
- pearmut/static/listwise.bundle.js +1 -0
- pearmut/static/listwise.html +77 -0
- pearmut/static/pointwise.bundle.js +1 -1
- pearmut/static/pointwise.html +2 -168
- {pearmut-0.1.0.dist-info → pearmut-0.1.2.dist-info}/METADATA +9 -9
- pearmut-0.1.2.dist-info/RECORD +19 -0
- pearmut/protocols.py +0 -122
- pearmut-0.1.0.dist-info/RECORD +0 -17
- {pearmut-0.1.0.dist-info → pearmut-0.1.2.dist-info}/WHEEL +0 -0
- {pearmut-0.1.0.dist-info → pearmut-0.1.2.dist-info}/entry_points.txt +0 -0
- {pearmut-0.1.0.dist-info → pearmut-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {pearmut-0.1.0.dist-info → pearmut-0.1.2.dist-info}/top_level.txt +0 -0
pearmut/static/pointwise.html
CHANGED
|
@@ -28,10 +28,6 @@
|
|
|
28
28
|
text-align: center;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
.output_block {
|
|
32
|
-
margin-bottom: 30pt;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
31
|
.output_labels {
|
|
36
32
|
vertical-align: top;
|
|
37
33
|
display: inline-block;
|
|
@@ -48,7 +44,7 @@
|
|
|
48
44
|
width: 20px;
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
/* on displays with less than
|
|
47
|
+
/* on displays with less than 1000px */
|
|
52
48
|
@media (max-width: 1000px) {
|
|
53
49
|
.output_srctgt {
|
|
54
50
|
width: 80%;
|
|
@@ -63,109 +59,6 @@
|
|
|
63
59
|
}
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
.tgt_char:hover {
|
|
67
|
-
background-color: #ccc;
|
|
68
|
-
cursor: pointer;
|
|
69
|
-
;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.src_char:hover {
|
|
73
|
-
background-color: #ccc;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.error_unknown {
|
|
77
|
-
background-color: #ddf;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.error_neutral {
|
|
81
|
-
background-color: #edd;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.error_minor {
|
|
85
|
-
background-color: #fcc;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.error_major {
|
|
89
|
-
background-color: #e88;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.src_char.highlighted,
|
|
93
|
-
.tgt_char.highlighted {
|
|
94
|
-
background-color: #ccc;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
#button_error_minor:hover,
|
|
98
|
-
#button_error_major:hover {
|
|
99
|
-
opacity: 0.8;
|
|
100
|
-
cursor: pointer;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.highlighted_active {
|
|
104
|
-
background-color: #aaf !important;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/* span toolbox section */
|
|
108
|
-
.span_toolbox {
|
|
109
|
-
background-color: white;
|
|
110
|
-
padding: 5px;
|
|
111
|
-
border-radius: 8px;
|
|
112
|
-
box-shadow: 0 4px 6px #0005;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.span_toolbox_parent {
|
|
116
|
-
position: absolute;
|
|
117
|
-
padding-left: 20px;
|
|
118
|
-
padding-right: 20px;
|
|
119
|
-
padding-top: 10px;
|
|
120
|
-
/* always maximally spread out children */
|
|
121
|
-
min-width: max-content;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
input[type="button"].error_neutral {
|
|
125
|
-
background-color: #ecc9 !important;
|
|
126
|
-
width: 100%;
|
|
127
|
-
text-align: center;
|
|
128
|
-
border-radius: 8px;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
input[type="button"].error_neutral:hover {
|
|
132
|
-
background-color: #ecc !important;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
input[type="button"].error_minor {
|
|
136
|
-
background-color: #fcc !important;
|
|
137
|
-
width: 100%;
|
|
138
|
-
text-align: center;
|
|
139
|
-
border-radius: 8px;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
input[type="button"].error_minor:hover {
|
|
143
|
-
background-color: #daa !important;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
input[type="button"].error_major {
|
|
147
|
-
background-color: #e88 !important;
|
|
148
|
-
width: 100%;
|
|
149
|
-
text-align: center;
|
|
150
|
-
border-radius: 8px;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
input[type="button"].error_major:hover {
|
|
154
|
-
background-color: #c66 !important;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
input[type="button"].error_delete {
|
|
158
|
-
background-color: #ddd !important;
|
|
159
|
-
font-size: 10pt;
|
|
160
|
-
width: 100%;
|
|
161
|
-
text-align: center;
|
|
162
|
-
border-radius: 8px;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
input[type="button"].error_delete:hover {
|
|
166
|
-
background-color: #ccc !important;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
62
|
input[type=range][orient=vertical] {
|
|
170
63
|
position: relative;
|
|
171
64
|
top: -5px;
|
|
@@ -173,63 +66,4 @@
|
|
|
173
66
|
direction: rtl;
|
|
174
67
|
width: 16px;
|
|
175
68
|
height: 200px;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/* progress bar */
|
|
179
|
-
#progress span {
|
|
180
|
-
font-size: 0pt;
|
|
181
|
-
display: inline-block;
|
|
182
|
-
border-radius: 50%;
|
|
183
|
-
text-align: center;
|
|
184
|
-
line-height: 2em;
|
|
185
|
-
margin-left: 2px;
|
|
186
|
-
box-shadow: 0 1px 1px #0002;
|
|
187
|
-
width: 10px;
|
|
188
|
-
height: 10px;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
#progress span:hover,
|
|
192
|
-
#progress span.progress_current,
|
|
193
|
-
#progress span.progress_incomplete:last-child {
|
|
194
|
-
cursor: pointer;
|
|
195
|
-
user-select: none;
|
|
196
|
-
position: relative;
|
|
197
|
-
top: 7.5px;
|
|
198
|
-
width: 22px;
|
|
199
|
-
height: 22px;
|
|
200
|
-
font-size: 8pt;
|
|
201
|
-
margin-left: -5px;
|
|
202
|
-
margin-right: -5px;
|
|
203
|
-
box-shadow: 0 1px 3px #0002;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
#progress span:hover {
|
|
207
|
-
z-index: 100;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
#progress span.progress_complete {
|
|
211
|
-
color: white;
|
|
212
|
-
background: #3b5238;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
#progress span.progress_complete:hover {
|
|
217
|
-
background: #2e3e2b;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
#progress span.progress_current {
|
|
221
|
-
background: #91b08d;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
#progress span.progress_current:hover {
|
|
225
|
-
background: #739c6f;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
#progress span.progress_incomplete {
|
|
229
|
-
background: #bbb;
|
|
230
|
-
color: #555;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
#progress span.progress_incomplete:hover {
|
|
234
|
-
background: #aaa;
|
|
235
|
-
}</style><script defer="defer" src="pointwise.bundle.js"></script></head><body><div style="max-width: 1600px; min-width: 900px; margin-left: auto; margin-right: auto; margin-top: 20px; padding-left: 10px;"><div class="white-box" style="margin-right: 30px; background-color: #e7e2cf; padding: 5px 15px 5px 5px;"><span id="instructions_global" style="display: inline-block; font-size: 11pt; width: calc(100% - 170px);"><ul id="instructions_spans"><li>Error spans:<ul><li><strong>Select</strong> the part of translation where you have identified a <strong>translation error</strong> (drag or click start & end).</li><li><strong>Click</strong> on the highlight to change error severity (minor/major) or remove the highlight.</li></ul>Choose error severity:<ul><li><span class="instruction_sev" id="instruction_sev_minor">Minor errors:</span> Style, grammar, word choice could be better or more natural.</li><li><span class="instruction_sev" id="instruction_sev_major">Major errors:</span>: The meaning is changed significantly and/or the part is really hard to understand.</li></ul><strong>Tip</strong>: Highlight the word or general area of the error (it doesn't need to be exact). Use separate highlights for different errors.<br></li><li id="instructions_score">Score the translation: Please use the slider and set an overall score based on meaning preservation and general quality:</li><ul><li>0: <strong>No meaning preserved</strong>: most information is lost.</li><li>33%: <strong>Some meaning preserved</strong>: major gaps and narrative issues.</li><li>66%: <strong>Most meaning preserved</strong>: minor issues with grammar or consistency.</li><li>100%: <strong>Perfect</strong>: meaning and grammar align completely with the source.</li></ul><li id="instructions_categories">Error types: After highlighting an error fragment, you will be asked to select the specific error type (main category and subcategory). If you are unsure about which errors fall under which categories, please consult the <a href="https://themqm.org/the-mqm-typology/" style="font-weight: bold; text-decoration: underline;">typology definitions</a>.</li></ul></span><div style="width: 170px; display: inline-block; vertical-align: top; text-align: right; padding-top: 5px;"><span id="time" style="width: 135px; text-align: left; display: inline-block; font-size: 11pt;" title="Approximation of total annotation time.">Time: 0m</span> <input type="button" value="⚙️" id="button_settings" style="height: 1.5em; width: 30px;"><br><br><div id="progress" style="text-align: center;"></div><br><br><input type="button" value="Next 🛠️" id="button_next" disabled="disabled" style="width: 170px; height: 2.5em;" title="Finish annotating all examples first."> <input type="button" value="skip tutorial" id="button_skip_tutorial" style="width: 170px; font-size: 11pt; height: 30px; margin-top: 10px; display: none;" title="Skip tutorial only if you completed it already."></div></div><div id="settings_div" class="white-box" style="margin-right: 20px; margin-top: 10px; display: none; background-color: #e7e2cf; font-size: 11pt;"><input type="checkbox" id="settings_approximate_alignment"> <label for="settings_approximate_alignment">Show approximate alignment</label></div><div id="output_div" style="margin-top: 100px;"></div><br><br><br></div></body></html>
|
|
69
|
+
}</style><script defer="defer" src="pointwise.bundle.js"></script></head><body><div style="max-width: 1600px; min-width: 900px; margin-left: auto; margin-right: auto; margin-top: 20px; padding-left: 10px;"><div class="white-box" style="margin-right: 30px; background-color: #e7e2cf; padding: 5px 15px 5px 5px;"><span id="instructions_global" style="display: inline-block; font-size: 11pt; width: calc(100% - 170px);"><ul id="instructions_spans"><li>Error spans:<ul><li><strong>Select</strong> the part of translation where you have identified a <strong>translation error</strong> (drag or click start & end).</li><li><strong>Click</strong> on the highlight to change error severity (minor/major) or remove the highlight.</li></ul>Choose error severity:<ul><li><span class="instruction_sev" id="instruction_sev_minor">Minor errors:</span> Style, grammar, word choice could be better or more natural.</li><li><span class="instruction_sev" id="instruction_sev_major">Major errors:</span>: The meaning is changed significantly and/or the part is really hard to understand.</li></ul><strong>Tip</strong>: Highlight the word or general area of the error (it doesn't need to be exact). Use separate highlights for different errors.<br></li><li id="instructions_score">Score the translation: Please use the slider and set an overall score based on meaning preservation and general quality:</li><ul><li>0: <strong>No meaning preserved</strong>: most information is lost.</li><li>33%: <strong>Some meaning preserved</strong>: major gaps and narrative issues.</li><li>66%: <strong>Most meaning preserved</strong>: minor issues with grammar or consistency.</li><li>100%: <strong>Perfect</strong>: meaning and grammar align completely with the source.</li></ul><li id="instructions_categories">Error types: After highlighting an error fragment, you will be asked to select the specific error type (main category and subcategory). If you are unsure about which errors fall under which categories, please consult the <a href="https://themqm.org/the-mqm-typology/" style="font-weight: bold; text-decoration: none; color: black;">typology definitions</a>.</li></ul></span><div style="width: 170px; display: inline-block; vertical-align: top; text-align: right; padding-top: 5px;"><span id="time" style="width: 135px; text-align: left; display: inline-block; font-size: 11pt;" title="Approximation of total annotation time.">Time: 0m</span> <input type="button" value="⚙️" id="button_settings" style="height: 1.5em; width: 30px;"><br><br><div id="progress" style="text-align: center;"></div><br><br><input type="button" value="Next 🛠️" id="button_next" disabled="disabled" style="width: 170px; height: 2.5em;" title="Finish annotating all examples first."> <input type="button" value="skip tutorial" id="button_skip_tutorial" style="width: 170px; font-size: 11pt; height: 30px; margin-top: 10px; display: none;" title="Skip tutorial only if you completed it already."></div></div><div id="settings_div" class="white-box" style="margin-right: 20px; margin-top: 10px; display: none; background-color: #e7e2cf; font-size: 11pt;"><input type="checkbox" id="settings_approximate_alignment"> <label for="settings_approximate_alignment">Show approximate alignment</label></div><div id="output_div" style="margin-top: 100px;"></div><br><br><br></div></body></html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pearmut
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A tool for evaluation of model outputs, primarily MT.
|
|
5
5
|
Author-email: Vilém Zouhar <vilem.zouhar@gmail.com>
|
|
6
6
|
License: apache-2.0
|
|
@@ -63,7 +63,7 @@ One of the simplest ones, where each user has a pre-defined list of tasks (`task
|
|
|
63
63
|
```python
|
|
64
64
|
{
|
|
65
65
|
"info": {
|
|
66
|
-
"
|
|
66
|
+
"assignment": "task-based",
|
|
67
67
|
"template": "pointwise",
|
|
68
68
|
"protocol_score": true, # we want scores [0...100] for each segment
|
|
69
69
|
"protocol_error_spans": true, # we want error spans
|
|
@@ -115,19 +115,19 @@ For the standard ones (ESA, DA, MQM), we expect each item to be a dictionary (co
|
|
|
115
115
|
... # definition of another item (document)
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
We also support a
|
|
118
|
+
We also support a simple allocation where all annotators draw from the same pool (`single-stream`). Items are randomly assigned to annotators from the pool of unfinished items:
|
|
119
119
|
```python
|
|
120
120
|
{
|
|
121
121
|
"campaign_id": "my campaign 6",
|
|
122
122
|
"info": {
|
|
123
|
-
"
|
|
123
|
+
"assignment": "single-stream",
|
|
124
124
|
"template": "pointwise",
|
|
125
125
|
"protocol_score": True, # collect scores
|
|
126
126
|
"protocol_error_spans": True, # collect error spans
|
|
127
127
|
"protocol_error_categories": False, # do not collect MQM categories, so ESA
|
|
128
|
-
"
|
|
128
|
+
"num_users": 50, # number of annotators
|
|
129
129
|
},
|
|
130
|
-
"data": [...], # list of all items
|
|
130
|
+
"data": [...], # list of all items (shared among all annotators)
|
|
131
131
|
}
|
|
132
132
|
```
|
|
133
133
|
|
|
@@ -137,10 +137,10 @@ We also support dynamic allocation of annotations (`dynamic`, not yet ⚠️), w
|
|
|
137
137
|
{
|
|
138
138
|
"campaign_id": "my campaign 6",
|
|
139
139
|
"info": {
|
|
140
|
-
"
|
|
140
|
+
"assignment": "dynamic",
|
|
141
141
|
"template": "kway",
|
|
142
142
|
"protocol_k": 5,
|
|
143
|
-
"
|
|
143
|
+
"num_users": 50,
|
|
144
144
|
},
|
|
145
145
|
"data": [...], # list of all items
|
|
146
146
|
}
|
|
@@ -185,7 +185,7 @@ To make changes locally, clone the repository and run the following, which will
|
|
|
185
185
|
cd pearmut
|
|
186
186
|
# watch the frontend for changes (in a separate terminal)
|
|
187
187
|
npm install web/ --prefix web/
|
|
188
|
-
npm run
|
|
188
|
+
npm run build --prefix web/ # `watch` for rebuild on code change
|
|
189
189
|
|
|
190
190
|
# install local package as editable
|
|
191
191
|
pip3 install -e .
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
pearmut/app.py,sha256=s_xv7Nq9dm3ObApH_Iz9myS-H_q4oXsFKqwiwVbQYuY,6740
|
|
2
|
+
pearmut/assignment.py,sha256=IgGXmZKFASoGW8jVeXXUN3meY8Two-Txwg4nMwZEOnA,6422
|
|
3
|
+
pearmut/cli.py,sha256=mV76uw6BywckbU7QEKIKTboukcALEdZp7l-kskJnBVA,7683
|
|
4
|
+
pearmut/utils.py,sha256=6hfVenrVdGm1r-7uJIkWHhX9o0ztWjqPse_j_MqkgBw,1443
|
|
5
|
+
pearmut/static/dashboard.bundle.js,sha256=6389gsHLCFh6JqiKdU3ng-Lm6VICRvfJgCSYM61H75U,91257
|
|
6
|
+
pearmut/static/dashboard.html,sha256=tUP1yYvbKySRz0mxFtGq2Si4hTMhJkUCWeTpnq91Nf4,1789
|
|
7
|
+
pearmut/static/index.html,sha256=ieCRLK83MVe-f-gtjYiOlvE-kKd8VnFF2xgyi6FoZpU,872
|
|
8
|
+
pearmut/static/listwise.bundle.js,sha256=_KWKocPZjkDHHoiixKFOZzmD0qlw-nqFheBPcbED0HM,100788
|
|
9
|
+
pearmut/static/listwise.html,sha256=zipFfGus26qWEdFbuNQmaG-NR5S1yaczv2XpD8j843U,5203
|
|
10
|
+
pearmut/static/pointwise.bundle.js,sha256=1mks6kD4P2w7uQqeze4GttKVc-JZvsLYKRktV6Em6R0,100431
|
|
11
|
+
pearmut/static/pointwise.html,sha256=dhmfgpWvCFB833Y4kj08_aBZyCN33SayYcS1ckL2-FU,5009
|
|
12
|
+
pearmut/static/assets/favicon.svg,sha256=gVPxdBlyfyJVkiMfh8WLaiSyH4lpwmKZs8UiOeX8YW4,7347
|
|
13
|
+
pearmut/static/assets/style.css,sha256=-B-RySjt8qccqkwvLT0PDy6IRoE1xytLLKAFtR_S-Tg,3967
|
|
14
|
+
pearmut-0.1.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
15
|
+
pearmut-0.1.2.dist-info/METADATA,sha256=cuHpmxeRqYF9H6s5ukP6RZBEx4tzy7bzipdhmbtIBVc,8923
|
|
16
|
+
pearmut-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
17
|
+
pearmut-0.1.2.dist-info/entry_points.txt,sha256=eEA9LVWsS3neQbMvL_nMvEw8I0oFudw8nQa1iqxOiWM,45
|
|
18
|
+
pearmut-0.1.2.dist-info/top_level.txt,sha256=CdgtUM-SKQDt6o5g0QreO-_7XTBP9_wnHMS1P-Rl5Go,8
|
|
19
|
+
pearmut-0.1.2.dist-info/RECORD,,
|
pearmut/protocols.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
from fastapi.responses import JSONResponse
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def get_next_item(
|
|
7
|
-
campaign_id: str,
|
|
8
|
-
user_id: str,
|
|
9
|
-
tasks_data: dict,
|
|
10
|
-
progress_data: dict,
|
|
11
|
-
) -> JSONResponse:
|
|
12
|
-
"""
|
|
13
|
-
Get the next item for the user in the specified campaign.
|
|
14
|
-
"""
|
|
15
|
-
if tasks_data[campaign_id]["info"]["type"] == "task-based":
|
|
16
|
-
return get_next_item_taskbased(campaign_id, user_id, tasks_data, progress_data)
|
|
17
|
-
elif tasks_data[campaign_id]["info"]["type"] == "dynamic":
|
|
18
|
-
return get_next_item_dynamic(campaign_id, user_id, tasks_data, progress_data)
|
|
19
|
-
else:
|
|
20
|
-
return JSONResponse(content={"error": "Unknown campaign type"}, status_code=400)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def get_next_item_taskbased(
|
|
24
|
-
campaign_id: str,
|
|
25
|
-
user_id: str,
|
|
26
|
-
data_all: dict,
|
|
27
|
-
progress_data: dict,
|
|
28
|
-
) -> JSONResponse:
|
|
29
|
-
"""
|
|
30
|
-
Get the next item for task-based protocol.
|
|
31
|
-
"""
|
|
32
|
-
if all(progress_data[campaign_id][user_id]["progress"]):
|
|
33
|
-
# all items completed
|
|
34
|
-
# TODO: add check for data quality
|
|
35
|
-
is_ok = True
|
|
36
|
-
return JSONResponse(
|
|
37
|
-
content={
|
|
38
|
-
"status": "completed",
|
|
39
|
-
"progress": {
|
|
40
|
-
"completed": sum(progress_data[campaign_id][user_id]["progress"]),
|
|
41
|
-
"time": progress_data[campaign_id][user_id]["time"],
|
|
42
|
-
"total": len(data_all[campaign_id]["data"][user_id]),
|
|
43
|
-
},
|
|
44
|
-
"token": progress_data[campaign_id][user_id]["token_correct" if is_ok else "token_incorrect"],
|
|
45
|
-
},
|
|
46
|
-
status_code=200
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
# find first incomplete item
|
|
50
|
-
item_i = min([i for i, v in enumerate(progress_data[campaign_id][user_id]["progress"]) if not v])
|
|
51
|
-
return JSONResponse(
|
|
52
|
-
content={
|
|
53
|
-
"status": "ok",
|
|
54
|
-
"progress": {
|
|
55
|
-
"completed": sum(progress_data[campaign_id][user_id]["progress"]),
|
|
56
|
-
"time": progress_data[campaign_id][user_id]["time"],
|
|
57
|
-
"total": len(data_all[campaign_id]["data"][user_id]),
|
|
58
|
-
},
|
|
59
|
-
"info": {
|
|
60
|
-
"instructions": data_all[campaign_id]["info"].get("instructions", ""),
|
|
61
|
-
"item_i": item_i,
|
|
62
|
-
} | {
|
|
63
|
-
k: v
|
|
64
|
-
for k, v in data_all[campaign_id]["info"].items()
|
|
65
|
-
if k.startswith("protocol")
|
|
66
|
-
},
|
|
67
|
-
"payload": data_all[campaign_id]["data"][user_id][item_i]},
|
|
68
|
-
status_code=200
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def get_next_item_dynamic(campaign_data: dict, user_id: str, progress_data: dict, data_all: dict):
|
|
73
|
-
raise NotImplementedError("Dynamic protocol is not implemented yet.")
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def reset_task(
|
|
78
|
-
campaign_id: str,
|
|
79
|
-
user_id: str,
|
|
80
|
-
tasks_data: dict,
|
|
81
|
-
progress_data: dict,
|
|
82
|
-
) -> JSONResponse:
|
|
83
|
-
"""
|
|
84
|
-
Reset the task progress for the user in the specified campaign.
|
|
85
|
-
"""
|
|
86
|
-
if tasks_data[campaign_id]["info"]["type"] == "task-based":
|
|
87
|
-
progress_data[campaign_id][user_id]["progress"] = [False]*len(tasks_data[campaign_id]["data"][user_id])
|
|
88
|
-
progress_data[campaign_id][user_id]["time"] = 0.0
|
|
89
|
-
progress_data[campaign_id][user_id]["time_start"] = None
|
|
90
|
-
progress_data[campaign_id][user_id]["time_end"] = None
|
|
91
|
-
return JSONResponse(content={"status": "ok"}, status_code=200)
|
|
92
|
-
else:
|
|
93
|
-
progress_data[campaign_id][user_id]["progress"] = []
|
|
94
|
-
progress_data[campaign_id][user_id]["time"] = 0.0
|
|
95
|
-
progress_data[campaign_id][user_id]["time_start"] = None
|
|
96
|
-
progress_data[campaign_id][user_id]["time_end"] = None
|
|
97
|
-
return JSONResponse(content={"status": "ok"}, status_code=200)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def update_progress(
|
|
102
|
-
campaign_id: str,
|
|
103
|
-
user_id: str,
|
|
104
|
-
tasks_data: dict,
|
|
105
|
-
progress_data: dict,
|
|
106
|
-
item_i: int,
|
|
107
|
-
payload: Any,
|
|
108
|
-
) -> JSONResponse:
|
|
109
|
-
"""
|
|
110
|
-
Log the user's response for the specified item in the campaign.
|
|
111
|
-
"""
|
|
112
|
-
if tasks_data[campaign_id]["info"]["type"] == "task-based":
|
|
113
|
-
# even if it's already set it should be fine
|
|
114
|
-
progress_data[campaign_id][user_id]["progress"][item_i] = True
|
|
115
|
-
# TODO: log attention checks/quality?
|
|
116
|
-
return JSONResponse(content={"status": "ok"}, status_code=200)
|
|
117
|
-
elif tasks_data[campaign_id]["info"]["type"] == "dynamic":
|
|
118
|
-
return JSONResponse(content={"status": "error", "message": "Dynamic protocol logging not implemented yet."}, status_code=400)
|
|
119
|
-
elif tasks_data[campaign_id]["info"]["type"] == "task-single":
|
|
120
|
-
return JSONResponse(content={"status": "error", "message": "Task-single protocol logging not implemented yet."}, status_code=400)
|
|
121
|
-
else:
|
|
122
|
-
return JSONResponse(content={"status": "error", "message": "Unknown campaign type"}, status_code=400)
|
pearmut-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
pearmut/app.py,sha256=p438nGXTqdGHTfTA3DHRA7GF71DsBT77D3pcCCOW_Ow,6535
|
|
2
|
-
pearmut/cli.py,sha256=PSF6JxAzGuV2ir6hdL6Q0Enf2G6KUgaf59_uS18LbZk,6929
|
|
3
|
-
pearmut/protocols.py,sha256=qd0X2l9c2_x4YKtK8RswNHdwc7bUb59IP2-GlDA1_R0,4674
|
|
4
|
-
pearmut/utils.py,sha256=6hfVenrVdGm1r-7uJIkWHhX9o0ztWjqPse_j_MqkgBw,1443
|
|
5
|
-
pearmut/static/dashboard.bundle.js,sha256=d_uoUgbBaAzcnT-hTGhxmZ1GxtSvfCI1xw6c8F8AAMY,91230
|
|
6
|
-
pearmut/static/dashboard.html,sha256=tUP1yYvbKySRz0mxFtGq2Si4hTMhJkUCWeTpnq91Nf4,1789
|
|
7
|
-
pearmut/static/index.html,sha256=ieCRLK83MVe-f-gtjYiOlvE-kKd8VnFF2xgyi6FoZpU,872
|
|
8
|
-
pearmut/static/pointwise.bundle.js,sha256=zdVJ2S9vBcd5-BHzbpCM-fCghAmB6pGB21lQE6butOc,100218
|
|
9
|
-
pearmut/static/pointwise.html,sha256=F4mWSnUf9DPf7LGyzQTvI1MgKb84ov9NItWzoFn1eIU,8314
|
|
10
|
-
pearmut/static/assets/favicon.svg,sha256=gVPxdBlyfyJVkiMfh8WLaiSyH4lpwmKZs8UiOeX8YW4,7347
|
|
11
|
-
pearmut/static/assets/style.css,sha256=p1gu_IVTdJMsiW9UtFQwtpiQ-4XillAbU9XLw1KJeGA,964
|
|
12
|
-
pearmut-0.1.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
13
|
-
pearmut-0.1.0.dist-info/METADATA,sha256=2SCD_wBHfpjAo1gr7Ygsc1ESvVKeZqkB2E_0wsIBGfM,8811
|
|
14
|
-
pearmut-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
pearmut-0.1.0.dist-info/entry_points.txt,sha256=eEA9LVWsS3neQbMvL_nMvEw8I0oFudw8nQa1iqxOiWM,45
|
|
16
|
-
pearmut-0.1.0.dist-info/top_level.txt,sha256=CdgtUM-SKQDt6o5g0QreO-_7XTBP9_wnHMS1P-Rl5Go,8
|
|
17
|
-
pearmut-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|