def get_queryset(self, pk=None): """Only allow accessing own ratings.""" user_preferences = get_user_preferences(self.request) queryset = VideoRating.objects.filter(user=user_preferences) # computing score inside the database queryset = queryset.annotate( score=get_score_annotation( get_user_preferences( self.request).features_as_vector_centered)) return queryset
def perform_create(self, serializer): # setting the user automatically with transaction.atomic(): try: serializer.save(user=get_user_preferences(self.request)) except IntegrityError: raise serializers.ValidationError({'detail': "Rating exists already"}) except Exception as e: logging.error(e)
def disagreements(self, request): """Get disagreements in Expert Ratings.""" data = disagreements_for_user( get_user_preferences( self.request)) return Response({'count': data['count'], 'next': None, 'previous': None, 'results': DisagreementSerializer(data['results'], many=True).data})
def set_mark(self, request, pk=None): """Mark a comment with a flag (like/dislike/red flag).""" fields = VideoCommentMarker.MARKER_CHOICES_1 if request.query_params.get('marker', "") not in fields: return Response( status=400, data={'explanation': f"Marker must be one of {fields}"}) if request.query_params.get("action", "") not in self.marker_actions: return Response(status=400, data={ 'explanation': f"Action must be one of {self.marker_actions}" }) f = request.query_params['marker'] action_ = request.query_params['action'] f0 = VideoCommentMarker.MARKER_CHOICES_1to0[f] if not self.get_queryset().filter(id=pk).count(): return Response(status=404) c = self.get_object() marker_user = get_user_preferences(request) kwargs = dict(comment=c, which=f0, user=marker_user) if action_ == "delete" and not VideoCommentMarker.objects.filter( **kwargs).count(): return Response( status=422, data={'explanation': "Cannot delete, marker does not exist"}) if action_ == "add" and VideoCommentMarker.objects.filter( **kwargs).count(): return Response( status=422, data={'explanation': "Cannot add, marker already exists"}) if action_ == "add": VideoCommentMarker.objects.create(**kwargs).save() elif action_ == "delete": VideoCommentMarker.objects.filter(**kwargs).delete() elif action_ == "toggle": n_now = VideoCommentMarker.objects.filter(**kwargs).count() if n_now: VideoCommentMarker.objects.filter(**kwargs).delete() else: VideoCommentMarker.objects.create(**kwargs).save() return Response(self.get_serializer(c, many=False).data, status=201)
def video_rating_statistics(self, request): """Get statistical data on video ratings.""" qs = VideoRating.objects.all() # filtering according to the query parameters qs = self.filter_queryset(qs) # annotate: total score given the preferences vector = get_user_preferences(self.request).features_as_vector_centered vector = update_preferences_vector_from_request(vector, self.request.query_params) qs = qs.annotate(score=get_score_annotation(vector)) # annotate: public/private rating qs = VideoRatingPrivacy._annotate_privacy( qs, prefix='video__videoratingprivacy', field_user=F('user'), default_value=None, annotate_bool=True, annotate_n=False) # either public, or myself qs = qs.annotate(_is_public_or_myself=Case( When(_is_public=True, then=Value(True)), When(user__user__username=request.user.username, then=Value(True)), default=Value(False), output_field=BooleanField(), )) # total number of pairwise comparisons by this video by this user qs = qs.annotate(n_cmp_1=Count('video__expertrating_video_1', distinct=True, filter=Q(video__expertrating_video_1__user=F('user')))) qs = qs.annotate(n_cmp_2=Count('video__expertrating_video_2', distinct=True, filter=Q(video__expertrating_video_2__user=F('user')))) qs = qs.annotate(n_comparisons=F('n_cmp_1') + F('n_cmp_2')) # annotate: for public ones, give the username, for the rest, give None qs = qs.annotate(public_username=Case( When(_is_public_or_myself=True, then=F('user__user__username')), default=Value(None), output_field=CharField())) # deterministic ordering qs = qs.order_by('pk') page = self.paginate_queryset(qs) if page is not None: serializer = VideoRatingsStatisticsSerializerV2(page, many=True) return self.get_paginated_response(serializer.data) serializer = VideoRatingsStatisticsSerializerV2(qs, many=True) return Response(serializer.data)
def inconsistencies(self, request): """Get inconsistencies in Expert Ratings.""" try: data = inconsistencies_3_for_queryset( get_user_preferences( self.request), queryset=self.get_queryset()) return Response({'count': len(data), 'next': None, 'previous': None, 'results': InconsistenciesSerializer(data, many=True).data}) except Exception: return error_response(GenericErrorSerializer)
def get_features_from_request(self): """Get preferences features from request, either from the user, or from attributes.""" # by default, set to zeros vector = np.zeros(len(VIDEO_FIELDS)) # trying to fill data from the user try: user_prefs = get_user_preferences(self.request) vector = user_prefs.features_as_vector_centered except UserPreferences.DoesNotExist: pass vector = update_preferences_vector_from_request(vector, self.request.query_params) return vector
def get_by_video_ids(self, request): """Get rating by video IDs.""" user = get_user_preferences(request) v1 = request.query_params.get("video_left", "") v2 = request.query_params.get("video_right", "") r12 = get_object_or_None(ExpertRating, user=user, video_1__video_id=v1, video_2__video_id=v2) r21 = get_object_or_None(ExpertRating, user=user, video_1__video_id=v2, video_2__video_id=v1) if not any([r12, r21]): raise ExpertRating.DoesNotExist("Expert Rating not found") r = r12 if r12 else r21 reverse = False if r12 else True return r, reverse
def perform_update(self, serializer): serializer.save(user=get_user_preferences(self.request))
def get_queryset(self, pk=None): """All videos except for null ones.""" queryset = ExpertRating.objects.all() return queryset.filter(user=get_user_preferences(self.request))