from django.contrib.auth.models import User from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from api.models import Trip, City, NotificationTypeChoice from api.modules.notification.views import add_notification from api.modules.trips.serializers import TripSerializer, TripCondensedSerializer @api_view(['POST']) def add_trip(request): """ Add a trip with current user as a default member to it :param request: :return: 400 if incorrect parameters are sent or database request failed :return: 201 successful """ trip_name = request.POST.get('trip_name', None) start_date_tx = request.POST.get('start_date_tx', None) city_id = request.POST.get('city_id', None) if not trip_name or not start_date_tx or not city_id: # incorrect request received error_message = "Missing parameters in request. Send trip_name, city_id, start_date_tx" return Response(error_message, status=status.HTTP_400_BAD_REQUEST) try: city = City.objects.get(pk=city_id) trip = Trip(trip_name=trip_name, city=city, start_date_tx=start_date_tx) trip.save() trip.users.add(request.user) except Exception as e: error_message = str(e) return Response(error_message, status=status.HTTP_400_BAD_REQUEST) success_message = "Successfully added new trip." return Response(success_message, status=status.HTTP_201_CREATED) @api_view(['GET']) def get_trip(request, trip_id): """ Returns a trip using 'trip_id' :param request: :param trip_id: :return: 401 if user is not a member of this specific trip and trip is private :return: 404 if invalid trip id is sent :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) if request.user not in trip.users.all() and not trip.is_public: return Response(status=status.HTTP_401_UNAUTHORIZED) except Trip.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) serializer = TripSerializer(trip) return Response(serializer.data) @api_view(['GET']) def get_all_trips(request, no_of_trips=10): """ Returns a list of all the trips for a given user :param request: :param no_of_trips: default 10 :return: 200 successful """ trips = Trip.objects.filter(users=request.user).order_by('-start_date_tx')[:no_of_trips] serializer = TripCondensedSerializer(trips, many=True) return Response(serializer.data) @api_view(['GET']) def add_friend_to_trip(request, trip_id, user_id): """ Associates a user to existing trip :param request: :param trip_id: :param user_id: :return: 400 if user is already associated with the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) if request.user not in trip.users.all(): return Response(status=status.HTTP_401_UNAUTHORIZED) user = User.objects.get(pk=user_id) if user in trip.users.all(): error_message = "User already associated with trip" return Response(error_message, status=status.HTTP_400_BAD_REQUEST) trip.users.add(user) # creating notification notification_text = "You are added to %s trip by %s %s." % ( trip.city.city_name, request.user.first_name, request.user.last_name,) if not add_notification(initiator_user=request.user, destined_user=user, text=notification_text, notification_type=NotificationTypeChoice.TRIP.value, trip=trip): raise RuntimeError("Error while creating notification") except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except User.DoesNotExist: error_message = "User does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK) @api_view(['GET']) def remove_friend_from_trip(request, trip_id, user_id): """ Dissociates a user to existing trip :param request: :param trip_id: :param user_id: :return: 400 if user not present in the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) if request.user not in trip.users.all(): return Response(status=status.HTTP_401_UNAUTHORIZED) user = User.objects.get(pk=user_id) if user not in trip.users.all(): error_message = "User already not a part of trip" return Response(error_message, status=status.HTTP_400_BAD_REQUEST) trip.users.remove(user) except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except User.DoesNotExist: error_message = "User does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK) @api_view(['GET']) def update_trip_name(request, trip_id, trip_name): """ :param request: :param trip_id: :param trip_name: :return: 400 if user not present in the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(id=trip_id) if request.user not in trip.users.all(): return Response(status=status.HTTP_401_UNAUTHORIZED) trip.trip_name = trip_name trip.save(update_fields=['trip_name']) except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK) @api_view(['GET']) def get_common_trips(request, user_id): """ Common trips with a given friend :param request: :param user_id: :return: 400 if user_id and request.user are same :return: 404 if user with user_id does not exist :return: 200 successful """ # if user with user_id does not exist if not User.objects.filter(id=user_id).exists(): error_message = "User does not exists." return Response(error_message, status=status.HTTP_404_NOT_FOUND) # if user_id is same as of request.user if user_id == request.user.id: error_message = "Requested user and logged in user are same." return Response(error_message, status=status.HTTP_400_BAD_REQUEST) common_trips = Trip.objects \ .filter(users=request.user) \ .filter(users=user_id) serializer = TripSerializer(common_trips, many=True) return Response(serializer.data, status=status.HTTP_200_OK) @api_view(['GET']) def remove_user_from_trip(request, trip_id): """ Dissociates current signed-in user from existing trip :param request: :param trip_id: :return: 400 if user not present in the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) # if signed-in user not associated with requested trip if request.user not in trip.users.all(): error_message = "User not a part of trip" return Response(error_message, status=status.HTTP_401_UNAUTHORIZED) if trip.users.count() == 1: trip.delete() # delete trip if signed-in user is only member else: trip.users.remove(request.user) except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_200_OK) @api_view(['GET']) def update_trip_public(request, trip_id): """ Makes given trip public :param request: :param trip_id: :return: 400 if user not present in the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) # if signed-in user not associated with requested trip if request.user not in trip.users.all(): error_message = "User not a part of trip" return Response(error_message, status=status.HTTP_401_UNAUTHORIZED) trip.is_public = True trip.save() except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) return Response(status=status.HTTP_200_OK) @api_view(['GET']) def update_trip_private(request, trip_id): """ Makes given trip private :param request: :param trip_id: :return: 400 if user not present in the trip :return: 404 if trip or user does not exist :return: 200 successful """ try: trip = Trip.objects.get(pk=trip_id) # if signed-in user not associated with requested trip if request.user not in trip.users.all(): error_message = "User not a part of trip" return Response(error_message, status=status.HTTP_401_UNAUTHORIZED) trip.is_public = False trip.save() except Trip.DoesNotExist: error_message = "Trip does not exist" return Response(error_message, status=status.HTTP_404_NOT_FOUND) return Response(status=status.HTTP_200_OK)