Skip to content
Snippets Groups Projects
Select Git revision
2 results Searching

dataset_reader.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    contentViews.py 7.31 KiB
    import logging
    # Create your views here.
    from typing import Optional, List, Dict
    
    from django.db.models import QuerySet, Count
    from rest_framework import status
    from rest_framework.authentication import TokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.request import Request
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    from ..models import Account, Statement, Hashtag, HashtagTagging
    from ..serializers.contentSerializers import StatementObservationSerializer, StatementSerializer, TrendingHashtagSerializer
    
    logger = logging.getLogger(__name__)
    
    
    class ShowStatement(APIView):
        """
        This view can be used to get an specific statement and all correlated data by the statements id.
        To get information about an statement one must provide an valid token for identification.
        """
        authentication_classes = [TokenAuthentication]
        permission_classes = (IsAuthenticated,)
    
        @staticmethod
        def get(request: Request, *args, **kwargs):
            """
            This method returns all information about an specific statement.
            :param request: Not used.
            :param args: Not used.
            :param kwargs: Additional information to get the id of the requested statement.
            :return:
            """
            statement: Statement = Statement.objects.filter(id=int(kwargs.get("id")))
            serializer: StatementObservationSerializer = StatementObservationSerializer(instance=statement, many=True)
            return Response(status=status.HTTP_200_OK, data=serializer.data)
    
    
    class ShowStatementsWithHashtag(APIView):
        """
        This view is representative for the hashtag view.
        It can be used to get all statements with containing an specific hashtag.
        To get the information one must have an valid token.
        """
        authentication_classes = [TokenAuthentication]
        permission_classes = (IsAuthenticated,)
    
        @staticmethod
        def get(request: Request):
            """
            This method returns all statements containing the given hashtag string.
            If there is no data or if there is no hashtag one get 200.
            If there is data one get data and 200.
            If the request is wrong one get 400.
    
            :param request: Request with the parameter q, which is the string representation of the hashtag.
            :return: 200 if there are statements with the hashtag or if there is no data, 400 if the request is invalid.
            """
            query: str = request.query_params.get('q', None)
            if not query:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            hashtag: Optional[Hashtag] = Hashtag.objects.filter(tag=query).first()
            if not hashtag:
                return Response(status=status.HTTP_200_OK)
            statement: List[Statement] = Statement.objects.filter(tagged=hashtag)
            serializer: StatementSerializer = StatementSerializer(instance=statement, many=True)
            return Response(status=status.HTTP_200_OK, data=serializer.data)
    
    
    class ShowStatementFeed(APIView):
        """
        This view is for querying the feed for an calling account.
        The feed is generated by the accounts the calling account is following.
        To get the feed the calling account must be authenticated.
        """
        authentication_classes = [TokenAuthentication]
        permission_classes = (IsAuthenticated,)
    
        @staticmethod
        def get(request: Request):
            """
            This is for getting the feed.
            :param request: The request containing the token to identify the calling user.
            :return: Feed for the calling user based on the actions of those the calling account follows.
            """
            account: Account = Account.objects.get(user=request.user)
            following: List[Account] = account.get_related_to() + [account]
            feed: QuerySet[Statement] = Statement.objects.filter(author__in=following)
            serializer: StatementSerializer = StatementSerializer(instance=feed, many=True)
            return Response(status=status.HTTP_200_OK, data=serializer.data)
        
        
    class ShowStatementFeedPagination(APIView):
        """
        This view is for querying the feed for an calling account.
        The feed is generated by the accounts the calling account is following.
        To get the feed the calling account must be authenticated.
        """
        authentication_classes = [TokenAuthentication]
        permission_classes = (IsAuthenticated,)
    
        @staticmethod
        def get(request: Request):
            """
            This is for getting the feed with pagination.
            Todo: Add pagination for infinite scrolling.
            :param request: The request containing the token to identify the calling user. The page number. The size number.
            :return: Feed for the calling user based on the actions of those the calling account follows.
            """
            page: int = int(request.query_params.get('page', None))
            size: int = int(request.query_params.get('size', None))
            if not page or not size or page <= 0 or size <= 0:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            
            account: Account = Account.objects.get(user=request.user)
            following: List[Account] = account.get_related_to() + [account]
            feed: QuerySet[Statement] = Statement.objects.filter(author__in=following)
            
            first = (page - 1) * size
            last = first + size
            total: int = feed.count()
            
            if first >= total:
                feed = []
            else:
                if last >= total:
                    last = None
                    feed = feed[first:last]
            
            serializer: StatementSerializer = StatementSerializer(instance=feed, many=True)
            return Response(status=status.HTTP_200_OK, data={"data": serializer.data, "total": total})
    
    
    class ShowTrendingHashtag(APIView):
        """
        This view is for getting the five most trending hashtags.
        The calling user must be authenticated.
        Also the calling user is not included as an participant of the hashtag,
        since those others are for recommendation.
        """
        authentication_classes = [TokenAuthentication]
        permission_classes = (IsAuthenticated,)
    
        @staticmethod
        def get(request: Request):
            """
            This method handles the request for trending hashtags.
            Therefore the tagging of hashtags are counted and turned into an trending hashtag representation.
            The TrendingHashtagSerializer adds all needed information like the count of uses and other participants.
            The calling account is excluded from the participants.
            :param request: Request containing the the token for identification.
            :return: 200 OK with empty or not empty data section. The data section is empty if there are not hashtags.
            """
            hashtags: QuerySet[Dict] = HashtagTagging.objects.values('hashtag')
            hashtags_counted: QuerySet[Dict] = hashtags.annotate(the_count=Count('hashtag')).order_by("-the_count")
            counted: Dict = {item["hashtag"]: item["the_count"] for item in hashtags_counted}
            hashtags: QuerySet[Hashtag] = Hashtag.objects.filter(id__in=counted.keys())
            if not hashtags_counted:
                return Response(status=status.HTTP_200_OK, data=[])
            serializer: TrendingHashtagSerializer = TrendingHashtagSerializer(
                instance=hashtags,
                many=True,
                context={"counted": counted, "calling_user": request.user.id})
            return Response(status=status.HTTP_200_OK, data=serializer.data[:3])