Exemple #1
0
 def get_project_data(obj):
     from crowdsourcing.serializers.project import ProjectSerializer
     project = ProjectSerializer(instance=obj.project,
                                 many=False,
                                 fields=('id', 'name', 'hash_id',
                                         'repetition')).data
     return project
Exemple #2
0
def check_project_completed(project_id):
    query = '''
         SELECT
              count(t.id) remaining

            FROM crowdsourcing_task t INNER JOIN (SELECT
                                                    group_id,
                                                    max(id) id
                                                  FROM crowdsourcing_task
                                                  WHERE deleted_at IS NULL
                                                  GROUP BY group_id) t_max ON t_max.id = t.id
              INNER JOIN crowdsourcing_project p ON p.id = t.project_id
              INNER JOIN (
                           SELECT
                             t.group_id,
                             sum(t.others) OTHERS
                           FROM (
                                  SELECT
                                    t.group_id,
                                    CASE WHEN tw.id IS NOT NULL THEN 1 ELSE 0 END OTHERS
                                  FROM crowdsourcing_task t
                                    LEFT OUTER JOIN crowdsourcing_taskworker tw
                                    ON (t.id = tw.task_id AND tw.status NOT IN (4, 6, 7))
                                  WHERE t.exclude_at IS NULL AND t.deleted_at IS NULL) t
                           GROUP BY t.group_id) t_count ON t_count.group_id = t.group_id
            WHERE t_count.others < p.repetition AND p.id=(%(project_id)s)
            GROUP BY p.id;
    '''
    params = {
        "project_id": project_id
    }
    cursor = connection.cursor()
    cursor.execute(query, params)
    remaining_count = cursor.fetchall()[0][0] if cursor.rowcount > 0 else 0
    print(remaining_count)
    if remaining_count == 0:
        with transaction.atomic():
            project = models.Project.objects.select_for_update().get(id=project_id)
            if project.is_prototype:
                feedback = project.comments.all()
                if feedback.count() > 0 and feedback.filter(ready_for_launch=True).count() / feedback.count() < 0.66:
                    # mandatory stop
                    pass
                else:
                    from crowdsourcing.serializers.project import ProjectSerializer
                    from crowdsourcing.viewsets.project import ProjectViewSet

                    needs_workers = project.repetition < project.aux_attributes.get('repetition', project.repetition)
                    needs_tasks = project.tasks.filter(exclude_at__isnull=True).count < project.aux_attributes.get(
                        'number_of_tasks')
                    if needs_workers or needs_tasks:
                        serializer = ProjectSerializer()
                        revision = ProjectSerializer.create_revision(project)
                        revision.repetition = revision.aux_attributes.get('repetition', project.repetition)
                        revision.is_prototype = False
                        revision.save()
                        serializer.create_tasks(revision.id, False)
                        total_needed = ProjectViewSet.calculate_total(revision)
                        to_pay = (Decimal(total_needed) - revision.amount_due).quantize(Decimal('.01'),
                                                                                        rounding=ROUND_UP)
                        revision.amount_due = total_needed if total_needed is not None else 0
                        if to_pay * 100 > revision.owner.stripe_customer.account_balance:
                            return 'FAILED'
                        else:
                            serializer = ProjectSerializer(instance=revision, data={})
                            if serializer.is_valid():
                                serializer.publish(to_pay)
                            return 'SUCCESS'

            else:
                send_project_completed(to=project.owner.email, project_name=project.name, project_id=project_id)
    return 'SUCCESS'
Exemple #3
0
    def submit_results(self, request, mock=False, *args, **kwargs):
        task = request.data.get('task', None)
        auto_accept = request.data.get('auto_accept', False)
        template_items = request.data.get('items', [])
        task_status = request.data.get('status', None)
        saved = request.data.get('saved')
        task_worker = None
        if mock:
            task_status = TaskWorker.STATUS_SUBMITTED
            template_items = kwargs['items']
            task_worker = kwargs['task_worker']

        with transaction.atomic():
            if not mock:
                task_worker = TaskWorker.objects.prefetch_related(
                    'task', 'task__project').get(worker=request.user,
                                                 task=task)
            task_worker_results = TaskWorkerResult.objects.filter(
                task_worker_id=task_worker.id)

            if task_status == TaskWorker.STATUS_IN_PROGRESS:
                serializer = TaskWorkerResultSerializer(data=template_items,
                                                        many=True,
                                                        partial=True)
            else:
                serializer = TaskWorkerResultSerializer(data=template_items,
                                                        many=True)

            if serializer.is_valid():
                task_worker.status = task_status
                task_worker.save()
                if task_status == TaskWorker.STATUS_SUBMITTED:
                    redis_publisher = RedisPublisher(
                        facility='bot', users=[task_worker.task.project.owner])

                    task = task_worker.task
                    message = {
                        "type": "REGULAR",
                        "payload": {
                            'project_id':
                            task_worker.task.project_id,
                            'project_key':
                            ProjectSerializer().get_hash_id(
                                task_worker.task.project),
                            'task_id':
                            task_worker.task_id,
                            'task_group_id':
                            task_worker.task.group_id,
                            'taskworker_id':
                            task_worker.id,
                            'worker_id':
                            task_worker.worker_id
                        }
                    }
                    if task.project.is_review:
                        match_group = MatchGroup.objects.get(batch=task.batch)
                        if is_final_review(match_group.batch_id):
                            message = get_review_redis_message(
                                match_group.id,
                                ProjectSerializer().get_hash_id(
                                    task_worker.task.project))
                    message = RedisMessage(json.dumps(message))

                    redis_publisher.publish_message(message)

                if task_worker_results.count() != 0:
                    serializer.update(task_worker_results,
                                      serializer.validated_data)
                else:
                    serializer.create(task_worker=task_worker)

                update_worker_cache.delay([task_worker.worker_id],
                                          constants.TASK_SUBMITTED)
                winner_id = task_worker_results[0].result
                update_ts_scores(task_worker, winner_id)
                if task_status == TaskWorker.STATUS_IN_PROGRESS or saved or mock:
                    return Response('Success', status.HTTP_200_OK)
                elif task_status == TaskWorker.STATUS_SUBMITTED and not saved:

                    if not auto_accept:
                        serialized_data = {}
                        http_status = 204
                        return Response(serialized_data, http_status)

                    task_worker_serializer = TaskWorkerSerializer()
                    instance, http_status = task_worker_serializer.create(
                        worker=request.user,
                        project=task_worker.task.project_id)
                    serialized_data = {}

                    if http_status == status.HTTP_200_OK:
                        serialized_data = TaskWorkerSerializer(
                            instance=instance).data
                        update_worker_cache.delay([task_worker.worker_id],
                                                  constants.TASK_ACCEPTED)

                    return Response(serialized_data, http_status)
            else:
                return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
Exemple #4
0
    def submit_results(self, request, *args, **kwargs):
        mturk_assignment = self.get_object()
        template_items = request.data.get('items', [])

        with transaction.atomic():
            task_worker_results = TaskWorkerResult.objects.filter(
                task_worker_id=mturk_assignment.task_worker.id)
            serializer = TaskWorkerResultSerializer(data=template_items,
                                                    many=True)

            if serializer.is_valid():
                if task_worker_results.count() != 0:
                    serializer.update(task_worker_results,
                                      serializer.validated_data)
                else:
                    serializer.create(task_worker=mturk_assignment.task_worker)

                if mturk_assignment.status == TaskWorker.STATUS_SKIPPED:
                    in_progress_assignment = MTurkAssignment.objects. \
                        filter(hit=mturk_assignment.hit, assignment_id=mturk_assignment.assignment_id,
                               status=TaskWorker.STATUS_IN_PROGRESS).first()

                    if in_progress_assignment is not None and in_progress_assignment.task_worker is not None:
                        in_progress_assignment.status = TaskWorker.STATUS_SKIPPED
                        in_progress_assignment.task_worker.status = TaskWorker.STATUS_SKIPPED
                        in_progress_assignment.task_worker.save()

                        in_progress_assignment.save()

                mturk_assignment.task_worker.task_status = TaskWorker.STATUS_SUBMITTED
                mturk_assignment.task_worker.status = TaskWorker.STATUS_SUBMITTED
                mturk_assignment.task_worker.save()

                mturk_assignment.status = TaskWorker.STATUS_SUBMITTED
                mturk_assignment.save()

                task_worker = mturk_assignment.task_worker

                task_data = task_worker.task.data

                redis_publisher = RedisPublisher(
                    facility='bot', users=[task_worker.task.project.owner])
                task = task_worker.task

                task_workers = TaskWorker.objects.filter(
                    task__group_id=task_worker.task.group_id,
                    status__in=[
                        TaskWorker.STATUS_ACCEPTED, TaskWorker.STATUS_SUBMITTED
                    ])

                message = {
                    "type": "REGULAR",
                    "payload": {
                        'project_id':
                        task_worker.task.project_id,
                        'project_key':
                        ProjectSerializer().get_hash_id(
                            task_worker.task.project),
                        'task_id':
                        task_worker.task_id,
                        'task_group_id':
                        task_worker.task.group_id,
                        'taskworker_id':
                        task_worker.id,
                        'worker_id':
                        task_worker.worker_id,
                        'expected':
                        max(task_workers.count(),
                            task_worker.task.project.repetition),
                    }
                }

                if task.project.is_review:
                    match_group = MatchGroup.objects.get(batch=task.batch)
                    if is_final_review(task.batch_id):
                        message = {
                            "type": "REVIEW",
                            "payload": {
                                "match_group_id":
                                match_group.id,
                                'project_key':
                                ProjectSerializer().get_hash_id(
                                    task_worker.task.project),
                                "is_done":
                                True
                            }
                        }
                message = RedisMessage(json.dumps(message))

                redis_publisher.publish_message(message)
                update_worker_cache.delay([task_worker.worker_id],
                                          constants.TASK_SUBMITTED)

                if task.project.is_review:
                    winner_id = task_worker_results[0].result
                    update_ts_scores(task_worker, winner_id=winner_id)

                if "gold_truth" in task_data:
                    truth = dict()
                    truth["message"] = "truth"
                    truth["truth"] = task_data.get("gold_truth")
                    return Response(data=truth, status=status.HTTP_200_OK)

                return Response(data={'message': 'Success'},
                                status=status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)