def post(self, request): """ **Use Case** * Send favorite program through email to user for later learning. **Example Request for program** POST /api/v1/save/program/ **Example POST Request for program** { "email": "*****@*****.**", "program_uuid": "587f6abe-bfa4-4125-9fbe-4789bf3f97f1" } """ user = request.user data = request.data program_uuid = data.get('program_uuid') email = data.get('email') user_id = request.user.id pref_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, 'en') send_to_self = bool(not request.user.is_anonymous and request.user.email == email) if getattr(request, 'limited', False): return Response({'error_code': 'rate-limited'}, status=403) if get_email_validation_error(email): return Response({'error_code': 'incorrect-email'}, status=400) if not program_uuid: return Response({'error_code': 'program-uuid-missing'}, status=400) program = get_programs(uuid=program_uuid) SavedProgram.objects.update_or_create(email=email, program_uuid=program_uuid, defaults={ 'user_id': user.id, 'reminder_email_sent': False, }) if program: program_data = { 'program': program, 'send_to_self': send_to_self, 'user_id': user_id, 'pref-lang': pref_lang, 'type': 'program', 'reminder': False, 'braze_event': USER_SEND_SAVE_FOR_LATER_EMAIL, } if send_email(email, program_data): return Response({'result': 'success'}, status=200) else: return Response({'error_code': 'email-not-send'}, status=400) return Response({'error_code': 'program-not-found'}, status=404)
def handle(self, *args, **options): """ Handle the send save for later reminder emails. """ reminder_email_threshold_date = datetime.now() - timedelta( days=settings.SAVE_FOR_LATER_REMINDER_EMAIL_THRESHOLD) saved_courses_ids = SavedCourse.objects.filter( reminder_email_sent=False, modified__lt=reminder_email_threshold_date).values_list('id', flat=True) total = saved_courses_ids.count() batch_size = max(1, options.get('batch_size')) num_batches = ((total - 1) / batch_size + 1) if total > 0 else 0 for batch_num in range(int(num_batches)): reminder_email_sent_ids = [] start = batch_num * batch_size end = min(start + batch_size, total) - 1 saved_courses_batch_ids = list(saved_courses_ids)[start:end + 1] query = SavedCourse.objects.filter( id__in=saved_courses_batch_ids).order_by('-modified') saved_courses = use_read_replica_if_available(query) for saved_course in saved_courses: user = User.objects.filter(email=saved_course.email).first() course_overview = CourseOverview.get_from_id( saved_course.course_id) course_data = { 'course': course_overview, 'send_to_self': None, 'user_id': saved_course.user_id, 'org_img_url': saved_course.org_img_url, 'marketing_url': saved_course.marketing_url, 'weeks_to_complete': saved_course.weeks_to_complete, 'min_effort': saved_course.min_effort, 'max_effort': saved_course.max_effort, 'type': 'course', 'reminder': True, 'braze_event': USER_SEND_SAVE_FOR_LATER_REMINDER_EMAIL, } if user: enrollment = CourseEnrollment.get_enrollment( user, saved_course.course_id) if enrollment: continue email_sent = send_email(saved_course.email, course_data) if email_sent: reminder_email_sent_ids.append(saved_course.id) else: logging.info( "Unable to send reminder email to {user} for {course} course" .format(user=str(saved_course.email), course=str(saved_course.course_id))) SavedCourse.objects.filter(id__in=reminder_email_sent_ids).update( reminder_email_sent=True)
def post(self, request): """ **Use Case** * Send favorite course through email to user for later learning. **Example Request for course** POST /api/v1/save/course/ **Example POST Request for course** { "email": "*****@*****.**", "course_id": "course-v1:edX+DemoX+2021", "marketing_url": "https://test.com", "org_img_url": "https://test.com/logo.png", "weeks_to_complete": 7, "min_effort": 4, "max_effort": 5, } """ user = request.user data = request.data course_id = data.get('course_id') email = data.get('email') if getattr(request, 'limited', False): return Response({'error_code': 'rate-limited'}, status=403) if get_email_validation_error(email): return Response({'error_code': 'incorrect-email'}, status=400) try: course_key = CourseKey.from_string(course_id) course = CourseOverview.get_from_id(course_key) except InvalidKeyError: return Response({'error_code': 'invalid-course-key'}, status=400) except CourseOverview.DoesNotExist: return Response({'error_code': 'course-not-found'}, status=404) SavedCourse.objects.update_or_create( user_id=user.id, email=email, course_id=course_id, ) course_data = { 'course': course, 'type': 'course', } if send_email(request, email, course_data): return Response({'result': 'success'}, status=200) else: return Response({'error_code': 'email-not-send'}, status=400)
def handle(self, *args, **options): """ Handle the send save for later reminder emails. """ reminder_email_threshold_date = datetime.now() - timedelta( days=settings.SAVE_FOR_LATER_REMINDER_EMAIL_THRESHOLD) saved_program_ids = SavedProgram.objects.filter( reminder_email_sent=False, modified__lt=reminder_email_threshold_date).values_list('id', flat=True) total = saved_program_ids.count() batch_size = max(1, options.get('batch_size')) num_batches = ((total - 1) / batch_size + 1) if total > 0 else 0 for batch_num in range(int(num_batches)): reminder_email_sent_ids = [] start = batch_num * batch_size end = min(start + batch_size, total) - 1 saved_program_batch_ids = list(saved_program_ids)[start:end + 1] query = SavedProgram.objects.filter( id__in=saved_program_batch_ids).order_by('-modified') saved_programs = use_read_replica_if_available(query) for saved_program in saved_programs: user = User.objects.filter(email=saved_program.email).first() program = get_programs(uuid=saved_program.program_uuid) if program: program_data = { 'program': program, 'send_to_self': None, 'user_id': saved_program.user_id, 'type': 'program', 'reminder': True, 'braze_event': USER_SEND_SAVE_FOR_LATER_REMINDER_EMAIL, } try: if user and get_program_enrollment( program_uuid=saved_program.program_uuid, user=user): continue except ObjectDoesNotExist: pass email_sent = send_email(saved_program.email, program_data) if email_sent: reminder_email_sent_ids.append(saved_program.id) else: logging.info( "Unable to send reminder email to {user} for {program} program" .format(user=str(saved_program.email), program=str(saved_program.program_uuid))) SavedProgram.objects.filter(id__in=reminder_email_sent_ids).update( reminder_email_sent=True)
def post(self, request): """ **Use Case** * Send favorite program through email to user for later learning. **Example Request for program** POST /api/v1/save/program/ **Example POST Request for program** { "email": "*****@*****.**", "program_uuid": "587f6abe-bfa4-4125-9fbe-4789bf3f97f1" } """ user = request.user data = request.data program_uuid = data.get('program_uuid') email = data.get('email') if getattr(request, 'limited', False): return Response({'error_code': 'rate-limited'}, status=403) if get_email_validation_error(email): return Response({'error_code': 'incorrect-email'}, status=400) if not program_uuid: return Response({'error_code': 'program-uuid-missing'}, status=400) program = get_programs(uuid=program_uuid) SavedProgram.objects.update_or_create( user_id=user.id, email=email, program_uuid=program_uuid, ) if program: program_data = { 'program': program, 'type': 'program', } if send_email(request, email, program_data): return Response({'result': 'success'}, status=200) else: return Response({'error_code': 'email-not-send'}, status=400) return Response({'error_code': 'program-not-found'}, status=404)
def post(self, request): """ **Use Case** * Send favorite course through email to user for later learning. **Example Request for course** POST /api/v1/save/course/ **Example POST Request for course** { "email": "*****@*****.**", "course_id": "course-v1:edX+DemoX+2021", "marketing_url": "https://test.com", "org_img_url": "https://test.com/logo.png", "weeks_to_complete": 7, "min_effort": 4, "max_effort": 5, } """ user = request.user data = request.data course_id = data.get('course_id') email = data.get('email') org_img_url = data.get('org_img_url') marketing_url = data.get('marketing_url') weeks_to_complete = data.get('weeks_to_complete', 0) min_effort = data.get('min_effort', 0) max_effort = data.get('max_effort', 0) user_id = request.user.id pref_lang = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME, 'en') send_to_self = bool(not request.user.is_anonymous and request.user.email == email) if getattr(request, 'limited', False): return Response({'error_code': 'rate-limited'}, status=403) if get_email_validation_error(email): return Response({'error_code': 'incorrect-email'}, status=400) try: course_key = CourseKey.from_string(course_id) course = CourseOverview.get_from_id(course_key) except InvalidKeyError: return Response({'error_code': 'invalid-course-key'}, status=400) except CourseOverview.DoesNotExist: return Response({'error_code': 'course-not-found'}, status=404) SavedCourse.objects.update_or_create( user_id=user.id, email=email, course_id=course_id, org_img_url=org_img_url, marketing_url=marketing_url, weeks_to_complete=weeks_to_complete, min_effort=min_effort, max_effort=max_effort, reminder_email_sent=False, ) course_data = { 'course': course, 'send_to_self': send_to_self, 'user_id': user_id, 'pref-lang': pref_lang, 'org_img_url': org_img_url, 'marketing_url': marketing_url, 'weeks_to_complete': weeks_to_complete, 'min_effort': min_effort, 'max_effort': max_effort, 'type': 'course', 'reminder': False, 'braze_event': USER_SEND_SAVE_FOR_LATER_EMAIL, } if send_email(email, course_data): return Response({'result': 'success'}, status=200) else: return Response({'error_code': 'email-not-send'}, status=400)