1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# -*- coding: utf-8 -*-
import datetime
import logging
from flask import render_template, flash, url_for, redirect, request
from flask_login import current_user
from app import db
from app.decorators import login_required
from app.main import bp
from app.models import Annotation, Task
from app.utils.datasets import load_data_for_chart
logger = logging.getLogger(__name__)
RUBRIC = """
Please mark the points in the time series where an <b>abrupt change</b> in
the behaviour of the series occurs. The goal is to define segments of the time
series that are separated by places where these abrupt changes occur.
<br>
"""
@bp.route("/")
@bp.route("/index")
def index():
if not current_user.is_anonymous and not current_user.is_confirmed:
return redirect(url_for("auth.not_confirmed"))
if current_user.is_authenticated:
user_id = current_user.id
tasks = Task.query.filter_by(annotator_id=user_id).all()
tasks_done = [t for t in tasks if t.done and not t.dataset.is_demo]
tasks_todo = [t for t in tasks if not t.done]
return render_template(
"index.html",
title="Home",
tasks_done=tasks_done,
tasks_todo=tasks_todo,
)
return render_template("index.html", title="Home")
@bp.route("/annotate/<int:task_id>", methods=("GET", "POST"))
@login_required
def annotate(task_id):
if request.method == "POST":
# record post time
now = datetime.datetime.utcnow()
# get the json from the client
annotation = request.get_json()
if annotation["identifier"] != task_id:
flash("Internal error: task id doesn't match.", "error")
return redirect(url_for(task_id=task_id))
task = Task.query.filter_by(id=task_id).first()
# remove all previous annotations for this task
for ann in Annotation.query.filter_by(task_id=task_id).all():
db.session.delete(ann)
task.done = False
task.annotated_on = None
db.session.commit()
# record the annotation
if annotation["changepoints"] is None:
ann = Annotation(cp_index=None, task_id=task_id)
db.session.add(ann)
db.session.commit()
else:
for cp in annotation["changepoints"]:
ann = Annotation(cp_index=cp["x"], task_id=task_id)
db.session.add(ann)
db.session.commit()
# mark the task as done
task.done = True
task.annotated_on = now
db.session.commit()
flash("Your annotation has been recorded, thank you!", "success")
return url_for("main.index")
task = Task.query.filter_by(id=task_id).first()
if task is None:
flash("No task with id %r exists." % task_id, "error")
return redirect(url_for("main.index"))
if not task.annotator_id == current_user.id:
flash(
"No task with id %r has been assigned to you." % task_id, "error"
)
return redirect(url_for("main.index"))
if task.done:
flash("It's not possible to edit annotations at the moment.")
return redirect(url_for("main.index"))
data = load_data_for_chart(task.dataset.name, task.dataset.md5sum)
if data is None:
flash(
"An internal error occurred loading this dataset, the admin has been notified. Please try again later. We apologise for the inconvenience."
)
return render_template(
"annotate/index.html",
title=task.dataset.name.title(),
identifier=task.id,
data=data,
rubric=RUBRIC,
)
|