def change_username(self, request, username=None): user = request.user serializer = UserSerializer(instance=user, data=request.data, partial=True) if serializer.is_valid(): serializer.change_username() return Response({"message": "Username updated successfully."}) raise serializers.ValidationError(detail=serializer.errors)
def change_password(self, request, username=None): user = request.user serializer = UserSerializer(validate_non_fields=True, instance=user, data=request.data, partial=True) if serializer.is_valid(): serializer.change_password() return Response({"message": "Password updated successfully."}, status.HTTP_200_OK) raise serializers.ValidationError(detail=serializer.errors)
def forgot_password(self, request): email = request.data.get('email', '') user = get_object_or_404(User, email=email) serializer = UserSerializer(context={'request': request}) serializer.send_forgot_password(user=user) return Response(data={'message': 'Email sent.'}, status=status.HTTP_201_CREATED)
def change_password(self, request, username=None): user = request.user serializer = UserSerializer(validate_non_fields=True, instance=user, data=request.data, partial=True) if serializer.is_valid(): serializer.change_password() return Response({"message": "Password updated successfully."}, status.HTTP_200_OK) return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): serializer = UserSerializer(validate_non_fields=True, data=request.data) if serializer.is_valid(): serializer.create() return Response(serializer.data) return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): serializer = UserSerializer(validate_non_fields=True, data=request.data, context={'request': request}) if serializer.is_valid(): with transaction.atomic(): serializer.create() return Response(serializer.data) return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
def change_username(self, request, username=None): user = request.user serializer = UserSerializer(instance=user, data=request.data, partial=True) if serializer.is_valid(): serializer.change_username() return Response({"message": "Username updated successfully."}) return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): request.data['admin_override'] = False serializer = UserSerializer(validate_non_fields=True, data=request.data, context={'request': request}) if serializer.is_valid(): serializer.create() return Response(serializer.data) return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): serializer = UserSerializer(validate_non_fields=True, data=request.data, context={'request': request}) if serializer.is_valid(): with transaction.atomic(): serializer.create() return Response({}) raise serializers.ValidationError(detail=serializer.errors)
def create(self, request, *args, **kwargs): serializer = UserSerializer(validate_non_fields=True, data=request.data, context={'request': request}) if serializer.is_valid(): with transaction.atomic(): serializer.create() return Response(serializer.data) raise serializers.ValidationError(detail=serializer.errors)
def forgot_password(self, request): email = request.data.get('email', '') user = get_object_or_404(User, email=email) serializer = UserSerializer(context={'request': request}) serializer.send_forgot_password(user=user) return Response(data={ 'message': 'Email sent.' }, status=status.HTTP_201_CREATED)
def ignore_password_reset(self, request): password_reset_model = get_object_or_404(PasswordResetModel, reset_key=request.data.get( 'reset_key', '')) serializer = UserSerializer(context={'request': request}) data, http_status = serializer.ignore_reset_password( reset_model=password_reset_model) return Response(data=data, status=http_status)
def reset_password(self, request): password = request.data.get('password', 'N') password_reset_model = get_model_or_none(PasswordResetModel, reset_key=request.data.get( 'reset_key', '')) serializer = UserSerializer(context={'request': request}) data, http_status = serializer.reset_password( reset_model=password_reset_model, password=password) return Response(data=data, status=http_status)
def list_username(self, request, *args, **kwargs): pattern = request.query_params.get('pattern', '$') user_names = self.queryset.exclude(username=request.user.username) \ .filter(~Q(username__startswith='mock'), is_active=True, profile__handle__icontains=pattern, profile__is_worker=True) serializer = UserSerializer(instance=user_names, many=True, fields=('id', 'handle')) return Response(data=serializer.data, status=status.HTTP_200_OK)
def authenticate(self, request): serializer = UserSerializer() response_data, status = serializer.authenticate(request) return Response(response_data, status)
def reset_password(self, request): password = request.data.get('password', 'N') password_reset_model = get_model_or_none(models.UserPasswordReset, reset_key=request.data.get('reset_key', '')) serializer = UserSerializer(context={'request': request}) data, http_status = serializer.reset_password(reset_model=password_reset_model, password=password) return Response(data=data, status=http_status)
def ignore_password_reset(self, request): password_reset_model = get_object_or_404(models.UserPasswordReset, reset_key=request.data.get('reset_key', '')) serializer = UserSerializer(context={'request': request}) data, http_status = serializer.ignore_reset_password(reset_model=password_reset_model) return Response(data=data, status=http_status)
def retrieve(self, request, username=None, *args, **kwargs): user = get_object_or_404(self.queryset, username=username) serializer = UserSerializer(instance=user) return Response(serializer.data)
class ProjectSerializer(DynamicFieldsModelSerializer): total_tasks = serializers.SerializerMethodField() age = serializers.SerializerMethodField() has_comments = serializers.SerializerMethodField() available_tasks = serializers.IntegerField(read_only=True) in_progress = serializers.IntegerField(read_only=True) completed = serializers.IntegerField(read_only=True) awaiting_review = serializers.IntegerField(read_only=True) comments = serializers.SerializerMethodField() relaunch = serializers.SerializerMethodField() requester_rating = serializers.FloatField(read_only=True, required=False) raw_rating = serializers.IntegerField(read_only=True, required=False) owner = UserSerializer(fields=('username', 'id'), read_only=True) batch_files = BatchFileSerializer(many=True, read_only=True, fields=('id', 'name', 'size', 'column_headers', 'format', 'number_of_rows')) template = TemplateSerializer(many=False, required=False) name = serializers.CharField(default='Untitled Project') status = serializers.IntegerField(default=models.Project.STATUS_DRAFT) file_id = serializers.IntegerField(write_only=True, allow_null=True, required=False) num_rows = serializers.IntegerField(write_only=True, allow_null=True, required=False) deadline = serializers.DateTimeField(required=False) revisions = serializers.SerializerMethodField() hash_id = serializers.SerializerMethodField() review_price = serializers.FloatField(required=False) has_review = serializers.BooleanField(required=False) class Meta: model = models.Project fields = ('id', 'name', 'owner', 'description', 'status', 'repetition', 'deadline', 'timeout', 'template', 'batch_files', 'deleted_at', 'created_at', 'updated_at', 'price', 'has_data_set', 'data_set_location', 'total_tasks', 'file_id', 'age', 'is_micro', 'is_prototype', 'has_review', 'task_time', 'allow_feedback', 'feedback_permissions', 'min_rating', 'has_comments', 'available_tasks', 'comments', 'num_rows', 'requester_rating', 'raw_rating', 'post_mturk', 'qualification', 'relaunch', 'group_id', 'revisions', 'hash_id', 'is_api_only', 'in_progress', 'awaiting_review', 'completed', 'review_price') read_only_fields = ( 'created_at', 'updated_at', 'deleted_at', 'owner', 'has_comments', 'available_tasks', 'comments', 'template', 'is_api_only') validators = [ProjectValidator()] def to_representation(self, instance): data = super(ProjectSerializer, self).to_representation(instance) task_time = int(instance.task_time.total_seconds() / 60) if instance.task_time is not None else None timeout = int(instance.timeout.total_seconds() / 60) if instance.timeout is not None else None review_project = models.Project.objects.filter(parent_id=instance.group_id, is_review=True, deleted_at__isnull=True).first() if review_project is not None: review_price = review_project.price data.update({'review_price': review_price}) data.update({'has_review': review_project is not None}) data.update({'task_time': task_time, 'timeout': timeout}) data.update({'price': instance.price}) return data def to_internal_value(self, data): if 'task_time' in data and data['task_time'] is not None: data['task_time'] = "00:{}:00".format(data['task_time']) if 'timeout' in data and data['timeout'] is not None: data['timeout'] = "00:{}:00".format(data['timeout']) return super(ProjectSerializer, self).to_internal_value(data) def create(self, with_defaults=True, **kwargs): template_initial = self.validated_data.pop('template') if 'template' in self.validated_data else None template_items = template_initial['items'] if template_initial else [] template = { "name": 't_' + generate_random_id(), "items": template_items } template_serializer = TemplateSerializer(data=template) self.validated_data.pop('post_mturk') project = models.Project.objects.create(owner=kwargs['owner'], post_mturk=True, amount_due=0, **self.validated_data) if template_serializer.is_valid(): project_template = template_serializer.create(with_defaults=with_defaults, is_review=False, owner=kwargs['owner']) project.template = project_template else: raise ValidationError(template_serializer.errors) project.group_id = project.id if not with_defaults: project.status = models.Project.STATUS_IN_PROGRESS project.published_at = timezone.now() # self.instance = project # if not project.is_paid: # self.pay(self.instance.price * self.instance.repetition) # self.create_task(project.id) project.save() self.create_review(project=project, template_data=template) models.BoomerangLog.objects.create(object_id=project.group_id, min_rating=project.min_rating, rating_updated_at=project.rating_updated_at, reason='DEFAULT') return project @staticmethod def create_review(project, template_data, parent_review_project=None): project_name = 'Peer Review for ' + project.name review_project = models.Project.objects.create(name=project_name, owner=project.owner, parent=project, is_prototype=False, min_rating=1.99, post_mturk=True, timeout=project.timeout, is_review=True, deleted_at=timezone.now()) if parent_review_project is not None: review_project.price = parent_review_project.price template_serializer = TemplateSerializer(data=template_data) if template_serializer.is_valid(): review_template = template_serializer.create(with_defaults=False, is_review=True, owner=project.owner) review_project.template = review_template else: raise ValidationError(template_serializer.errors) review_project.group_id = review_project.id review_project.save() return review_project def update(self, *args, **kwargs): self.instance.name = self.validated_data.get('name', self.instance.name) self.instance.price = self.validated_data.get('price', self.instance.price) review_project = models.Project.objects.filter(parent_id=self.instance.group_id, is_review=True).first() has_review = self.validated_data.get('has_review', review_project.deleted_at is None) self.instance.timeout = self.validated_data.get('timeout', self.instance.timeout) if review_project is not None: review_project.price = self.validated_data.get('review_price', review_project.price) review_project.timeout = self.instance.timeout review_project.deleted_at = None if has_review else timezone.now() review_project.save() self.instance.repetition = self.validated_data.get('repetition', self.instance.repetition) self.instance.deadline = self.validated_data.get('deadline', self.instance.deadline) self.instance.post_mturk = self.validated_data.get('post_mturk', self.instance.post_mturk) self.instance.qualification = self.validated_data.get('qualification', self.instance.qualification) self.instance.save() return self.instance def update_status(self, *args, **kwargs): status = self.initial_data.get('status', self.instance.status) validator = ProjectValidator() validator.set_context(self) validator.__call__(value={'status': status}) self.instance.status = status mturk_update_status.delay({'id': self.instance.id, 'status': status}) self.instance.save() return self.instance @staticmethod def get_age(model): from crowdsourcing.utils import get_relative_time if model.status == models.Project.STATUS_DRAFT: return get_relative_time(model.updated_at) else: return get_relative_time(model.published_at) @staticmethod def get_total_tasks(obj): return obj.tasks.all().count() @staticmethod def get_has_comments(obj): return obj.comments.count() > 0 @staticmethod def get_comments(obj): if obj: comments = [] tasks = obj.tasks.all() for task in tasks: task_comments = task.comments.all() for task_comment in task_comments: comments.append(task_comment) serializer = TaskCommentSerializer(many=True, instance=comments, read_only=True) return serializer.data return [] @staticmethod def has_csv_linkage(items): if items.count() > 0: template_items = items.all() for item in template_items: attribs = item.aux_attributes if 'question' in attribs and 'data_source' in attribs['question'] and \ attribs['question']['data_source'] is not None: return True if 'options' in attribs and attribs['options'] is not None: for option in attribs['options']: if 'data_source' in option and option['data_source'] is not None: return True return False @staticmethod def create_task(project_id): task_data = { "project": project_id, "data": {} } task_serializer = TaskSerializer(data=task_data) if task_serializer.is_valid(): task_serializer.create() else: raise ValidationError(task_serializer.errors) def fork(self, *args, **kwargs): template = self.instance.template template_items = copy.copy(template.items.all()) # batch_files = self.instance.batch_files.all() project = self.instance project.name += ' (copy)' project.status = models.Project.STATUS_DRAFT project.is_prototype = False project.parent_id = self.instance.id template.pk = None template.save() project.template = template review_project = models.Project.objects.filter(parent_id=self.instance.group_id, is_review=True).first() for template_item in template_items: template_item.pk = None template_item.template = template template_item.save() project.id = None project.save() project.group_id = project.id project.save() template = { "name": 't_' + generate_random_id(), "items": [] } self.create_review(project=project, template_data=template, parent_review_project=review_project) return project @staticmethod def create_revision(instance): models.Project.objects.filter(group_id=instance.group_id).update(status=models.Project.STATUS_PAUSED) template = TemplateSerializer.create_revision(instance=instance.template) # batch_files = copy.copy(instance.batch_files.all()) tasks = copy.copy(instance.tasks.all()) mturk_update_status.delay({'id': instance.id, 'status': models.Project.STATUS_PAUSED}) instance.pk = None instance.template = template instance.status = models.Project.STATUS_DRAFT instance.is_prototype = False instance.is_paid = False instance.save() # for f in batch_files: # models.ProjectBatchFile.objects.create(project=instance, batch_file=f) for t in tasks: t.pk = None t.project = instance TaskSerializer.bulk_create(data=tasks) return instance def publish(self, amount_due): self.instance.repetition = self.validated_data.get('repetition', self.instance.repetition) self.instance.published_at = timezone.now() review_project = models.Project.objects.filter(parent_id=self.instance.group_id, is_review=True, deleted_at__isnull=True).first() if review_project is not None and review_project.price is not None: review_project.status = models.Project.STATUS_IN_PROGRESS review_project.name = 'Peer Review for ' + self.instance.name review_project.published_at = timezone.now() review_project.save() status = models.Project.STATUS_IN_PROGRESS if status != self.instance.status \ and status in (models.Project.STATUS_PAUSED, models.Project.STATUS_IN_PROGRESS) and \ self.instance.status in (models.Project.STATUS_PAUSED, models.Project.STATUS_IN_PROGRESS): mturk_update_status.delay({'id': self.instance.id, 'status': status}) self.instance.status = status # TODO rm when mturk is removed if status == models.Project.STATUS_IN_PROGRESS and not self.instance.is_paid: # self.pay(amount_due) self.instance.save() @staticmethod def get_relaunch(obj): """ Not used since we removed csv Args: obj: project instance Returns: """ previous_revision = models.Project.objects.prefetch_related('batch_files').filter(~Q(id=obj.id), group_id=obj.group_id) \ .order_by('-id').first() previous_batch_file = previous_revision.batch_files.first() if previous_revision else None batch_file = obj.batch_files.first() active_workers = models.TaskWorker.objects.active().filter(task__project__group_id=obj.group_id, task__exclude_at__isnull=True, status__in=[models.TaskWorker.STATUS_IN_PROGRESS, models.TaskWorker.STATUS_SUBMITTED, models.TaskWorker.STATUS_RETURNED, models.TaskWorker.STATUS_ACCEPTED] ).count() same_file = ( previous_batch_file is not None and batch_file is not None and previous_batch_file.id == batch_file.id ) different_file = (previous_batch_file is not None and batch_file is None) or \ (previous_batch_file is None and batch_file is not None) if previous_revision is None or active_workers == 0: return { "is_forced": False, "ask_for_relaunch": False, "overlaps": False } elif (previous_batch_file is None and batch_file is None) or same_file: return { "is_forced": False, "ask_for_relaunch": True, "overlaps": True } elif different_file: return { "is_forced": True, "ask_for_relaunch": False, "overlaps": False } elif previous_batch_file.id != batch_file.id: return { "is_forced": False, "ask_for_relaunch": True, "overlaps": True } def pay(self, amount_due, *args, **kwargs): requester_account = models.FinancialAccount.objects.get(owner_id=self.instance.owner_id, type=models.FinancialAccount.TYPE_REQUESTER, is_system=False).id system_account = models.FinancialAccount.objects.get(is_system=True, type=models.FinancialAccount.TYPE_ESCROW).id transaction_data = { 'sender': requester_account, 'recipient': system_account, 'amount': amount_due, 'method': 'daemo', 'sender_type': models.Transaction.TYPE_PROJECT_OWNER, 'reference': 'P#' + str(self.instance.id) } if amount_due < 0: transaction_data['sender'] = system_account transaction_data['recipient'] = requester_account transaction_data['amount'] = abs(amount_due) transaction_serializer = TransactionSerializer(data=transaction_data) if transaction_serializer.is_valid(): if amount_due != 0: transaction_serializer.create() self.instance.is_paid = True self.instance.save() else: raise ValidationError('Error in payment') @staticmethod def get_revisions(obj): return models.Project.objects.active().filter(group_id=obj.group_id).order_by('id').values_list('id', flat=True) def reset_boomerang(self): update_project_boomerang.delay(self.instance.id) @staticmethod def get_hash_id(obj): return to_hash(obj.group_id)