diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2019-09-13 15:27:37 +0100 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2019-09-13 15:27:37 +0100 |
| commit | 85e36328f7bd5033efaa92c3b040769eb2eee181 (patch) | |
| tree | 172706ab0dec53f468ec7962d5bc172788e42c35 | |
| parent | Remove y-axis value from table (diff) | |
| download | AnnotateChange-85e36328f7bd5033efaa92c3b040769eb2eee181.tar.gz AnnotateChange-85e36328f7bd5033efaa92c3b040769eb2eee181.zip | |
Assign new tasks on the fly
The old logic assigned a task when the user finished the
demo, logged in, or finished an annotation. This was not
optimal as it could lead to race conditions where some
datasets were annotated unnecessarily. With this change
we select the dataset to annotate at the exact moment the
user wants to do another one.
| -rw-r--r-- | app/auth/routes.py | 31 | ||||
| -rw-r--r-- | app/main/demo.py | 8 | ||||
| -rw-r--r-- | app/main/routes.py | 37 | ||||
| -rw-r--r-- | app/templates/index.html | 56 |
4 files changed, 55 insertions, 77 deletions
diff --git a/app/auth/routes.py b/app/auth/routes.py index fa792c2..0556233 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -30,8 +30,7 @@ from app.auth.email import ( send_password_reset_email, send_email_confirmation_email, ) -from app.models import User, Task -from app.utils.tasks import generate_user_task +from app.models import User, Task, Annotation LEGAL = markdown.markdown( @@ -92,6 +91,21 @@ def login(): current_user.last_active = datetime.datetime.utcnow() db.session.commit() + # remove any assigned unfinished datasets, as these may no longer be + # needed + user_tasks = Task.query.filter_by( + annotator_id=current_user.id, done=False + ).all() + for task in user_tasks: + anns = Annotation.query.filter_by(task_id=task.id).all() + if len(anns) > 0: + flash( + "Internal error, unfinished tasks has annotations!", + "error", + ) + db.session.delete(task) + db.session.commit() + # redirect if not confirmed yet if not user.is_confirmed: return redirect(url_for("auth.not_confirmed")) @@ -105,19 +119,6 @@ def login(): if not user.is_introduced: return redirect(url_for("main.index")) - # assign task if no remaining and not at maximum. - remaining = Task.query.filter_by( - annotator_id=user.id, done=False - ).all() - if remaining: - return redirect(next_page) - - task = generate_user_task(user) - if task is None: - return redirect(next_page) - - db.session.add(task) - db.session.commit() return redirect(next_page) return render_template("auth/login.html", title="Sign In", form=form) diff --git a/app/main/demo.py b/app/main/demo.py index bc9e7bd..3be8258 100644 --- a/app/main/demo.py +++ b/app/main/demo.py @@ -23,7 +23,6 @@ from app.main import bp from app.main.forms import NextForm from app.main.routes import RUBRIC from app.utils.datasets import load_data_for_chart, get_demo_true_cps -from app.utils.tasks import generate_user_task LOGGER = logging.getLogger(__name__) @@ -381,13 +380,6 @@ def redirect_user(demo_id, phase_id): current_user.is_introduced = True db.session.commit() - # assign a task to the user - task = generate_user_task(current_user) - if task is None: - return redirect(url_for("main.index")) - db.session.add(task) - db.session.commit() - return redirect(url_for("main.index")) elif phase_id == demo_last_phase_id: demo_id += 1 diff --git a/app/main/routes.py b/app/main/routes.py index 13fe3f8..8a0e83e 100644 --- a/app/main/routes.py +++ b/app/main/routes.py @@ -46,6 +46,32 @@ def index(): return render_template("index.html", title="Home") +@bp.route("/assign") +@login_required +def assign(): + # Intermediate page that assigns a task to a user if needed and then + # redirects to /annotate/task.id + user_tasks = Task.query.filter_by(annotator_id=current_user.id).all() + user_tasks = [t for t in user_tasks if not t.dataset.is_demo] + user_tasks = [t for t in user_tasks if not t.done] + + # if the user has, for some reason, a unfinished assigned task, redirect to + # that + if len(user_tasks) > 0: + task = user_tasks[0] + return redirect(url_for("main.annotate", task_id=task.id)) + + task = generate_user_task(current_user) + if task is None: + flash( + "There are no more datasets to annotate at the moment, thanks for all your help!", + "info", + ) + return redirect(url_for("main.index")) + db.session.add(task) + db.session.commit() + return redirect(url_for("main.annotate", task_id=task.id)) + @bp.route("/annotate/<int:task_id>", methods=("GET", "POST")) @login_required def annotate(task_id): @@ -94,17 +120,6 @@ def annotate(task_id): "annotations_raw": annotation, } send_annotation_backup(record) - - # assign a new task if necessary - task = generate_user_task(current_user) - if task is None: - return url_for("main.index") - db.session.add(task) - db.session.commit() - flash( - "A new dataset has been assigned for you to annotate. Thanks for your help!", - "info", - ) return url_for("main.index") task = Task.query.filter_by(id=task_id).first() diff --git a/app/templates/index.html b/app/templates/index.html index 1606f2a..e1648c0 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -28,8 +28,7 @@ <br> <br> <p> - When you have finished the introduction, the datasets to annotate - will appear here. + Once you have finished the introduction you will be able to annotate real datasets. </p> {% endif %} {% else %} @@ -37,52 +36,23 @@ Thank you for completing the introduction. If you want to revisit it, you can do so by <a href="{{ url_for('main.demo') }}">clicking here</a>. </p> - {% if tasks_todo|length == 0 and tasks_done|length == 0 %} - <br> - <br> - <p> - There are currently no datasets for you to annotate. Please check back - again later. - </p> - {% endif %} {% endif %} - {% if tasks_todo %} - <h3>Datasets to Annotate</h3> - <p> - Below are the datasets that we would like you to annotate, thank you - very much for your help! - </p> - <div class="tasks-todo"> - <table class="table table-striped"> - <thead class="thead-dark"> - <th scope="col">Name</th> - </thead> - {% for task in tasks_todo %} - <tr> - <td> - <a href="{{ url_for('main.annotate', task_id=task.id) }}"> - {% if current_user.is_admin %} - {{ task.dataset.name | title }} - {% else %} - Dataset {{ task.dataset.id | title }} - {% endif %} - </a> - </td> - </tr> - {% endfor %} - </table> - </div> - {% elif tasks_todo|length == 0 and tasks_done|length > 0 %} - <div id="done"> - <img src="{{ url_for('static', filename='img/done.png') }}"> - <span> - No more annotations to do! Thank you so much for your help, - <b>you rock!</b> - </span> + {% if current_user.is_introduced %} + <h3>Doing Annotations</h3> + {% if tasks_done|length == 0 %} + <p>Click the button below to start annotating!</p> + {% else %} + <p>Click the button below to do some more annotations!</p> + {% endif %} + <div id="annotate-button"> + <a class="btn btn-primary btn-lg btn-block" href="{{ url_for('main.assign') }}" role="button"> + Click here to annotate a time series! + </a> </div> {% endif %} {% if tasks_done %} <h3>Completed Annotations</h3> + <p>Below are the time series that you've annotated so far. Thanks so much for your help!</p> <div class="tasks-done"> <table class="table table-striped"> <thead> |
