def create_professor(request): try: logger.info("Got request to create new professor") data = get_data_from_request(request, 'added_by') logger.info(f"Request data - {data}") logger.info("Validating request data") serializer = ProfessorsSerializerPOST(data=data) if serializer.is_valid(): logger.info("Serializer valid") serializer.save() logger.info("Professor added to database") prof = Professor.objects.get(id=serializer.data["id"]) serialized_prof_data = ProfessorsSerializerGET(prof) return Response( { 'success': 'true', 'professor': serialized_prof_data.data }, status=status.HTTP_201_CREATED) else: logger.info( "Request data invalid. Unable to save professor to database") logger.error(serializer.errors) return Response({ 'success': 'false', 'errors': serializer.errors }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def register_by_access_token(request, backend): # This view expects an access_token GET parameter, if it's needed, # request.backend and request.strategy will be loaded with the current # backend and strategy. logger.info("Got request to sign in user from access token") request_data = get_data_from_request(request) token = request_data.get('access_token') user = request.backend.do_auth(access_token=token, backend=backend) if user: logger.info("User authenticated. Generating token") login(request, user) jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) logger.info("Token generated successfully") return Response({ "user": user.email, "token": token }, status=status.HTTP_200_OK) else: logger.info("unable to authenticate user. Error.") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def create_college(request): logger.info("Got request to add new college") try: data = get_data_from_request(request, 'added_by') logger.info(f"Request data - {data}") college_id = data["id"] logger.info("Checking if college exists in database") college_exists = College.objects.filter(id=college_id).exists() if college_exists: logger.info( "College already added to database. Returning existing college data" ) college = College.objects.get(id=college_id) response_data = {'status': 'exists'} college_data = CollegesSerializerGET(college).data response_data['college'] = college_data logger.info(f"Fetching professors for college - {college_id}") professors_data = search(request._request, college_id) logger.info("Got professors for college. Adding to response") response_data['professors'] = professors_data.data['professors'] return Response(response_data, status=status.HTTP_302_FOUND) else: logger.info("New college. Formatting data and saving to database") formatted_data = format_college_add_data(data) logger.info("Got formatted data. Serializing to save to database") serializer = CollegesSerializerPOST(data=formatted_data) if serializer.is_valid(): logger.info("Data successfully serialized") serializer.save() logger.info("Saved to database") college = College.objects.get(id=formatted_data['id']) logger.info("Sending serialized college data in response") get_serializer = CollegesSerializerGET(college) return Response( { 'status': 'success', 'college': get_serializer.data }, status=status.HTTP_201_CREATED) else: logger.error( f"Error serializing college data - {serializer.errors}") return Response( { 'status': 'failure', 'college': {}, 'errors': serializer.errors }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def report_review(request, review_id): logger.info("Got request to report review") try: report_data = get_data_from_request(request, 'reported_by') logger.info(f"Report data - {report_data}") report_data['review'] = review_id review = Review.objects.get(pk=review_id) response_data = {'success': False, 'message': ""} logger.info("Checking if review is already reported by the user") try: existing_report = ReportReview.objects.get( review=review_id, reported_by=report_data['reported_by']) logger.info( "Review already reported by user. No updated required") is_reported = True except ReportReview.DoesNotExist: logger.info("Review not reported by the user.") is_reported = False if is_reported: logger.info( "Review already reported by the user. Updating reason, if any") existing_report.reason = report_data["reason"] existing_report.save() response_data['message'] = "Report updated" logger.info("Database updated.") return Response(response_data, status=status.HTTP_302_FOUND) else: logger.info( f"Review reported by user {report_data['reported_by']} for first time. Saving to database" ) review.times_reported += 1 serialized_report = ReportReviewSerializer(data=report_data) if serialized_report.is_valid(): logger.info("Serialised request object") review.save() serialized_report.save() logger.info("Database successfully updated") response_data['success'] = True response_data['message'] = "Review Reported" logger.info( "Soft delete review if reported more than threshold and returning response" ) check_and_hide_reported_reviews(review) return Response(response_data, status=status.HTTP_200_OK) else: logger.error( f"Error saving report - {serialized_report.errors}") response_data['message'] = serialized_report.errors return Response(response_data, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def add_review(request, professor_id): logger.info("Got request to add review for professor") try: data = get_data_from_request(request, 'added_by') data['professor'] = professor_id existing_review_data = check_if_professor_reviewed( request._request, professor_id).data if existing_review_data['is_reviewed']: logger.info("Found existing review. Overwriting") review = Review.objects.get( id=existing_review_data['review_data']['id']) review.title = data['title'] review.score = data['score'] review.review = data['review'] logger.info("Review data updated. Saving...") update_professor_and_college_data_on_review_add( data, professor_id, existing_review_data) logger.info("Professor and college data updated") review.save() logger.info("Review saved to database") return Response({'success': 'Review successfully updated.'}, status=status.HTTP_201_CREATED) else: logger.info("New review found. Serialize and save to database") serializer = ReviewsSerializer(data=data) if serializer.is_valid(): logger.info( "Review serialized successfully. Update professors and college data." ) update_professor_and_college_data_on_review_add( data, professor_id, existing_review_data) logger.info( "Professor and college data updated. Saving review to database" ) serializer.save() return Response({'success': 'Review successfully added.'}, status=status.HTTP_201_CREATED) else: logger.info(f"Error serializing review. {serializer.errors}") return Response( { 'success': 'false', 'errors': serializer.errors }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def set_profile(request): try: data = get_data_from_request(request) serializer = ProfileSerializer(data=data) if serializer.is_valid(): serializer.save() return Response({"success": "true"}, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def save_user_phone_details(request): try: logger.info("Saving user phone details") data = get_data_from_request(request) logger.info(f"Request data - {data}") logger.info("Validating request data") serializer = UserPhoneDetailsSerializer(data=data) response_data = {'status': 'Reject'} user_version_code = float(data['versionCode']) if serializer.is_valid(): logger.info("User data valid. Saving to database") serializer.save() logger.info("User phone data saved") logger.info("Saving data to firebase db") db = firebase.database() db.child("userDevice").push(serializer.data) logger.info("Data saved to firebase db") logger.info("Checking user app version") if user_version_code >= float(VERSIONS['min_code']): logger.info( f"User version code - {user_version_code} greater than minimum required version - " f"{VERSIONS['min_code']}") response_data['status'] = 'Later' if user_version_code >= float(VERSIONS['latest_code']): logger.info( f"User version code - {user_version_code} satisfies latest version - " f"{VERSIONS['latest_code']}") response_data['status'] = 'Approved' return Response(response_data, status=status.HTTP_200_OK) else: logger.info("User phone data invalid") return Response({ 'status': 'Error', 'error': serializer.errors }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def verify_activation_code(request): try: data = get_data_from_request(request) logger.info(f"Verifying activation code. User - {data['user']}") data['activation_code'] = int(data['activation_code']) try: logger.info("Fetching user and activation code from database.") user_activation_object = UserActivation.objects.get( email=data['email']) if user_activation_object is not None: user_activation_serializer = UserActivationSerializer( user_activation_object) activation_code = user_activation_serializer.data[ 'activation_code'] logger.info( "Matching user activation code with actual activation code" ) if activation_code == data['activation_code']: logger.info("Code matched") data['activation_status'] = True updated_serializer = UserActivationSerializer( user_activation_object, data=data) if updated_serializer.is_valid(): logger.info( "User activation status updated. Sending Success response" ) updated_serializer.save() return Response({'status': 'verified'}, status=status.HTTP_200_OK) else: logger.error("Activation code mismatch") return Response({'status': 'rejected'}, status=status.HTTP_404_NOT_FOUND) except UserActivation.DoesNotExist: logger.info( "User not found. Activation code is not generated for the user." ) return Response({'status': 'email not found'}, status=status.HTTP_404_NOT_FOUND) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_filtered_professors(request, college_id): try: logger.info("Got request to filter professors") filter_params = get_data_from_request(request) logger.info(f"Filter parameters - {filter_params}") logger.info(f"Fetching professors with current college - {college_id}") professors = Professor.objects.filter(college=college_id) prof_serialized_data = ProfessorsSerializerGET(professors, many=True).data logger.info(f"Found {len(prof_serialized_data)} professors") if not filter_params.get("show_present_college_only", False): logger.info( f"Fetching professors who previously were at college = {college_id}" ) old_professors = Professor.objects.filter( previous_college=college_id) old_prof_serialized_data = ProfessorsSerializerGET(old_professors, many=True).data logger.info( f"Found {len(old_prof_serialized_data)} old professors") else: logger.info("Filtering to not show any old professors") old_prof_serialized_data = [] if filter_params.get("rating_low_high", False): logger.info("Sort professors by rating - low to high") prof_serialized_data = sorted(prof_serialized_data, key=itemgetter('rating')) old_prof_serialized_data = sorted(old_prof_serialized_data, key=itemgetter('rating')) elif filter_params.get("rating_high_low", False): logger.info("Sort professors by rating - high to low") prof_serialized_data = sorted(prof_serialized_data, key=itemgetter('rating'), reverse=True) old_prof_serialized_data = sorted(old_prof_serialized_data, key=itemgetter('rating'), reverse=True) elif filter_params.get('num_reviews_low_high', False): logger.info("Sort professors by number of reviews - low to high") prof_serialized_data = sorted(prof_serialized_data, key=itemgetter('num_reviews')) old_prof_serialized_data = sorted(old_prof_serialized_data, key=itemgetter('num_reviews')) elif filter_params.get('num_reviews_high_low', False): logger.info("Sort professors by number of reviews - high to low") prof_serialized_data = sorted(prof_serialized_data, key=itemgetter('num_reviews'), reverse=True) old_prof_serialized_data = sorted(old_prof_serialized_data, key=itemgetter('num_reviews'), reverse=True) num_prof = len(prof_serialized_data) + len(old_prof_serialized_data) response_data = { 'count': num_prof, 'professors': prof_serialized_data, 'previous_professors': old_prof_serialized_data } if num_prof != 0: logger.info(f"Found {num_prof} professors. Send response") return Response(response_data, status=status.HTTP_200_OK) else: logger.info("Found 0 professors. Send response") return Response(response_data, status=status.HTTP_404_NOT_FOUND) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def verify_if_user_registered(request): data = get_data_from_request(request) email = data['email'] logger.info(f"Searching for user with email {email}") user = get_object_or_404(User, username=email) return Response({'success': 'User exists'}, status=status.HTTP_302_FOUND)
def send_activation_code(request): try: data = get_data_from_request(request) email = data['email'] logger.info(f"Sending activation code to {email}") # TODO: possible to implement hashing here activation_code = random.randint(100000, 999999) logger.debug(f"Activation code - {activation_code}") serializer_data = { 'email': email, 'activation_code': activation_code, 'activation_status': False, } try: logger.info("Checking if user already requested activation token.") existing_detail = UserActivation.objects.get(email=email) last_attempt_time = existing_detail.attempt_datetime logger.info( f"User's lask activation code request time - {last_attempt_time}" ) time_difference_between_attempts = time.time() - last_attempt_time logger.info( f"Time difference between consecutive attempts - {time_difference_between_attempts}" ) logger.info( f"Maximum attempts allowed in {settings.ACTIVATION_DELAY_SECONDS}seconds - " f"{settings.MAX_ACTIVATION_ATTEMPTS}") if existing_detail.num_attempts >= settings.MAX_ACTIVATION_ATTEMPTS: if time_difference_between_attempts <= settings.ACTIVATION_DELAY_SECONDS: logger.info( "Exceeded maximum number of attempts in given time") delay_minutes = int(settings.ACTIVATION_DELAY_SECONDS / 60) response_data = { 'status': 'failure', 'reason': f"Only {settings.MAX_ACTIVATION_ATTEMPTS} attempts " f"allowed every {delay_minutes}" f" minutes. Please try after " f"{delay_minutes-int(time_difference_between_attempts/60)} minutes." } return Response(response_data, status=status.HTTP_429_TOO_MANY_REQUESTS) else: logger.info( "User requesting activation code after expected time difference. " "Sending new activation code.") serializer_data['num_attempts'] = 1 serializer_data['attempt_datetime'] = time.time() logger.info( f"Activation code generated at - {time.time()}") serializer = UserActivationSerializer(existing_detail, data=serializer_data) else: logger.info( f"Activation code request number - {existing_detail.num_attempts + 1}" ) serializer_data[ 'num_attempts'] = existing_detail.num_attempts + 1 logger.info( f"User requested less than {settings.MAX_ACTIVATION_ATTEMPTS} times. Sending activation code." ) serializer = UserActivationSerializer(existing_detail, data=serializer_data) except UserActivation.DoesNotExist: logger.info("New user. Sending activation code.") serializer_data['num_attempts'] = 1 serializer_data['attempt_datetime'] = time.time() serializer = UserActivationSerializer(data=serializer_data) if serializer.is_valid(): serializer.save() if not settings.IS_TESTING: logger.info("Preparing email to be sent to the user.") plaintext = get_template('email.txt') htmltext = get_template('email.html') context = {'activation_code': activation_code} text_content = plaintext.render(context) html_content = htmltext.render(context) subject = "Welcome to PISS" msg = EmailMultiAlternatives(subject, text_content, to=[data["email"]]) msg.attach_alternative(html_content, "text/html") logger.info("Email content generated. Sending email to user") send_email_thread = Thread(target=send_email, args=(msg, )) send_email_thread.start() response_data = {'status': 'success'} return Response(response_data, status=status.HTTP_200_OK) else: logger.info("Error generating activation code for the user") logger.error(f"{serializer.errors}") response_data = {'status': 'failure'} return Response(response_data, status=status.HTTP_404_NOT_FOUND) except Exception as e: logger.error(f"Unhandled exception occurred - {str(e)}") return Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)