예제 #1
0
    def update_tasks_redundancy(self, project, n_answers, filters=None):
        """
        Update the n_answer of every task from a project and their state.
        Use raw SQL for performance. Mark tasks as exported = False for
        tasks with curr redundancy < new redundancy, with state as completed
        and were marked as exported = True
        """
        from pybossa.jobs import check_and_send_task_notifications

        if n_answers < self.MIN_REDUNDANCY or n_answers > self.MAX_REDUNDANCY:
            raise ValueError("Invalid redundancy value: {}".format(n_answers))

        filters = filters or {}
        task_expiration = '{} day'.format(self.rdancy_upd_exp)
        conditions, params = get_task_filters(filters)
        tasks_not_updated = self._get_redundancy_update_msg(
            project, n_answers, conditions, params, task_expiration)

        self.update_task_exported_status(project.id, n_answers, conditions, params, task_expiration)
        sql = text('''
                   WITH all_tasks_with_orig_filter AS (
                        SELECT task.id as id,
                        coalesce(ct, 0) as n_task_runs, task.n_answers, ft,
                        priority_0, task.created
                        FROM task LEFT OUTER JOIN
                        (SELECT task_id, CAST(COUNT(id) AS FLOAT) AS ct,
                        MAX(finish_time) as ft FROM task_run
                        WHERE project_id=:project_id GROUP BY task_id) AS log_counts
                        ON task.id=log_counts.task_id
                        WHERE task.project_id=:project_id {}
                   ),

                   tasks_with_file_urls AS (
                        SELECT t.id as id FROM task t
                        WHERE t.id IN (SELECT id from all_tasks_with_orig_filter)
                        AND jsonb_typeof(t.info) = 'object'
                        AND EXISTS(SELECT TRUE FROM jsonb_object_keys(t.info) AS key
                        WHERE key ILIKE '%\_\_upload\_url%')
                   ),

                   tasks_excl_file_urls AS (
                        SELECT id FROM all_tasks_with_orig_filter
                        WHERE id NOT IN (SELECT id FROM tasks_with_file_urls)
                   )

                   UPDATE task SET n_answers=:n_answers,
                   state='ongoing' WHERE project_id=:project_id AND
                   ((id IN (SELECT id from tasks_excl_file_urls)) OR
                   (id IN (SELECT id from tasks_with_file_urls) AND state='ongoing'
                   AND TO_DATE(created, 'YYYY-MM-DD\THH24:MI:SS.US') >= NOW() - :task_expiration ::INTERVAL));'''
                   .format(conditions))
        self.db.session.execute(sql, dict(n_answers=n_answers,
                                          project_id=project.id,
                                          task_expiration=task_expiration,
                                          **params))
        self.update_task_state(project.id)
        self.db.session.commit()
        cached_projects.clean_project(project.id)
        check_and_send_task_notifications(project.id)
        return tasks_not_updated
예제 #2
0
    def test_remaining_tasks_drop_below_configuration_2(self, notify, n_tasks):
        """Do not sent multiple email"""
        n_tasks.return_value = 0
        reminder = dict(target_remaining=0, sent=True)
        project_id = '1'
        project = ProjectFactory.create(id=project_id,
                                        owners_ids=[],
                                        published=True,
                                        featured=True,
                                        info={'progress_reminder': reminder})

        check_and_send_task_notifications(project_id)
        assert not notify.called
        assert project.info['progress_reminder']['sent']
예제 #3
0
    def test_remaining_tasks_drop_below_configuration_0(self, notify, n_tasks):
        """Send email if remaining tasks drops below, test with connection"""
        n_tasks.return_value = 0
        reminder = dict(target_remaining=0, sent=False)
        conn = MagicMock()
        conn.execute.return_value = None
        project_id = '1'
        project = ProjectFactory.create(id=project_id,
                                        owners_ids=[],
                                        published=True,
                                        featured=True,
                                        info={'progress_reminder': reminder})

        check_and_send_task_notifications(project_id, conn)
        assert notify.called
        assert project.info['progress_reminder']['sent']
예제 #4
0
    def delete_task_by_id(self, project_id, task_id):
        from pybossa.jobs import check_and_send_task_notifications

        args = dict(project_id=project_id, task_id=task_id)
        self.db.session.execute(text('''
                   DELETE FROM result WHERE project_id=:project_id
                                      AND task_id=:task_id;'''), args)
        self.db.session.execute(text('''
                   DELETE FROM task_run WHERE project_id=:project_id
                                        AND task_id=:task_id;'''), args)
        self.db.session.execute(text('''
                   DELETE FROM task WHERE project_id=:project_id
                                    AND id=:task_id;'''), args)
        self.db.session.commit()
        cached_projects.clean_project(project_id)
        check_and_send_task_notifications(project_id)
예제 #5
0
def on_taskrun_submit(mapper, conn, target):
    """Update the task.state when n_answers condition is met."""
    # Get project details
    sql_query = (
        'select name, short_name, published, webhook, info, category_id \
                 from project where id=%s') % target.project_id
    results = conn.execute(sql_query)
    tmp = dict()
    for r in results:
        tmp['name'] = r.name
        tmp['short_name'] = r.short_name
        _published = r.published
        tmp['info'] = r.info
        _webhook = r.webhook
        tmp['category_id'] = r.category_id
        tmp['id'] = target.project_id

    project_public = dict()
    project_public.update(Project().to_public_json(tmp))
    project_public['action_updated'] = 'TaskCompleted'

    sched.after_save(target, conn)
    add_user_contributed_to_feed(conn, target.user_id, project_public)

    # golden tasks never complete; bypass update to task.state
    # mark task as exported false for each task run submissions
    task = task_repo.get_task(id=target.task_id)
    if task.calibration:
        if task.exported and _published:
            sql_query = ("""UPDATE task SET exported=False \
                           WHERE id=%s;""") % (task.id)
            conn.execute(sql_query)
        return

    is_completed = is_task_completed(conn, target.task_id, target.project_id)
    if is_completed:
        update_task_state(conn, target.task_id)
        check_and_send_task_notifications(target.project_id, conn)

    if is_completed and _published:
        update_feed(project_public)
        result_id = create_result(conn, target.project_id, target.task_id)
        project_private = dict()
        project_private.update(project_public)
        project_private['webhook'] = _webhook
        push_webhook(project_private, target.task_id, result_id)
예제 #6
0
    def test_remaining_tasks_drop_below_configuration_hitting_webhook_failed(
            self, notify, n_tasks, req):
        """Send email if remaining tasks drops below, test with connection"""
        n_tasks.return_value = 0
        req.post.side_effect = Exception('not found')
        reminder = dict(target_remaining=0, webhook="fake_url", sent=False)
        conn = MagicMock()
        conn.execute.return_value = None
        project_id = '1'
        project = ProjectFactory.create(id=project_id,
                                        owners_ids=[],
                                        published=True,
                                        featured=True,
                                        info={'progress_reminder': reminder})

        check_and_send_task_notifications(project_id, conn)
        assert req.post.called
        assert project.info['progress_reminder']['sent']
예제 #7
0
def calculate_and_send_progress_after_update_task(mapper, conn, target):
    check_and_send_task_notifications(target.project_id, conn)