Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring and added "missing" endpoints to the docs #1045

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions crowdsourcing/serializers/qualification.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from rest_framework import serializers

from crowdsourcing import constants
from crowdsourcing.serializers.dynamic import DynamicFieldsModelSerializer
from crowdsourcing.models import Qualification, QualificationItem, WorkerAccessControlEntry, \
RequesterAccessControlGroup
from crowdsourcing.serializers.dynamic import DynamicFieldsModelSerializer
from crowdsourcing.tasks import update_worker_cache


class QualificationSerializer(DynamicFieldsModelSerializer):
class Meta:
model = Qualification
fields = ('id', 'name', 'description')
fields = ('id', 'name', 'created_at', 'updated_at')
read_only_fields = ('created_at', 'updated_at')

def create(self, owner, *args, **kwargs):
return Qualification.objects.create(owner=owner, **self.validated_data)
Expand Down
24 changes: 16 additions & 8 deletions crowdsourcing/viewsets/qualification.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
from django.db import transaction
from rest_framework import status, viewsets
from rest_framework.decorators import list_route
from rest_framework import serializers
from rest_framework import status, viewsets, mixins
from rest_framework.decorators import list_route, detail_route
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import serializers
from crowdsourcing import constants
from crowdsourcing.tasks import update_worker_cache

from crowdsourcing import constants
from crowdsourcing.models import Qualification, QualificationItem, \
WorkerAccessControlEntry, RequesterAccessControlGroup
from crowdsourcing.serializers.qualification import QualificationSerializer, QualificationItemSerializer, \
WorkerACESerializer, RequesterACGSerializer
from crowdsourcing.tasks import update_worker_cache


class QualificationViewSet(viewsets.ModelViewSet):
class QualificationViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
queryset = Qualification.objects.all()
serializer_class = QualificationSerializer
permission_classes = [IsAuthenticated]
Expand All @@ -31,7 +32,14 @@ def create(self, request, *args, **kwargs):
def list(self, request, *args, **kwargs):
queryset = self.queryset.filter(owner=request.user)
serializer = self.serializer_class(instance=queryset, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
return Response(
data={"results": serializer.data, "count": len(serializer.data), "previous": None, "next": None},
status=status.HTTP_200_OK)

@detail_route(methods=['get'])
def items(self, request, *args, **kwargs):
qualification_items = self.get_object().items.all()
return Response(self.item_serializer_class(instance=qualification_items, many=True).data)


class QualificationItemViewSet(viewsets.ModelViewSet):
Expand All @@ -57,7 +65,7 @@ def update(self, request, *args, **kwargs):
raise serializers.ValidationError(detail=serializer.errors)

def list(self, request, *args, **kwargs):
queryset = self.queryset.filter(qualification_id=request.query_params.get('qualification', -1))
queryset = self.queryset.filter(qualification_id=request.query_params.get('qualification_id', -1))
serializer = self.serializer_class(instance=queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)

Expand Down
111 changes: 22 additions & 89 deletions crowdsourcing/viewsets/rating.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,44 @@
from django.contrib.auth.models import User
from django.db import transaction
from django.db.models import Q
from rest_framework import status, viewsets, serializers
from rest_framework import status, viewsets, serializers, mixins
from rest_framework.decorators import list_route
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from crowdsourcing.models import Rating, TaskWorker, Project, RawRatingFeedback, Match
from crowdsourcing.permissions.rating import IsRatingOwner
from crowdsourcing.serializers.project import ProjectSerializer
from crowdsourcing.serializers.rating import RatingSerializer
from crowdsourcing.utils import get_pk
from mturk.tasks import update_worker_boomerang


class WorkerRequesterRatingViewset(viewsets.ModelViewSet):
class RatingViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Rating.objects.all()
serializer_class = RatingSerializer
permission_classes = [IsAuthenticated, IsRatingOwner]

def create(self, request, *args, **kwargs):
wrr_serializer = RatingSerializer(data=request.data)
if wrr_serializer.is_valid():
wrr = wrr_serializer.create(origin=request.user)
wrr_serializer = RatingSerializer(instance=wrr)
if wrr.origin_type == Rating.RATING_REQUESTER:
update_worker_boomerang.delay(wrr.origin_id, wrr.task.project.group_id)
return Response(wrr_serializer.data, status=status.HTTP_201_CREATED)
else:
raise serializers.ValidationError(detail=wrr_serializer.errors)

def update(self, request, *args, **kwargs):
wrr_serializer = RatingSerializer(data=request.data, partial=True)
wrr = self.get_object()
if wrr_serializer.is_valid():
wrr = wrr_serializer.update(wrr, wrr_serializer.validated_data)
wrr_serializer = RatingSerializer(instance=wrr)
if wrr.origin_type == Rating.RATING_REQUESTER:
update_worker_boomerang.delay(wrr.origin_id, wrr.task.project.group_id)
return Response(wrr_serializer.data, status=status.HTTP_200_OK)
worker = request.data.get('target')
target = User.objects.filter(profile__handle=worker).first()
if target is None:
return Response({"message": "User with handle {} not found!".format(worker)},
status=status.HTTP_404_NOT_FOUND)
origin_type = request.data.get('origin_type', Rating.RATING_REQUESTER)
if target.id == request.user.id:
return Response({"message": "Cannot rate self!"}, status=status.HTTP_400_BAD_REQUEST)
if origin_type == 'worker':
origin_type = Rating.RATING_WORKER
elif origin_type == 'requester':
origin_type = Rating.RATING_REQUESTER

serializer = RatingSerializer(
data={"origin_type": origin_type, "target": target.id, "weight": request.data.get('weight')})
if serializer.is_valid():
rating = serializer.create(origin=request.user)
return Response({"id": rating.id}, status=status.HTTP_201_CREATED)
else:
raise serializers.ValidationError(detail=wrr_serializer.errors)
raise serializers.ValidationError(detail=serializer.errors)

@staticmethod
def get_true_skill_ratings(match_group_id):
Expand Down Expand Up @@ -141,7 +140,6 @@ def list_by_target(self, request, *args, **kwargs):
@list_route(methods=['post'], url_path='by-project')
def by_project(self, request, *args, **kwargs):
project_id = request.data.get('project')

origin_type = request.data.get('origin_type', Rating.RATING_REQUESTER)
target = request.data.get('target')
weight = request.data.get('weight')
Expand All @@ -164,68 +162,3 @@ def by_project(self, request, *args, **kwargs):
Rating.objects.filter(target_id=target, origin_id=origin, task__in=tasks, origin_type=origin_type).delete()
Rating.objects.bulk_create(rating_objects)
return Response({"message": "Ratings saved successfully"})


class RatingViewset(viewsets.ModelViewSet):
queryset = Project.objects.filter(deleted_at__isnull=True)
serializer_class = ProjectSerializer
permission_classes = [IsAuthenticated]

@list_route(methods=['GET'])
def workers_ratings_by_project(self, request, **kwargs):
project_id = request.query_params.get('project', -1)
# noinspection SqlResolve
data = TaskWorker.objects.raw(
'''
SELECT
r.id id,
2 origin_type,
r.weight weight,
u.id target,
u.username username,
p.owner_id origin,
COUNT(tw.task_id) AS "task_count"
FROM crowdsourcing_taskworker tw
INNER JOIN crowdsourcing_task t ON (tw.task_id = t.id)
INNER JOIN crowdsourcing_project p
ON (t.project_id = p.id)
INNER JOIN auth_user u
ON (u.id = p.owner_id)
LEFT OUTER JOIN crowdsourcing_rating r
ON (u.id = r.target_id)
WHERE (tw.status IN (3, 4, 5) AND o.id = %s)
GROUP BY
r.weight,
p.owner_id,
r.id
ORDER BY "task_count" DESC, username;
''', params=[project_id]
)

serializer = RatingSerializer(data, many=True, context={'request': request})
response_data = serializer.data
return Response(data=response_data, status=status.HTTP_200_OK)

@list_route(methods=['GET'])
def requesters_ratings(self, request, **kwargs):
data = TaskWorker.objects.raw(
'''
SELECT
DISTINCT
(u.username) username,
1 origin_type,
%(worker)s origin,
r.id id,
u.id target,
r.weight weight
FROM crowdsourcing_taskworker tw
INNER JOIN crowdsourcing_task t ON tw.task_id=t.id
INNER JOIN crowdsourcing_project p ON t.project_id=p.id
INNER JOIN auth_user u ON p.owner_id=u.id
LEFT OUTER JOIN crowdsourcing_rating r ON u.id=r.target_id
WHERE tw.status IN (3, 4, 5) AND tw.worker_id=%(worker)s;
''', params={'worker': request.user.id}
)
serializer = RatingSerializer(data, many=True, context={'request': request})
response_data = serializer.data
return Response(data=response_data, status=status.HTTP_200_OK)
35 changes: 18 additions & 17 deletions csp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@

from crowdsourcing import views
from crowdsourcing.viewsets.file import FileViewSet
from crowdsourcing.viewsets.message import ConversationViewSet, MessageViewSet, RedisMessageViewSet, \
ConversationRecipientViewSet
from crowdsourcing.viewsets.message import RedisMessageViewSet
from crowdsourcing.viewsets.payment import ChargeViewSet, TransferViewSet
from crowdsourcing.viewsets.project import *
from crowdsourcing.viewsets.qualification import QualificationViewSet, RequesterACGViewSet, WorkerACEViewSet, \
QualificationItemViewSet
from crowdsourcing.viewsets.rating import WorkerRequesterRatingViewset, RatingViewset
from crowdsourcing.viewsets.rating import RatingViewSet
from crowdsourcing.viewsets.task import TaskViewSet, TaskWorkerResultViewSet, TaskWorkerViewSet, \
ExternalSubmit, ReturnFeedbackViewSet
from crowdsourcing.viewsets.template import TemplateViewSet, TemplateItemViewSet, TemplateItemPropertiesViewSet
from crowdsourcing.viewsets.template import TemplateViewSet, TemplateItemViewSet
from crowdsourcing.viewsets.user import UserViewSet, UserProfileViewSet, UserPreferencesViewSet, CountryViewSet, \
CityViewSet
from mturk import views as mturk_views
Expand All @@ -27,33 +26,35 @@
router.register(r'assignments', TaskWorkerViewSet)
router.register(r'templates', TemplateViewSet)
router.register(r'template-items', TemplateItemViewSet)
router.register(r'qualification-items', QualificationItemViewSet)
router.register(r'payments', ChargeViewSet)
router.register(r'transfers', TransferViewSet)
router.register(r'qualifications', QualificationViewSet)
router.register(r'files', FileViewSet)

router.register(r'profile', UserProfileViewSet)
router.register(r'user', UserViewSet)
router.register(r'preferences', UserPreferencesViewSet)
router.register(r'worker-requester-rating', WorkerRequesterRatingViewset)
router.register(r'rating', RatingViewset)
router.register(r'ratings', RatingViewSet)

router.register(r'country', CountryViewSet)
router.register(r'city', CityViewSet)

router.register(r'task-worker', TaskWorkerViewSet)
router.register(r'task-worker-result', TaskWorkerResultViewSet)
router.register(r'template', TemplateViewSet)
router.register(r'template-item', TemplateItemViewSet)
router.register(r'template-item-properties', TemplateItemPropertiesViewSet)
# router.register(r'template', TemplateViewSet)
# router.register(r'template-item', TemplateItemViewSet)
# router.register(r'template-item-properties', TemplateItemPropertiesViewSet)
router.register(r'return-feedback', ReturnFeedbackViewSet)
router.register(r'conversation', ConversationViewSet)
router.register(r'conversation-recipients', ConversationRecipientViewSet)
router.register(r'message', MessageViewSet)
# router.register(r'conversation', ConversationViewSet)
# router.register(r'conversation-recipients', ConversationRecipientViewSet)
# router.register(r'message', MessageViewSet)
router.register(r'inbox', RedisMessageViewSet, base_name='redis-message')
router.register(r'file', FileViewSet)
router.register(r'qualification', QualificationViewSet)


router.register(r'requester-access-group', RequesterACGViewSet)
router.register(r'worker-access-entry', WorkerACEViewSet)
router.register(r'qualification-item', QualificationItemViewSet)
router.register(r'charges', ChargeViewSet)
router.register(r'transfers', TransferViewSet)


mturk_router = SimpleRouter(trailing_slash=False)
mturk_router.register(r'mturk', MTurkAssignmentViewSet)
Expand Down
53 changes: 53 additions & 0 deletions static/js/crowdsource.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,30 @@
templateUrl: '/static/templates/docs/template-items.html'
};

var docsPayments = {
controller: 'DocsController',
controllerAs: 'docs',
templateUrl: '/static/templates/docs/payments.html'
};

var docsRatings = {
controller: 'DocsController',
controllerAs: 'docs',
templateUrl: '/static/templates/docs/ratings.html'
};

var docsQualifications = {
controller: 'DocsController',
controllerAs: 'docs',
templateUrl: '/static/templates/docs/qualifications.html'
};

var docsQualificationItems = {
controller: 'DocsController',
controllerAs: 'docs',
templateUrl: '/static/templates/docs/qualification-items.html'
};

var docsOAuth2 = {
controller: 'DocsController',
controllerAs: 'docs',
Expand Down Expand Up @@ -466,6 +490,35 @@
},
authenticate: false
})
.state('docs.payments', {
url: '/payments',
views: {
'content': docsPayments
},
authenticate: false
})
.state('docs.ratings', {
url: '/ratings',
views: {
'content': docsRatings
},
authenticate: false
})

.state('docs.qualifications', {
url: '/qualifications',
views: {
'content': docsQualifications
},
authenticate: false
})
.state('docs.qualification_items', {
url: '/qualification-items',
views: {
'content': docsQualificationItems
},
authenticate: false
})
.state('docs.oauth2', {
url: '/oauth2-authentication',
views: {
Expand Down
2 changes: 1 addition & 1 deletion static/js/payment/services/payment.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

function createCharge(data) {
var settings = {
url: '/api/charges/',
url: '/api/payments/',
method: 'POST',
data: data
};
Expand Down
2 changes: 1 addition & 1 deletion static/js/project/controllers/project-review.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
}

function downloadResults() {
window.open('api/file/download-results/?project_id=' + self.resolvedData.id, '_self', '');
window.open('v1/files/download-results/?project_id=' + self.resolvedData.id, '_self', '');
}

function returnTask(taskWorker, worker_alias, e) {
Expand Down
2 changes: 1 addition & 1 deletion static/js/project/controllers/project.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@
var file = files[i];

Upload.upload({
url: '/api/file/',
url: '/api/files/',
//fields: {'username': $scope.username},
file: file
}).progress(function (evt) {
Expand Down
Loading