def test_n_available_tasks_include_gold_task(self): """Test n_available_tasks returns 0 for user if he has submitted taskruns for all the tasks""" project = ProjectFactory.create() task = TaskFactory.create(project=project, calibration=1) n_available_tasks_include_gold = helpers.n_available_tasks( project.id, include_gold_task=True) n_available_tasks_exclude_gold = helpers.n_available_tasks(project.id) assert task.state != 'completed', task.state assert n_available_tasks_include_gold == 1, n_available_tasks_include_gold assert n_available_tasks_exclude_gold == 0, n_available_tasks_exclude_gold
def user_progress(project_id=None, short_name=None): """API endpoint for user progress. Return a JSON object with two fields regarding the tasks for the user: { 'done': 10, 'total: 100, 'remaining': 90 } This will mean that the user has done a 10% of the available tasks for him and 90 tasks are yet to be submitted """ if current_user.is_anonymous(): return abort(401) if project_id or short_name: if short_name: project = project_repo.get_by_shortname(short_name) elif project_id: project = project_repo.get(project_id) if project: # For now, keep this version, but wait until redis cache is used here for task_runs too query_attrs = dict(project_id=project.id) query_attrs['user_id'] = current_user.id taskrun_count = task_repo.count_task_runs_with(**query_attrs) num_available_tasks = n_available_tasks(project.id, current_user.id) tmp = dict(done=taskrun_count, total=n_tasks(project.id), remaining=num_available_tasks) return Response(json.dumps(tmp), mimetype="application/json") else: return abort(404) else: # pragma: no cover return abort(404)
def test_n_available_tasks_no_tasks(self): """Test n_available_tasks returns 0 for user if the project has no tasks""" project = ProjectFactory.create() n_available_tasks = helpers.n_available_tasks(project.id) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_tasks_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if the project has no tasks""" project = ProjectFactory.create() n_available_tasks = helpers.n_available_tasks(project.id, user_id=1) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_tasks_anonymous_user(self): """Test n_available_tasks returns 0 for anonymous user if the app has no tasks""" app = AppFactory.create() n_available_tasks = helpers.n_available_tasks(app.id, user_ip='127.0.0.1') assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_tasks_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if the app has no tasks""" app = AppFactory.create() n_available_tasks = helpers.n_available_tasks(app.id, user_id=1) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_tasks_anonymous_user(self): """Test n_available_tasks returns 0 for anonymous user if the project has no tasks""" project = ProjectFactory.create() n_available_tasks = helpers.n_available_tasks(project.id, user_ip='127.0.0.1') assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_taskruns_anonymous_user(self): """Test n_available_tasks returns 1 for anonymous user if there are no taskruns""" app = AppFactory.create() task = TaskFactory.create(app=app) n_available_tasks = helpers.n_available_tasks(app.id, user_ip='127.0.0.1') assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_no_taskruns_authenticated_user(self): """Test n_available_tasks returns 1 for authenticated user if there are no taskruns""" app = AppFactory.create() task = TaskFactory.create(app=app) n_available_tasks = helpers.n_available_tasks(app.id, user_id=1) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_completed_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if all the tasks are completed""" app = AppFactory.create() task = TaskFactory.create(app=app, state='completed') n_available_tasks = helpers.n_available_tasks(app.id, user_id=1) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_all_tasks_completed(self): """Test n_available_tasks returns 0 for user if all the tasks are completed""" project = ProjectFactory.create() task = TaskFactory.create(project=project, state='completed') n_available_tasks = helpers.n_available_tasks(project.id) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_taskruns_anonymous_user(self): """Test n_available_tasks returns 1 for anonymous user if there are no taskruns""" project = ProjectFactory.create() task = TaskFactory.create(project=project) n_available_tasks = helpers.n_available_tasks(project.id, user_ip='127.0.0.1') assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_completed_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if all the tasks are completed""" project = ProjectFactory.create() task = TaskFactory.create(project=project, state='completed') n_available_tasks = helpers.n_available_tasks(project.id, user_id=1) assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_taskruns(self): """Test n_available_tasks returns 1 for authenticated user if there are no taskruns""" project = ProjectFactory.create() task = TaskFactory.create(project=project) n_available_tasks = helpers.n_available_tasks(project.id) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_completed_anonymous_user(self): """Test n_available_tasks returns 0 for anonymous user if all the tasks are completed""" project = ProjectFactory.create() task = TaskFactory.create(project=project, state='completed') n_available_tasks = helpers.n_available_tasks(project.id, user_ip='127.0.0.1') assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_no_taskruns_authenticated_user(self): """Test n_available_tasks returns 1 for authenticated user if there are no taskruns""" project = ProjectFactory.create() task = TaskFactory.create(project=project) n_available_tasks = helpers.n_available_tasks(project.id, user_id=1) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_task_answered_by_another_user(self): """Test n_available_tasks returns 1 for a user if another user has submitted taskruns for the task but he hasn't""" project = ProjectFactory.create() task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_some_task_answered_by_another_user(self): """Test n_available_tasks returns 1 for a user if another user has submitted taskruns for the task but he hasn't""" project = ProjectFactory.create() task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_answered_by_anonymous_user(self): """Test n_available_tasks returns 0 for anonymous user if he has submitted taskruns for all the tasks""" project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=2) taskrun = AnonymousTaskRunFactory.create(task=task) n_available_tasks = helpers.n_available_tasks(project.id, user_ip=taskrun.user_ip) assert task.state != 'completed', task.state assert n_available_tasks == 0, n_available_tasks
def test_n_available_tasks_some_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 1 for authenticated user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=answered_task, user=user) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_some_tasks_answered_by_anonymous_user(self): """Test n_available_tasks returns 1 for anonymous user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) taskrun = AnonymousTaskRunFactory.create(task=answered_task) n_available_tasks = helpers.n_available_tasks(project.id, user_ip=taskrun.user_ip) assert n_available_tasks == 1, n_available_tasks
def test_n_available_some_all_tasks_answered_by_anonymous_user(self): """Test n_available_tasks returns 1 for anonymous user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) taskrun = AnonymousTaskRunFactory.create(task=answered_task) n_available_tasks = helpers.n_available_tasks(project.id, user_ip=taskrun.user_ip) assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if he has submitted taskruns for all the tasks""" project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=2) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task, user=user) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert task.state != 'completed', task.state assert n_available_tasks == 0, n_available_tasks
def user_progress(project_id=None, short_name=None): """API endpoint for user progress. Return a JSON object with four fields regarding the tasks for the user: { 'done': 10, 'total: 100, 'remaining': 90, 'remaining_for_user': 45 } This will mean that the user has done 10% of the available tasks for the project, 90 tasks are yet to be submitted and the user can access 45 of them based on user preferences. """ if current_user.is_anonymous: return abort(401) if project_id or short_name: if short_name: project = project_repo.get_by_shortname(short_name) elif project_id: project = project_repo.get(project_id) if project: # For now, keep this version, but wait until redis cache is # used here for task_runs too query_attrs = dict(project_id=project.id, user_id=current_user.id) guidelines_updated = _guidelines_updated(project.id, current_user.id) taskrun_count = task_repo.count_task_runs_with(**query_attrs) num_available_tasks = n_available_tasks(project.id, include_gold_task=True) num_available_tasks_for_user = n_available_tasks_for_user( project, current_user.id) response = dict(done=taskrun_count, total=n_tasks(project.id), completed=n_completed_tasks(project.id), remaining=num_available_tasks, locked=len({ task["task_id"] for task in get_locked_tasks(project) }), remaining_for_user=num_available_tasks_for_user, quiz=current_user.get_quiz_for_project(project), guidelines_updated=guidelines_updated) if current_user.admin or (current_user.subadmin and current_user.id in project.owners_ids): num_gold_tasks = n_unexpired_gold_tasks(project.id) response['available_gold_tasks'] = num_gold_tasks return Response(json.dumps(response), mimetype="application/json") else: return abort(404) else: # pragma: no cover return abort(404)
def test_n_available_tasks_all_tasks_answered_by_user(self): """Test n_available_tasks returns 0 for user if he has submitted taskruns for all the tasks""" user = UserFactory.create() project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=2) taskrun = TaskRunFactory.create(task=task, user=user) n_available_tasks = helpers.n_available_tasks(project.id) assert task.state != 'completed', task.state assert n_available_tasks == 1, n_available_tasks
def test_n_available_tasks_all_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if he has submitted taskruns for all the tasks""" app = AppFactory.create() task = TaskFactory.create(app=app, n_answers=2) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task, user=user) n_available_tasks = helpers.n_available_tasks(app.id, user_id=user.id) assert task.state != 'completed', task.state assert n_available_tasks == 0, n_available_tasks
def get_projects_report(self, base_url): results = project_repo.get_projects_report() projects = [] for row in results: owners_ids = project_repo.get_by_shortname( row.short_name).owners_ids coowners = (co for co in user_repo.get_users(owners_ids) if co.name != row.owner_name) num_available_tasks = n_available_tasks(row.id) coowner_names = '|'.join('{};{}'.format(co.name, co.email_addr) for co in coowners) if not coowner_names: coowner_names = 'None' has_completed = str(num_available_tasks == 0) project = OrderedDict([('id', row.id), ('name', row.name), ('short_name', row.short_name), ('url', base_url + row.short_name), ('description', row.description), ('long_description', row.long_description), ('created', row.created), ('owner_name', row.owner_name), ('owner_email', row.owner_email), ('coowners', coowner_names), ('category_name', row.category_name), ('allow_anonymous_contributors', row.allow_anonymous_contributors), ('password_protected', row.password_protected), ('webhook', row.webhook), ('scheduler', row.scheduler), ('has_completed', has_completed), ('finish_time', row.ft), ('percent_complete', row.percent_complete), ('n_tasks', row.n_tasks), ('pending_tasks', row.pending_tasks), ('n_workers', row.n_workers), ('n_answers', row.n_answers), ('workers', row.workers), ('updated', row.updated), ('oldest_available', row.oldest_available), ('last_submission', row.last_submission), ('n_taskruns', row.n_taskruns), ('pending_taskruns', row.pending_taskruns)]) projects.append(project) return pd.DataFrame(projects)
def user_progress(project_id=None, short_name=None): """API endpoint for user progress. Return a JSON object with four fields regarding the tasks for the user: { 'done': 10, 'total: 100, 'remaining': 90, 'remaining_for_user': 45 } This will mean that the user has done 10% of the available tasks for the project, 90 tasks are yet to be submitted and the user can access 45 of them based on user preferences. """ if current_user.is_anonymous: return abort(401) if project_id or short_name: if short_name: project = project_repo.get_by_shortname(short_name) elif project_id: project = project_repo.get(project_id) if project: # For now, keep this version, but wait until redis cache is # used here for task_runs too query_attrs = dict(project_id=project.id) query_attrs['user_id'] = current_user.id taskrun_count = task_repo.count_task_runs_with(**query_attrs) num_available_tasks = n_available_tasks(project.id, current_user.id) num_available_tasks_for_user = n_available_tasks_for_user( project, current_user.id) response = dict(done=taskrun_count, total=n_tasks(project.id), remaining=num_available_tasks, remaining_for_user=num_available_tasks_for_user, quiz=current_user.get_quiz_for_project(project)) return Response(json.dumps(response), mimetype="application/json") else: return abort(404) else: # pragma: no cover return abort(404)
def get_projects_report(self, base_url): sql = text( '''WITH completed_tasks AS ( SELECT task.project_id, COUNT(DISTINCT task.id) AS value, MAX(task_run.finish_time) AS ft FROM task INNER JOIN task_run on task.id = task_run.task_id WHERE task.state = 'completed' GROUP BY task.project_id ), all_tasks AS ( SELECT project_id, COUNT(task.id) AS value FROM task GROUP BY project_id ), workers AS ( SELECT DISTINCT project_id, user_id, public.user.fullname, public.user.email_addr FROM task_run INNER JOIN public.user ON task_run.user_id = public.user.id ), n_workers AS ( SELECT project_id, COUNT(user_id) as value FROM workers GROUP BY project_id ) SELECT project.id, project.name, project.short_name, project.description, project.long_description, project.created, u.name as owner_name, u.email_addr as owner_email, category.name as category_name, project.allow_anonymous_contributors, ( COALESCE(project.info::json ->> 'passwd_hash', 'null') != 'null' ) as password_protected, project.webhook, COALESCE(project.info::json ->> 'sched', 'default') as scheduler, completed_tasks.ft, CASE WHEN all_tasks.value = 0 OR completed_tasks.value IS NULL THEN 0 ELSE completed_tasks.value * 100 / all_tasks.value END as percent_complete, COALESCE(all_tasks.value, 0) AS n_tasks, COALESCE(all_tasks.value, 0) - COALESCE(completed_tasks.value, 0) AS pending_tasks, COALESCE(n_workers.value, 0) as n_workers, ( SELECT n_answers FROM task WHERE project_id = project.id ORDER BY task.id DESC LIMIT 1 ) as n_answers, ( SELECT string_agg(concat('(', workers.user_id, ';', workers.fullname, ';', workers.email_addr, ')'), '|') FROM workers WHERE project.id = workers.project_id ) as workers FROM project INNER JOIN public.user as u on project.owner_id = u.id INNER JOIN category on project.category_id = category.id LEFT OUTER JOIN completed_tasks ON project.id = completed_tasks.project_id LEFT OUTER JOIN all_tasks ON project.id = all_tasks.project_id LEFT OUTER JOIN n_workers ON project.id = n_workers.project_id;''') results = self.db.session.execute(sql) projects = [] for row in results: coowners = self.get_by_shortname(row.short_name).coowners num_available_tasks = n_available_tasks(row.id) has_completed = "False" coowner_names = "None" if coowners: coowner_names = "" for co in coowners: coowner_names += co.name + ";" + co.email_addr + "| " if num_available_tasks == 0: has_completed = "True" project = AttrDict([('id', row.id), ('name', row.name), ('short_name', row.short_name), ('url', base_url + row.short_name), ('description', row.description), ('long_description', row.long_description), ('created', row.created), ('owner_name', row.owner_name), ('owner_email', row.owner_email), ('coowners', coowner_names), ('category_name', row.category_name), ('allow_anonymous_contributors', row.allow_anonymous_contributors), ('password_protected', row.password_protected), ('webhook', row.webhook), ('scheduler', row.scheduler), ('has_completed', has_completed), ('finish_time', row.ft), ('percent_complete', row.percent_complete), ('n_tasks', row.n_tasks), ('pending_tasks', row.pending_tasks), ('n_workers', row.n_workers), ('n_answers', row.n_answers), ('workers', row.workers) ]) projects.append(project) return projects