<commit_before># Roundware Server is released under the GNU Affero General Public License v3.
# See COPYRIGHT.txt, AUTHORS.txt, and LICENSE.txt in the project root directory.

# The Django REST Framework Views for the V2 API.
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.http import Http404
from roundware.rw.models import (Asset, Event, Envelope, ListeningHistoryItem, Project,
                                 Session, Tag, UserProfile)
from roundware.api2 import serializers
from roundware.api2.filters import EventFilterSet, AssetFilterSet, ListeningHistoryItemFilterSet, TagFilterSet
from roundware.lib.api import (get_project_tags, modify_stream, move_listener, heartbeat,
                               skip_ahead, add_asset_to_envelope, get_current_streaming_asset,
                               save_asset_from_request, vote_asset,
                               vote_count_by_asset, log_event)
from rest_framework import viewsets, status
from rest_framework.permissions import IsAuthenticated, DjangoObjectPermissions
from rest_framework.response import Response
from rest_framework.exceptions import ParseError
from rest_framework.authtoken.models import Token
from rest_framework.decorators import detail_route
import logging

logger = logging.getLogger(__name__)


# Note: Keep this stuff in alphabetical order!


class AssetViewSet(viewsets.ViewSet):
    """
    API V2: api/2/assets/
            api/2/assets/:asset_id/
    """

    # TODO: Implement DjangoObjectPermissions
    queryset = Asset.objects.all()
    permission_classes = (IsAuthenticated, DjangoObjectPermissions)

    def retrieve(self, request, pk=None):
        """
        GET api/2/assets/:id/ - Get asset by id
        """
        try:
            asset = Asset.objects.get(pk=pk)
        except Asset.DoesNotExist:
            raise Http404("Asset not found")
        serializer = serializers.AssetSerializer(asset)
        return Response(serializer.data)

    def create(self, request):
        """
        POST api/2/assets/ - Create a new asset
        """
        if "session_id" not in request.data:
            raise ParseError("session_id required")

        try:
            session_id = int(request.data["session_id"])
            session = Session.objects.get(pk=session_id)
        except Session.DoesNotExist:
            raise Http404("Session not found")

        if "asset_id" not in request.data and "file" not in request.data:
            raise ParseError("Must supply either asset_id or file")

        asset = None
        if "asset_id" in request.data:
            try:
                asset_id = int(request.data["asset_id"])
                asset = Asset.objects.get(pk=asset_id)
            except ValueError, Asset.DoesNotExist:
                raise Http404("Asset with id %s not found" % request.data["asset_id"])
        asset = save_asset_from_request(request, session, asset)
        serializer = serializers.AssetSerializer(asset)
        return Response(serializer.data)

    def list(self, request):
        """
        GET api/2/assets/ - retrieve list of assets filtered by parameters
        """
        assets = AssetFilterSet(request.query_params)
        serializer = serializers.AssetSerializer(assets, many=True)
        return Response(serializer.data)

    @detail_route(methods=['post', 'get'])
    def votes(self, request, pk=None):
        if request.method == "POST":
            vote_op = vote_asset(request, asset_id=pk)
            vote = vote_op["vote"]
            serializer = serializers.VoteSerializer(vote)
            return Response(serializer.data)
        else:
            count = vote_count_by_asset(pk)
            return Response(count)


class EventViewSet(viewsets.ViewSet):
    """
    API V2: api/2/events/
            api/2/events/:event_id/
    """

    # TODO: Implement ViewCreate permission.
    queryset = Event.objects.all()
    permission_classes = (IsAuthenticated,)

    def list(self, request):
        """
        GET api/2/events/ - Provides list of events filtered by parameters
        """
        events = EventFilterSet(request.query_params)
        serializer = serializers.EventSerializer(events, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        """
        GET api/2/events/:event_id/ - Get event by id
        """
        try:
            event = Event.objects.get(pk=pk)
        except Event.DoesNotExist:
            raise Http404("Event not found")
        serializer = serializers.EventSerializer(event)
        return Response(serializer.data)

    def create(self, request):
        """
        POST api/2/events/ - Create a new event
        """
        if 'session_id' not in request.data:
            raise ParseError("a session_id is required for this operation")
        if 'event_type' not in request.data:
            raise ParseError("an event_type is required for this operation")
        try:
            e = log_event(request.data['event_type'], request.data['session_id'], request.data)
        except Exception as e:
            raise ParseError(str(e))
        serializer = serializers.EventSerializer(e)
        return Response(serializer.data)


class EnvelopeViewSet(viewsets.ViewSet):
    """
    API V2: api/2/envelopes/
            api/2/envelopes/:envelope_id/
    """
    queryset = Envelope.objects.all()

    def create(self, request):
        """
        POST api/2/envelopes/ - Creates a new envelope based on passed session_id
        """
        serializer = serializers.EnvelopeSerializer(data=request.data)
        if serializer.is_valid():
            envelope = serializer.save()
            return Response({"envelope_id": envelope.pk})
        else:
            return Response(serializer.errors)

    def partial_update(self, request, pk=None):
        """
        PATCH api/2/envelopes/:id/ - Adds an asset to the envelope
        """
        if "asset_id" in request.data or "file" in request.FILES:
            try:
                result = add_asset_to_envelope(request, envelope_id=pk)
            except Exception as e:
                return Response({"detail": str(e)}, status.HTTP_400_BAD_REQUEST)
            serializer = serializers.AssetSerializer(result["asset"])
            return Response(serializer.data)
        else:
            raise ParseError("asset_id or file required")


class ListenEventViewSet(viewsets.ViewSet):
    """
    API V2: api/2/listenevents/
            api/2/listenevents/:id/
    """

    # TODO: Rename ListeningHistoryItem model to ListenEvent.<commit_msg>Preserve alpha ordering of class names<commit_after># Roundware Server is released under the GNU Affero General Public License v3.
# See COPYRIGHT.txt, AUTHORS.txt, and LICENSE.txt in the project root directory.

# The Django REST Framework Views for the V2 API.
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from django.http import Http404
from roundware.rw.models import (Asset, Event, Envelope, ListeningHistoryItem, Project,
                                 Session, Tag, UserProfile)
from roundware.api2 import serializers
from roundware.api2.filters import EventFilterSet, AssetFilterSet, ListeningHistoryItemFilterSet, TagFilterSet
from roundware.lib.api import (get_project_tags, modify_stream, move_listener, heartbeat,
                               skip_ahead, add_asset_to_envelope, get_current_streaming_asset,
                               save_asset_from_request, vote_asset,
                               vote_count_by_asset, log_event)
from rest_framework import viewsets, status
from rest_framework.permissions import IsAuthenticated, DjangoObjectPermissions
from rest_framework.response import Response
from rest_framework.exceptions import ParseError
from rest_framework.authtoken.models import Token
from rest_framework.decorators import detail_route
import logging

logger = logging.getLogger(__name__)


# Note: Keep this stuff in alphabetical order!


class AssetViewSet(viewsets.ViewSet):
    """
    API V2: api/2/assets/
            api/2/assets/:asset_id/
    """

    # TODO: Implement DjangoObjectPermissions
    queryset = Asset.objects.all()
    permission_classes = (IsAuthenticated, DjangoObjectPermissions)

    def retrieve(self, request, pk=None):
        """
        GET api/2/assets/:id/ - Get asset by id
        """
        try:
            asset = Asset.objects.get(pk=pk)
        except Asset.DoesNotExist:
            raise Http404("Asset not found")
        serializer = serializers.AssetSerializer(asset)
        return Response(serializer.data)

    def create(self, request):
        """
        POST api/2/assets/ - Create a new asset
        """
        if "session_id" not in request.data:
            raise ParseError("session_id required")

        try:
            session_id = int(request.data["session_id"])
            session = Session.objects.get(pk=session_id)
        except Session.DoesNotExist:
            raise Http404("Session not found")

        if "asset_id" not in request.data and "file" not in request.data:
            raise ParseError("Must supply either asset_id or file")

        asset = None
        if "asset_id" in request.data:
            try:
                asset_id = int(request.data["asset_id"])
                asset = Asset.objects.get(pk=asset_id)
            except ValueError, Asset.DoesNotExist:
                raise Http404("Asset with id %s not found" % request.data["asset_id"])
        asset = save_asset_from_request(request, session, asset)
        serializer = serializers.AssetSerializer(asset)
        return Response(serializer.data)

    def list(self, request):
        """
        GET api/2/assets/ - retrieve list of assets filtered by parameters
        """
        assets = AssetFilterSet(request.query_params)
        serializer = serializers.AssetSerializer(assets, many=True)
        return Response(serializer.data)

    @detail_route(methods=['post', 'get'])
    def votes(self, request, pk=None):
        if request.method == "POST":
            vote_op = vote_asset(request, asset_id=pk)
            vote = vote_op["vote"]
            serializer = serializers.VoteSerializer(vote)
            return Response(serializer.data)
        else:
            count = vote_count_by_asset(pk)
            return Response(count)


class EnvelopeViewSet(viewsets.ViewSet):
    """
    API V2: api/2/envelopes/
            api/2/envelopes/:envelope_id/
    """
    queryset = Envelope.objects.all()

    def create(self, request):
        """
        POST api/2/envelopes/ - Creates a new envelope based on passed session_id
        """
        serializer = serializers.EnvelopeSerializer(data=request.data)
        if serializer.is_valid():
            envelope = serializer.save()
            return Response({"envelope_id": envelope.pk})
        else:
            return Response(serializer.errors)

    def partial_update(self, request, pk=None):
        """
        PATCH api/2/envelopes/:id/ - Adds an asset to the envelope
        """
        if "asset_id" in request.data or "file" in request.FILES:
            try:
                result = add_asset_to_envelope(request, envelope_id=pk)
            except Exception as e:
                return Response({"detail": str(e)}, status.HTTP_400_BAD_REQUEST)
            serializer = serializers.AssetSerializer(result["asset"])
            return Response(serializer.data)
        else:
            raise ParseError("asset_id or file required")


class EventViewSet(viewsets.ViewSet):
    """
    API V2: api/2/events/
            api/2/events/:event_id/
    """

    # TODO: Implement ViewCreate permission.
    queryset = Event.objects.all()
    permission_classes = (IsAuthenticated,)

    def list(self, request):
        """
        GET api/2/events/ - Provides list of events filtered by parameters
        """
        events = EventFilterSet(request.query_params)
        serializer = serializers.EventSerializer(events, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        """
        GET api/2/events/:event_id/ - Get event by id
        """
        try:
            event = Event.objects.get(pk=pk)
        except Event.DoesNotExist:
            raise Http404("Event not found")
        serializer = serializers.EventSerializer(event)
        return Response(serializer.data)

    def create(self, request):
        """
        POST api/2/events/ - Create a new event
        """
        if 'session_id' not in request.data:
            raise ParseError("a session_id is required for this operation")
        if 'event_type' not in request.data:
            raise ParseError("an event_type is required for this operation")
        try:
            e = log_event(request.data['event_type'], request.data['session_id'], request.data)
        except Exception as e:
            raise ParseError(str(e))
        serializer = serializers.EventSerializer(e)
        return Response(serializer.data)


class ListenEventViewSet(viewsets.ViewSet):
    """
    API V2: api/2/listenevents/
            api/2/listenevents/:id/
    """

    # TODO: Rename ListeningHistoryItem model to ListenEvent.
{'fraction_non_alphanumeric': 0.09072535369413878, 'fraction_numerical': 0.0067370312149112955, 'mean_word_length': 2.4755463059313216, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4634583', 'n_tokens_mistral': 3722, 'n_tokens_neox': 3621, 'n_words': 940}