class BaseExperienceViewSet(object):

    queryset = Experience.objects.all()
    pagination_class = pagination.factory('PageNumberPagination')
    permission_classes = [
        permissions.C(permissions.IsAuthenticatedOrReadOnly)
        & permissions.check_owner('author', ('PATCH', 'PUT', 'DELETE'))
    ]

    def get_serializer_class(self):
        return DetailExperienceSerializer if self.action == 'retrieve' else ShortExperienceSerializer
Exemplo n.º 2
0
class UserRelationViewSet(mixins.ListModelMixin, BaseUserViewSetMixin):

    queryset = User.objects.all()
    serializer_class = UserSerializer
    pagination_class = pagination.factory('PageNumberPagination', page_size=20)

    allowed_actions = {'followers': 'followers', 'following': 'following'}

    def get_queryset(self):
        user = self.get_user_object()

        try:
            rel_field = getattr(user, self.allowed_actions[self.action])
        except KeyError:
            raise NotFound

        if self.request.user.is_authenticated():
            rel_field = rel_field.annotate(followed=models.ExpressionWrapper(
                models.Count(
                    models.Subquery(
                        User.following.through.objects.filter(
                            to_user_id=self.request.user.id,
                            from_user_id=models.OuterRef('id')).values('id'))),
                output_field=models.BooleanField()))
        else:
            rel_field = rel_field.annotate(followed=models.Value(
                False, output_field=models.BooleanField()))

        return rel_field.order_by('id')

    # for view_name in allowed_actions:
    #     locals()[view_name] = decorators.list_route(methods=['GET'])(
    #         lambda self, *args, **kwargs: self.list(*args, **kwargs)
    #     )

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @decorators.list_route(methods=['GET'])
    def followers(self, *args, **kwargs):
        return self.list(*args, **kwargs)

    @decorators.list_route(methods=['GET'])
    def following(self, *args, **kwargs):
        return self.list(*args, **kwargs)
Exemplo n.º 3
0
class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin,
                  mixins.UpdateModelMixin, BaseUserViewSetMixin):

    lookup_value_regex = re_user_lookup_value
    lookup_url_kwarg = 'user_pk'

    queryset = User.objects.all().order_by('id')
    serializer_class = UserSerializer
    pagination_class = pagination.factory('PageNumberPagination', page_size=20)
    permission_classes = [p.C(p.IsAuthenticatedOrReadOnly) & p.check_owner()]
    filter_fields = ('username', )

    def get_user_queryset(self):

        qs = super(UserViewSet, self).get_user_queryset()

        if self.request.user.is_authenticated():
            qs = qs.annotate(followed=models.ExpressionWrapper(
                models.Count(
                    models.Subquery(
                        User.following.through.objects.filter(
                            to_user_id=self.request.user.id,
                            from_user_id=models.OuterRef('id')).values('id'))),
                output_field=models.BooleanField()))
        else:
            qs = qs.annotate(followed=models.Value(
                False, output_field=models.BooleanField()))

        return qs

    def get_object(self):
        obj = self.get_user_object()
        self.check_object_permissions(self.request, obj)
        return obj

    @decorators.detail_route(['POST'])
    def follow(self, request, *args, **kwargs):
        request.user.follow(self.get_object())

        return Response('OK')

    @decorators.detail_route(['POST'])
    def unfollow(self, request, *args, **kwargs):
        request.user.unfollow(self.get_object())

        return Response('OK')

    @decorators.detail_route(['GET'])
    def stat(self, request, *args, **kwargs):

        user = self.get_object()
        data = UserSerializer(user).data
        return Response(data)
Exemplo n.º 4
0
class PostViewSet(viewsets.ModelViewSet):
    serializer_class = PostSerializer
    pagination_class = pagination.factory('PageNumberPagination', page_size=10)
    permission_classes = [permissions.C(permissions.IsAuthenticatedOrReadOnly) &
                          permissions.check_owner('author', ('PATCH', 'PUT', 'DELETE'))]

    # override this function to provide "request" as "None"
    def get_serializer_context(self):
        """
        Extra context provided to the serializer class.
        """
        return {
            'request': None,
            'format': self.format_kwarg,
            'view': self
        }

    def get_queryset(self):
        author = self.request.query_params.get('author', None)

        if author is not None:
            queryset = Post.objects.filter(author__username=author)
            if self.request.user.username != author:
                queryset = queryset.filter(is_visible=True)
        else:
            queryset = Post.objects.filter(is_visible=True)

        if 'experience_id' in self.kwargs:
            queryset = queryset.filter(experience__id=self.kwargs['experience_id'])

        return queryset

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

    def create(self, request, *args, **kwargs):
        from biohub.core.conf import settings as biohub_settings
        from datetime import timedelta
        from django.utils.timezone import now

        user = self.request.user
        if Post.objects.filter(
            author=user,
            pub_time__gte=now() - timedelta(seconds=biohub_settings.THROTTLE['post'])
        ).exists():
            raise exceptions.Throttled()

        return super(PostViewSet, self).create(request, *args, **kwargs)
Exemplo n.º 5
0
class ActivityViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
    serializer_class = ActivitySerializer
    pagination_class = pagination.factory('PageNumberPagination', page_size=10)

    def get_queryset(self):

        queryset = Activity.objects.all()

        if self.action == 'timeline':
            user = self.request.user
            queryset = queryset.filter(
                models.Q(user__in=models.Subquery(
                    user.following.through.objects.filter(
                        to_user_id=user.id).values('from_user_id')))
                | (models.Q(brick_name__in=models.Subquery(
                    user.bricks_watching.through.objects.filter(
                        user=user.id).values('brick')))
                   & ~models.Q(user=user.id)))

        user = self.request.query_params.get('user', None)
        type = self.request.query_params.get('type', None)

        if user is not None:
            queryset = queryset.filter(user__username=user)
        if type is not None:
            queryset = queryset.filter(type__in=type.split(','))

        queryset = queryset.annotate(score=models.Case(models.When(
            type='Watch',
            then=models.Subquery(
                BiobrickMeta.objects.filter(part_name=models.OuterRef(
                    'brick_name')).values('rate_score'))),
                                                       default=None))

        return queryset.order_by('-acttime')

    @decorators.list_route(methods=['GET'],
                           permission_classes=[permissions.IsAuthenticated])
    def timeline(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
Exemplo n.º 6
0
class BaseBrickViewSet(object):

    pagination_class = pagination.factory('PageNumberPagination')
    queryset = Biobrick.objects.all()

    @property
    def detail(self):
        if self.action == 'list':
            return False
        elif self.action == 'retrieve':
            return True
        else:
            return 'detail' in self.request.query_params

    def get_serializer_class(self):
        ret = BiobrickSerializer

        if self.action == 'list':
            return ret.list_creator()

        if not self.detail:
            ret = ret.short_creator()

        return ret
Exemplo n.º 7
0
class NoticeViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin,
                    viewsets.GenericViewSet, PassUserToSerializer):

    serializer_class = NoticeSerializer
    pagination_class = pagination.factory('PageNumberPagination')
    permission_classes = [
        p.C(p.IsAuthenticated) & p.check_owner('user', ('GET', ))
    ]
    filter_fields = ('has_read', 'category')

    def get_queryset(self):
        qs = Notice.objects.user_notices(self.request.user)

        id_list = self.request.query_params.get('ids', None)
        if id_list is not None:
            qs = qs.filter(id__in=id_list.split(','))

        return qs.order_by('-created')

    @decorators.list_route(['GET'])
    def mark_all_as_read(self, *args, **kwargs):
        self.get_queryset().mark_read()

        return Response('OK')

    @decorators.detail_route(['GET'])
    def mark_read(self, *args, **kwargs):
        self.get_object().mark_read()

        return Response('OK')

    @decorators.list_route(['GET'])
    def categories(self, *args, **kwargs):
        return Response(self.get_queryset().categories())

    @decorators.list_route(['GET'])
    def stats(self, *args, **kwargs):
        return Response(self.get_queryset().stats())

    @decorators.list_route(['GET'])
    def feeds(self, request, *args, **kwargs):
        """
        News from the users you're following.
        """
        qs = self.get_queryset().filter(category__startswith='Following').all()
        page = self.paginate_queryset(qs)
        qs.mark_read()  # See issue 40
        return self.get_paginated_response(
            NoticeSerializer(page, many=True).data)

    @decorators.list_route(['GET'])
    def has_new_feeds(self, request, *args, **kwargs):
        """
        Check if there is a new feed.
        """
        n_feeds = self.get_queryset().filter(category__startswith='Following',
                                             has_read=False).count()
        return Response({'count': n_feeds})

    @decorators.list_route(['GET'])
    def my(self, request, *args, **kwargs):
        """
        Notifications sent specifically to the current user.
        """
        qs = self.get_queryset().filter(~Q(
            category__startswith='Following')).all()
        page = self.paginate_queryset(qs)
        qs.mark_read()  # See issue 40
        return self.get_paginated_response(
            NoticeSerializer(page, many=True).data)

    @decorators.list_route(['GET'])
    def has_new_notifications(self, request, *args, **kwargs):
        """
        Check if there is a new notification.
        """
        qs = self.get_queryset().filter(~Q(category__startswith='Following'),
                                        has_read=False)
        notice = qs.first()
        return Response({
            'count': qs.count(),
            'latest': NoticeSerializer(notice).data
        })