<gh_stars>0

from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, JsonResponse
from django.template import loader
from django.core.paginator import Paginator, EmptyPage
from django.core import serializers
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Case, When, IntegerField, OuterRef, Subquery
from django.contrib.gis.db.models.functions import Distance
from django.template.loader import render_to_string
from rest_framework import viewsets
from rest_framework import permissions, authentication
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework import mixins
from rest_framework import generics
from rest_auth.registration.views import SocialLoginView
# from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from users.serializers import PetitionSerializer, ResponsePetitionSerializer, PlaceSerializer, ProviderSerializer, OfferSerializer, ApplauseSerializer, FollowingSerializer, FollowingPlaceSerializer, FollowingProviderSerializer
from users.models import Petition, ResponsePetition, Provider, FollowingProvider, Offer, Applause, Following, CustomUser, FollowingPlace, Place, Following
from users.forms import ProviderForm, PetitionForm, PetitionNewForm, CustomUserForm, PlaceForm
from django.contrib.gis.geos import Point
from django.contrib.gis.db.models.functions import Distance


import json
import logging
import copy
logger = logging.getLogger(__name__)

# Create your views here.

#######################################################################
# Petition
#######################################################################

#
# Petition - Petition
#
class private_petition_list(APIView):

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        page_size = request.GET.get('page_size','10')
        page_number = request.GET.get('page_number','1')
        longitude = request.GET.get('longitude','0')
        latitude = request.GET.get('latitude','0')

        following_list = Following.objects.filter(
            user=request.user).values_list(
                'following_to', flat=True).order_by('following_to')

        following_list_place = FollowingPlace.objects.filter(
            user=request.user).values_list(
                'place', flat=True).order_by('pk')

        following_list_provider = FollowingProvider.objects.filter(
            user=request.user).values_list(
                'provider', flat=True).order_by('pk')

        latest_joins = Petition.objects.filter(added_to=OuterRef('pk')).order_by('-start_date')


        user_location = Point(float(longitude), float(latitude), srid=4326)
        
        petition_full_list = Petition.objects.filter(
            Q(user__in= following_list) | Q(place__in= following_list_place) | Q(provider__in= following_list_provider) | Q(user=request.user)).prefetch_related('added_to_petition').annotate(
                num_joins=Count('added_to_petition')).annotate(
                    num_offers=Count('answer_to_petition')).annotate(
                        num_applauses=Count('applause')).annotate( i_joined=Count(Case(
                            When(added_to_petition__user__id=request.user.id, then=1),
                            output_field=IntegerField(),
                            ))).annotate( i_clapped=Count(Case(
                            When(applause__user__id=request.user.id, then=1),
                            output_field=IntegerField(),
                            ))).annotate(
                                distance=Distance('place__location',user_location)).order_by('distance').order_by('-start_date')

        paginator = Paginator(petition_full_list, page_size) # Show 25 contacts per page
        if int(page_number) > paginator.num_pages:
            return Response("", status=status.HTTP_204_NO_CONTENT)

        petition_list = paginator.get_page(page_number)
        serializer = PetitionSerializer(petition_list, many=True)
        return Response(serializer.data)


# Social login
class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter

""" class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter """
    
# API views
# Petition views
class PetitionList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        petitions = Petition.objects.all()
        serializer = PetitionSerializer(petitions, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = PetitionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class PetitionDetail(APIView):
    """
    Retrieve, update or delete a petition instance.
    """
    def get_object(self, pk):
        try:
            return Petition.objects.get(pk=pk)
        except Petition.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        petition = self.get_object(pk)
        petition.num_joins = Petition.objects.filter(added_to_petition=petition).count()
        petition.num_applauses  = Applause.objects.filter(petition=petition).count()
        petition.num_offers  = Petition.objects.filter(answer_to_petition=petition).count()
        petition.i_joined = 0
        petition.i_clapped = 0
        serializer = PetitionSerializer(petition)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        petition = self.get_object(pk)
        serializer = PetitionSerializer(petition, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        petition = self.get_object(pk)
        petition.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)




# API views
# Offer views
class OfferList(APIView):
    """
    List all offers, or create a new petition.
    """
    def get(self, request, format=None):
        offers = Offer.objects.all()
        serializer = OfferSerializer(offers, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = OfferSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class OfferDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Offer.objects.get(pk=pk)
        except Offer.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        offer = self.get_object(pk)
        serializer = OfferSerializer(offer)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        offer = self.get_object(pk)
        serializer = OfferSerializer(offer, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        offer = self.get_object(pk)
        offer.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

#
# Contribtions
#
# Petition views
class ResponsePetitionList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = ResponsePetition.objects.all()
    serializer_class = ResponsePetitionSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class ResponsePetitionDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = ResponsePetition.objects.all()
    serializer_class = ResponsePetitionSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


# API views
# Provider views
class ProviderList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        providers = Provider.objects.all()
        serializer = ProviderSerializer(providers, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ProviderSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ProviderDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Provider.objects.get(pk=pk)
        except Provier.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        provider = self.get_object(pk)
        provider.followers = FollowingProvider.objects.filter(provider=provider).count()
        provider.i_follow = FollowingProvider.objects.filter(user=request.user, provider=provider).count()
        serializer = ProviderSerializer(provider)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        provider = self.get_object(pk)
        serializer = ProviderSerializer(offer, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        provider = self.get_object(pk)
        provider.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


# API views
# Place views
class PlaceList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        longitude = -80.191788
        latitude = 25.761681
        user_location = Point(longitude, latitude, srid=4326)

        places = Place.objects.all().annotate(distance=Distance('location',user_location)).order_by('distance')
        serializer = PlaceSerializer(places, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = PlaceSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class PlaceDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Place.objects.get(pk=pk)
        except Place.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        place = self.get_object(pk)
        place.followers = FollowingPlace.objects.filter(place=place).count()
        place.i_follow = FollowingPlace.objects.filter(user=request.user, place=place).count()
        serializer = PlaceSerializer(place)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        place = self.get_object(pk)
        serializer = PlaceSerializer(place, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        place = self.get_object(pk)
        place.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


#
# Contribtions
#
# Applause views
class ApplauseList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Applause.objects.all()
    serializer_class = ApplauseSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = ApplauseSerializer(data=request.data)
        
        logger.error('Autenticado '+json.dumps(request.data))
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ApplauseDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Applause.objects.all()
    serializer_class = ApplauseSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# Applause views
class FollowingList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Following.objects.all()
    serializer_class = FollowingSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = Following.objects.filter(user=request.user,following_to=request.POST.get("following_to"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST)
                
        


class FollowingDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Following.objects.all()
    serializer_class = FollowingSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# FollowingPlace views
class FollowingPlaceList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = FollowingPlace.objects.all()
    serializer_class = FollowingPlaceSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = FollowingPlace.objects.filter(user=request.user,place=request.POST.get("place"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingPlaceSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FollowingPlaceDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = FollowingPlace.objects.all()
    serializer_class = FollowingPlaceSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# FollowingPlace views
class FollowingProviderList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = FollowingProvider.objects.all()
    serializer_class = FollowingProviderSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = FollowingProvider.objects.filter(user=request.user,provider=request.POST.get("provider"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingProviderSerializer(data=request.data)

            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FollowingProviderDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = FollowingProvider.objects.all()
    serializer_class = FollowingProviderSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, JsonResponse
from django.template import loader
from django.core.paginator import Paginator, EmptyPage
from django.core import serializers
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Case, When, IntegerField, OuterRef, Subquery
from django.contrib.gis.db.models.functions import Distance
from django.template.loader import render_to_string
from rest_framework import viewsets
from rest_framework import permissions, authentication
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework import mixins
from rest_framework import generics
from rest_auth.registration.views import SocialLoginView
# from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from users.serializers import PetitionSerializer, ResponsePetitionSerializer, PlaceSerializer, ProviderSerializer, OfferSerializer, ApplauseSerializer, FollowingSerializer, FollowingPlaceSerializer, FollowingProviderSerializer
from users.models import Petition, ResponsePetition, Provider, FollowingProvider, Offer, Applause, Following, CustomUser, FollowingPlace, Place, Following
from users.forms import ProviderForm, PetitionForm, PetitionNewForm, CustomUserForm, PlaceForm
from django.contrib.gis.geos import Point
from django.contrib.gis.db.models.functions import Distance


import json
import logging
import copy
logger = logging.getLogger(__name__)

# Create your views here.

#######################################################################
# Petition
#######################################################################

#
# Petition - Petition
#
class private_petition_list(APIView):

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, format=None):
        """
        Return a list of all users.
        """
        page_size = request.GET.get('page_size','10')
        page_number = request.GET.get('page_number','1')
        longitude = request.GET.get('longitude','0')
        latitude = request.GET.get('latitude','0')

        following_list = Following.objects.filter(
            user=request.user).values_list(
                'following_to', flat=True).order_by('following_to')

        following_list_place = FollowingPlace.objects.filter(
            user=request.user).values_list(
                'place', flat=True).order_by('pk')

        following_list_provider = FollowingProvider.objects.filter(
            user=request.user).values_list(
                'provider', flat=True).order_by('pk')

        latest_joins = Petition.objects.filter(added_to=OuterRef('pk')).order_by('-start_date')


        user_location = Point(float(longitude), float(latitude), srid=4326)
        
        petition_full_list = Petition.objects.filter(
            Q(user__in= following_list) | Q(place__in= following_list_place) | Q(provider__in= following_list_provider) | Q(user=request.user)).prefetch_related('added_to_petition').annotate(
                num_joins=Count('added_to_petition')).annotate(
                    num_offers=Count('answer_to_petition')).annotate(
                        num_applauses=Count('applause')).annotate( i_joined=Count(Case(
                            When(added_to_petition__user__id=request.user.id, then=1),
                            output_field=IntegerField(),
                            ))).annotate( i_clapped=Count(Case(
                            When(applause__user__id=request.user.id, then=1),
                            output_field=IntegerField(),
                            ))).annotate(
                                distance=Distance('place__location',user_location)).order_by('distance').order_by('-start_date')

        paginator = Paginator(petition_full_list, page_size) # Show 25 contacts per page
        if int(page_number) > paginator.num_pages:
            return Response("", status=status.HTTP_204_NO_CONTENT)

        petition_list = paginator.get_page(page_number)
        serializer = PetitionSerializer(petition_list, many=True)
        return Response(serializer.data)


# Social login
class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter

""" class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter """
    
# API views
# Petition views
class PetitionList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        petitions = Petition.objects.all()
        serializer = PetitionSerializer(petitions, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = PetitionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class PetitionDetail(APIView):
    """
    Retrieve, update or delete a petition instance.
    """
    def get_object(self, pk):
        try:
            return Petition.objects.get(pk=pk)
        except Petition.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        petition = self.get_object(pk)
        petition.num_joins = Petition.objects.filter(added_to_petition=petition).count()
        petition.num_applauses  = Applause.objects.filter(petition=petition).count()
        petition.num_offers  = Petition.objects.filter(answer_to_petition=petition).count()
        petition.i_joined = 0
        petition.i_clapped = 0
        serializer = PetitionSerializer(petition)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        petition = self.get_object(pk)
        serializer = PetitionSerializer(petition, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        petition = self.get_object(pk)
        petition.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)




# API views
# Offer views
class OfferList(APIView):
    """
    List all offers, or create a new petition.
    """
    def get(self, request, format=None):
        offers = Offer.objects.all()
        serializer = OfferSerializer(offers, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = OfferSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class OfferDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Offer.objects.get(pk=pk)
        except Offer.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        offer = self.get_object(pk)
        serializer = OfferSerializer(offer)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        offer = self.get_object(pk)
        serializer = OfferSerializer(offer, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        offer = self.get_object(pk)
        offer.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

#
# Contribtions
#
# Petition views
class ResponsePetitionList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = ResponsePetition.objects.all()
    serializer_class = ResponsePetitionSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class ResponsePetitionDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = ResponsePetition.objects.all()
    serializer_class = ResponsePetitionSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


# API views
# Provider views
class ProviderList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        providers = Provider.objects.all()
        serializer = ProviderSerializer(providers, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ProviderSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ProviderDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Provider.objects.get(pk=pk)
        except Provier.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        provider = self.get_object(pk)
        provider.followers = FollowingProvider.objects.filter(provider=provider).count()
        provider.i_follow = FollowingProvider.objects.filter(user=request.user, provider=provider).count()
        serializer = ProviderSerializer(provider)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        provider = self.get_object(pk)
        serializer = ProviderSerializer(offer, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        provider = self.get_object(pk)
        provider.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


# API views
# Place views
class PlaceList(APIView):
    """
    List all petitions, or create a new petition.
    """
    def get(self, request, format=None):
        longitude = -80.191788
        latitude = 25.761681
        user_location = Point(longitude, latitude, srid=4326)

        places = Place.objects.all().annotate(distance=Distance('location',user_location)).order_by('distance')
        serializer = PlaceSerializer(places, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = PlaceSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class PlaceDetail(APIView):
    """
    Retrieve, update or delete a offer instance.
    """
    def get_object(self, pk):
        try:
            return Place.objects.get(pk=pk)
        except Place.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        place = self.get_object(pk)
        place.followers = FollowingPlace.objects.filter(place=place).count()
        place.i_follow = FollowingPlace.objects.filter(user=request.user, place=place).count()
        serializer = PlaceSerializer(place)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        place = self.get_object(pk)
        serializer = PlaceSerializer(place, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        place = self.get_object(pk)
        place.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


#
# Contribtions
#
# Applause views
class ApplauseList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Applause.objects.all()
    serializer_class = ApplauseSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = ApplauseSerializer(data=request.data)
        
        logger.error('Autenticado '+json.dumps(request.data))
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ApplauseDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Applause.objects.all()
    serializer_class = ApplauseSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# Applause views
class FollowingList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Following.objects.all()
    serializer_class = FollowingSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = Following.objects.filter(user=request.user,following_to=request.POST.get("following_to"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(status=status.HTTP_400_BAD_REQUEST)
                
        


class FollowingDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Following.objects.all()
    serializer_class = FollowingSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# FollowingPlace views
class FollowingPlaceList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = FollowingPlace.objects.all()
    serializer_class = FollowingPlaceSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = FollowingPlace.objects.filter(user=request.user,place=request.POST.get("place"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingPlaceSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FollowingPlaceDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = FollowingPlace.objects.all()
    serializer_class = FollowingPlaceSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


#
# Contribtions
#
# FollowingPlace views
class FollowingProviderList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = FollowingProvider.objects.all()
    serializer_class = FollowingProviderSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        following = FollowingProvider.objects.filter(user=request.user,provider=request.POST.get("provider"))
        if following:
            following.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            serializer = FollowingProviderSerializer(data=request.data)

            if serializer.is_valid():
                serializer.save(user=request.user)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class FollowingProviderDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = FollowingProvider.objects.all()
    serializer_class = FollowingProviderSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
# from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter # Create your views here. ####################################################################### # Petition ####################################################################### # # Petition - Petition # Return a list of all users. # Show 25 contacts per page # Social login class FacebookLogin(SocialLoginView):     adapter_class = FacebookOAuth2Adapter # API views # Petition views List all petitions, or create a new petition. Retrieve, update or delete a petition instance. # API views # Offer views List all offers, or create a new petition. Retrieve, update or delete a offer instance. # # Contribtions # # Petition views # API views # Provider views List all petitions, or create a new petition. Retrieve, update or delete a offer instance. # API views # Place views List all petitions, or create a new petition. Retrieve, update or delete a offer instance. # # Contribtions # # Applause views # # Contribtions # # Applause views # # Contribtions # # FollowingPlace views # # Contribtions # # FollowingPlace views