"""Establishment app views.""" from django.conf import settings from django.contrib.gis.geos import Point from django.shortcuts import get_object_or_404 from rest_framework import generics, permissions from comment import models as comment_models from establishment import filters from establishment import models, serializers from establishment.views import EstablishmentMixin from main import methods from main.models import MetaDataContent from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer from utils.pagination import EstablishmentPortionPagination class EstablishmentListView(EstablishmentMixin, generics.ListAPIView): """Resource for getting a list of establishments.""" serializer_class = serializers.EstablishmentListSerializer filter_class = filters.EstablishmentFilter def get_queryset(self): """Overridden method 'get_queryset'.""" qs = super(EstablishmentListView, self).get_queryset() return qs.by_country_code(code=self.request.country_code) \ .annotate_in_favorites(user=self.request.user) class EstablishmentRecentReviewListView(EstablishmentListView): """List view for last reviewed establishments.""" pagination_class = EstablishmentPortionPagination def get_queryset(self): """Overridden method 'get_queryset'.""" qs = super().get_queryset() user_ip = methods.get_user_ip(self.request) query_params = self.request.query_params if 'longitude' in query_params and 'latitude' in query_params: longitude, latitude = query_params.get('longitude'), query_params.get('latitude') else: longitude, latitude = methods.determine_coordinates(user_ip) if not longitude or not latitude: return qs.none() point = Point(x=float(longitude), y=float(latitude), srid=settings.GEO_DEFAULT_SRID) return qs.last_reviewed(point=point) class EstablishmentSimilarListView(EstablishmentListView): """Resource for getting a list of establishments.""" serializer_class = serializers.EstablishmentListSerializer pagination_class = EstablishmentPortionPagination def get_queryset(self): """Override get_queryset method""" qs = super().get_queryset() return qs.similar(establishment_slug=self.kwargs.get('slug')) class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView): """Resource for getting a establishment.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentDetailSerializer def get_queryset(self): """Override 'get_queryset' method.""" return super(EstablishmentRetrieveView, self).get_queryset() \ .annotate_in_favorites(self.request.user) class EstablishmentTypeListView(generics.ListAPIView): """Resource for getting a list of establishment types.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentTypeSerializer queryset = models.EstablishmentType.objects.all() class EstablishmentCommentCreateView(generics.CreateAPIView): """View for create new comment.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentCommentCreateSerializer queryset = comment_models.Comment.objects.all() class EstablishmentCommentListView(generics.ListAPIView): """View for return list of establishment comments.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentCommentCreateSerializer def get_queryset(self): """Override get_queryset method""" establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug']) return comment_models.Comment.objects.by_content_type(app_label='establishment', model='establishment')\ .by_object_id(object_id=establishment.pk)\ .order_by('-created') class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): """View for retrieve/update/destroy establishment comment.""" serializer_class = serializers.EstablishmentCommentRUDSerializer queryset = models.Establishment.objects.all() def get_object(self): """ Returns the object the view is displaying. """ queryset = self.filter_queryset(self.get_queryset()) establishment_obj = get_object_or_404(queryset, slug=self.kwargs['slug']) comment_obj = get_object_or_404(establishment_obj.comments.by_user(self.request.user), pk=self.kwargs['comment_id']) # May raise a permission denied self.check_object_permissions(self.request, comment_obj) return comment_obj class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.DestroyAPIView): """View for create/destroy establishment from favorites.""" serializer_class = serializers.EstablishmentFavoritesCreateSerializer lookup_field = 'slug' def get_object(self): """ Returns the object the view is displaying. """ establishment_obj = get_object_or_404(models.Establishment, slug=self.kwargs['slug']) obj = get_object_or_404( self.request.user.favorites.by_content_type(app_label='establishment', model='establishment') .by_object_id(object_id=establishment_obj.pk)) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj class EstablishmentNearestRetrieveView(EstablishmentListView, generics.ListAPIView): """Resource for getting list of nearest establishments.""" serializer_class = serializers.EstablishmentListSerializer filter_class = filters.EstablishmentFilter def get_queryset(self): """Overridden method 'get_queryset'.""" lat = self.request.query_params.get('lat') lon = self.request.query_params.get('lon') radius = self.request.query_params.get('radius') unit = self.request.query_params.get('unit') qs = super(EstablishmentNearestRetrieveView, self).get_queryset() if lat and lon and radius and unit: center = Point(float(lat), float(lon)) filter_kwargs = {'center': center, 'radius': float(radius), 'unit': unit} return qs.by_distance_from_point(**{k: v for k, v in filter_kwargs.items() if v is not None}) return qs class EstablishmentTagListView(generics.ListAPIView): """List view for establishment tags.""" serializer_class = serializers.EstablishmentTagListSerializer permission_classes = (permissions.AllowAny,) pagination_class = None def get_queryset(self): """Override get_queryset method""" return MetaDataContent.objects.by_content_type(app_label='establishment', model='establishment')\ .distinct('metadata__label') class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment schedule RUD view""" serializer_class = ScheduleRUDSerializer def get_object(self): """ Returns the object the view is displaying. """ establishment_pk = self.kwargs['pk'] schedule_id = self.kwargs['schedule_id'] establishment = get_object_or_404(klass=models.Establishment.objects.all(), pk=establishment_pk) schedule = get_object_or_404(klass=establishment.schedule, id=schedule_id) # May raise a permission denied self.check_object_permissions(self.request, establishment) self.check_object_permissions(self.request, schedule) return schedule class EstablishmentScheduleCreateView(generics.CreateAPIView): """Establishment schedule Create view""" serializer_class = ScheduleCreateSerializer