def index(request): ''' Redirects to main page -- info page if user authenticated, or marketing if not ''' if settings.COURSEWARE_ENABLED and request.user.is_authenticated(): return redirect(reverse('dashboard')) if settings.FEATURES.get('AUTH_USE_CERTIFICATES'): from external_auth.views import ssl_login return ssl_login(request) enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)) if enable_mktg_site: return redirect(settings.MKTG_URLS.get('ROOT')) university = MicrositeConfiguration.match_university( request.META.get('HTTP_HOST')) # keep specialized logic for Edge until we can migrate over Edge to fully use # microsite definitions if university == 'edge': context = {'suppress_toplevel_navigation': True} return render_to_response('university_profile/edge.html', context) # we do not expect this case to be reached in cases where # marketing and edge are enabled return student.views.index(request, user=request.user)
def index(request): """ Redirects to main page -- info page if user authenticated, or marketing if not """ if settings.COURSEWARE_ENABLED and request.user.is_authenticated(): return redirect(reverse("dashboard")) if settings.FEATURES.get("AUTH_USE_MIT_CERTIFICATES"): from external_auth.views import ssl_login return ssl_login(request) enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( "ENABLE_MKTG_SITE", settings.FEATURES.get("ENABLE_MKTG_SITE", False) ) if enable_mktg_site: return redirect(settings.MKTG_URLS.get("ROOT")) university = MicrositeConfiguration.match_university(request.META.get("HTTP_HOST")) # keep specialized logic for Edge until we can migrate over Edge to fully use # microsite definitions if university == "edge": context = {"suppress_toplevel_navigation": True} return render_to_response("university_profile/edge.html", context) # we do not expect this case to be reached in cases where # marketing and edge are enabled return student.views.index(request, user=request.user)
def get_logo_url(): """ Return the url for the branded logo image to be used """ # if the MicrositeConfiguration has a value for the logo_image_url # let's use that image_url = MicrositeConfiguration.get_microsite_configuration_value('logo_image_url') if image_url: return '{static_url}{image_url}'.format( static_url=settings.STATIC_URL, image_url=image_url ) # otherwise, use the legacy means to configure this university = MicrositeConfiguration.get_microsite_configuration_value('university') if university is None: return '{static_url}images/header-logo.png'.format( static_url=settings.STATIC_URL ) return '{static_url}images/{uni}-on-edx-logo.png'.format( static_url=settings.STATIC_URL, uni=university )
def get_visible_courses(): """ Return the set of CourseDescriptors that should be visible in this branded instance """ _courses = modulestore().get_courses() courses = [c for c in _courses if isinstance(c, CourseDescriptor)] courses = sorted(courses, key=lambda course: course.number) subdomain = MicrositeConfiguration.get_microsite_configuration_value('subdomain', 'default') # See if we have filtered course listings in this domain filtered_visible_ids = None # this is legacy format which is outside of the microsite feature -- also handle dev case, which should not filter if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG: filtered_visible_ids = frozenset(settings.COURSE_LISTINGS[subdomain]) filtered_by_org = MicrositeConfiguration.get_microsite_configuration_value('course_org_filter') if filtered_by_org: return [course for course in courses if course.location.org == filtered_by_org] if filtered_visible_ids: return [course for course in courses if course.id in filtered_visible_ids] else: # Let's filter out any courses in an "org" that has been declared to be # in a Microsite org_filter_out_set = MicrositeConfiguration.get_all_microsite_orgs() return [course for course in courses if course.location.org not in org_filter_out_set]
def platform_name(): """ Django template tag that outputs the current platform name: {% platform_name %} """ return MicrositeConfiguration.get_microsite_configuration_value( 'platform_name', settings.PLATFORM_NAME)
def marketing_link(name): """Returns the correct URL for a link to the marketing site depending on if the marketing site is enabled Since the marketing site is enabled by a setting, we have two possible URLs for certain links. This function is to decides which URL should be provided. """ # link_map maps URLs from the marketing site to the old equivalent on # the Django site link_map = settings.MKTG_URL_LINK_MAP enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)) if enable_mktg_site and name in settings.MKTG_URLS: # special case for when we only want the root marketing URL if name == 'ROOT': return settings.MKTG_URLS.get('ROOT') return settings.MKTG_URLS.get('ROOT') + settings.MKTG_URLS.get(name) # only link to the old pages when the marketing site isn't on elif not enable_mktg_site and name in link_map: # don't try to reverse disabled marketing links if link_map[name] is not None: return reverse(link_map[name]) else: log.warning("Cannot find corresponding link for name: {name}".format( name=name)) return '#'
def marketing_link(name): """Returns the correct URL for a link to the marketing site depending on if the marketing site is enabled Since the marketing site is enabled by a setting, we have two possible URLs for certain links. This function is to decides which URL should be provided. """ # link_map maps URLs from the marketing site to the old equivalent on # the Django site link_map = settings.MKTG_URL_LINK_MAP enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False) ) if enable_mktg_site and name in settings.MKTG_URLS: # special case for when we only want the root marketing URL if name == 'ROOT': return settings.MKTG_URLS.get('ROOT') return settings.MKTG_URLS.get('ROOT') + settings.MKTG_URLS.get(name) # only link to the old pages when the marketing site isn't on elif not enable_mktg_site and name in link_map: # don't try to reverse disabled marketing links if link_map[name] is not None: return reverse(link_map[name]) else: log.warning("Cannot find corresponding link for name: {name}".format(name=name)) return '#'
def get_university_for_request(): """ Return the university name specified for the domain, or None if no university was specified """ return MicrositeConfiguration.get_microsite_configuration_value( 'university')
def nav_institute_register(request, extra_context=None): """ This view will display the institute registration form """ #if request.user.is_authenticated(): # return redirect(reverse('dashboard')) #if settings.FEATURES.get('AUTH_USE_MIT_CERTIFICATES_IMMEDIATE_SIGNUP'): # Redirect to branding to process their certificate if SSL is enabled # and registration is disabled. # return redirect(reverse('root')) context = { 'course_id': request.GET.get('course_id'), 'enrollment_action': request.GET.get('enrollment_action'), 'platform_name': MicrositeConfiguration.get_microsite_configuration_value( 'platform_name', settings.PLATFORM_NAME ), } if extra_context is not None: context.update(extra_context) #if context.get("extauth_domain", '').startswith(external_auth.views.SHIBBOLETH_DOMAIN_PREFIX): # return render_to_response('register-shib.html', context) return render_to_response('institute_register.html', context)
def render_to_string(template_name, dictionary, context=None, namespace='main'): # see if there is an override template defined in the microsite template_name = MicrositeConfiguration.get_microsite_template_path(template_name) context_instance = Context(dictionary) # add dictionary to context_instance context_instance.update(dictionary or {}) # collapse context_instance to a single dictionary for mako context_dictionary = {} context_instance['settings'] = settings context_instance['EDX_ROOT_URL'] = settings.EDX_ROOT_URL context_instance['marketing_link'] = marketing_link # In various testing contexts, there might not be a current request context. if edxmako.middleware.requestcontext is not None: for d in edxmako.middleware.requestcontext: context_dictionary.update(d) for d in context_instance: context_dictionary.update(d) if context: context_dictionary.update(context) # fetch and render template template = edxmako.lookup[namespace].get_template(template_name) return template.render_unicode(**context_dictionary)
def render_to_string(template_name, dictionary, context=None, namespace='main'): # see if there is an override template defined in the microsite template_name = MicrositeConfiguration.get_microsite_template_path( template_name) context_instance = Context(dictionary) # add dictionary to context_instance context_instance.update(dictionary or {}) # collapse context_instance to a single dictionary for mako context_dictionary = {} context_instance['settings'] = settings context_instance['EDX_ROOT_URL'] = settings.EDX_ROOT_URL context_instance['marketing_link'] = marketing_link # In various testing contexts, there might not be a current request context. if edxmako.middleware.requestcontext is not None: for d in edxmako.middleware.requestcontext: context_dictionary.update(d) for d in context_instance: context_dictionary.update(d) if context: context_dictionary.update(context) # fetch and render template template = lookup_template(namespace, template_name) return template.render_unicode(**context_dictionary)
def settings_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ Course settings for dates and about pages GET html: get the page json: get the CourseDetails model PUT json: update the Course and About xblocks through the CourseDetails model """ locator, course_module = _get_locator_and_course(package_id, branch, version_guid, block, request.user) if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET': upload_asset_url = locator.url_reverse('assets/') # see if the ORG of this course can be attributed to a 'Microsite'. In that case, the # course about page should be editable in Studio about_page_editable = not MicrositeConfiguration.get_microsite_configuration_value_for_org( course_module.location.org, 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)) short_description_editable = settings.FEATURES.get( 'EDITABLE_SHORT_DESCRIPTION', True) return render_to_response( 'settings.html', { 'context_course': course_module, 'course_locator': locator, 'lms_link_for_about_page': utils.get_lms_link_for_about_page(course_module.location), 'course_image_url': utils.course_image_url(course_module), 'details_url': locator.url_reverse('/settings/details/'), 'about_page_editable': about_page_editable, 'short_description_editable': short_description_editable, 'upload_asset_url': upload_asset_url }) elif 'application/json' in request.META.get('HTTP_ACCEPT', ''): if request.method == 'GET': return JsonResponse( CourseDetails.fetch(locator), # encoder serializes dates, old locations, and instances encoder=CourseSettingsEncoder) else: # post or put, doesn't matter. return JsonResponse(CourseDetails.update_from_json( locator, request.json, request.user), encoder=CourseSettingsEncoder)
def refund_cert_callback(sender, course_enrollment=None, **kwargs): """ When a CourseEnrollment object calls its unenroll method, this function checks to see if that unenrollment occurred in a verified certificate that was within the refund deadline. If so, it actually performs the refund. Returns the refunded certificate on a successful refund; else, it returns nothing. """ # Only refund verified cert unenrollments that are within bounds of the expiration date if not course_enrollment.refundable(): return target_certs = CertificateItem.objects.filter( course_id=course_enrollment.course_id, user_id=course_enrollment.user, status='purchased', mode='verified') try: target_cert = target_certs[0] except IndexError: log.error( "Matching CertificateItem not found while trying to refund. User %s, Course %s", course_enrollment.user, course_enrollment.course_id) return target_cert.status = 'refunded' target_cert.refund_requested_time = datetime.now(pytz.utc) target_cert.save() target_cert.order.status = 'refunded' target_cert.order.save() order_number = target_cert.order_id # send billing an email so they can handle refunding subject = _("[Refund] User-Requested Refund") message = "User {user} ({user_email}) has requested a refund on Order #{order_number}.".format( user=course_enrollment.user, user_email=course_enrollment.user.email, order_number=order_number) to_email = [settings.PAYMENT_SUPPORT_EMAIL] from_email = [ MicrositeConfiguration.get_microsite_configuration_value( 'payment_support_email', settings.PAYMENT_SUPPORT_EMAIL) ] try: send_mail(subject, message, from_email, to_email, fail_silently=False) except (smtplib.SMTPException, BotoServerError): err_str = 'Failed sending email to billing request a refund for verified certiciate (User {user}, Course {course}, CourseEnrollmentID {ce_id}, Order #{order})' log.error( err_str.format(user=course_enrollment.user, course=course_enrollment.course_id, ce_id=course_enrollment.id, order=order_number)) return target_cert
def student_approve(request,post_override=None): """ This view will allow the Institute coordinater to approve registered students """ if not request.user.is_authenticated: raise Http404 post_vars = post_override if post_override else request.POST student_id = post_vars['student_id'] status = post_vars['student_status'] try: Student_object = Student_Institute.objects.filter(id=student_id)[0] status_id = int ( Institute_Status.objects.filter(name=status)[0].id ) Student_object.status_id = status_id Student_object.save() except: raise context= { } if status=="Approved" : # composes Approve Student email subject = render_to_string('emails/approve_student_email_subject.txt',context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/approve_student_email_body.txt',context) else : #composes Reject Student email subject = render_to_string('emails/reject_student_email_subject.txt',context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/reject_student_email_body.txt',context) # don't send email if we are doing load testing or random user generation for some reason if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')): from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) try: _res = Student_object.user.email_user(subject, message, from_address) except: log.warning('Unable to send Approve/Reject email to user', exc_info=True) js['value'] = _('Could not send Approve/Reject e-mail.') # What is the correct status code to use here? I think it's 500, because # the problem is on the server's end -- but also, the account was created. # Seems like the core part of the request was successful. return JsonResponse(js, status=500) return HttpResponse(json.dumps({'success': True}))
def render_to_response(template_name, dictionary=None, context_instance=None, namespace='main', **kwargs): """ Returns a HttpResponse whose content is filled with the result of calling lookup.get_template(args[0]).render with the passed arguments. """ # see if there is an override template defined in the microsite template_name = MicrositeConfiguration.get_microsite_template_path(template_name) dictionary = dictionary or {} return HttpResponse(render_to_string(template_name, dictionary, context_instance, namespace), **kwargs)
def get_visible_courses(): """ Return the set of CourseDescriptors that should be visible in this branded instance """ _courses = modulestore().get_courses() courses = [c for c in _courses if isinstance(c, CourseDescriptor)] courses = sorted(courses, key=lambda course: course.number) subdomain = MicrositeConfiguration.get_microsite_configuration_value( 'subdomain', 'default') # See if we have filtered course listings in this domain filtered_visible_ids = None # this is legacy format which is outside of the microsite feature -- also handle dev case, which should not filter if hasattr( settings, 'COURSE_LISTINGS' ) and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG: filtered_visible_ids = frozenset(settings.COURSE_LISTINGS[subdomain]) filtered_by_org = MicrositeConfiguration.get_microsite_configuration_value( 'course_org_filter') if filtered_by_org: return [ course for course in courses if course.location.org == filtered_by_org ] if filtered_visible_ids: return [ course for course in courses if course.id in filtered_visible_ids ] else: # Let's filter out any courses in an "org" that has been declared to be # in a Microsite org_filter_out_set = MicrositeConfiguration.get_all_microsite_orgs() return [ course for course in courses if course.location.org not in org_filter_out_set ]
def safe_get_host(request): """ Get the host name for this request, as safely as possible. If ALLOWED_HOSTS is properly set, this calls request.get_host; otherwise, this returns whatever settings.SITE_NAME is set to. This ensures we will never accept an untrusted value of get_host() """ if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and "*" not in settings.ALLOWED_HOSTS: return request.get_host() else: return MicrositeConfiguration.get_microsite_configuration_value("site_domain", settings.SITE_NAME)
def get_logo_url(): """ Return the url for the branded logo image to be used """ # if the MicrositeConfiguration has a value for the logo_image_url # let's use that image_url = MicrositeConfiguration.get_microsite_configuration_value( 'logo_image_url') if image_url: return '{static_url}{image_url}'.format(static_url=settings.STATIC_URL, image_url=image_url) # otherwise, use the legacy means to configure this university = MicrositeConfiguration.get_microsite_configuration_value( 'university') if university is None: return '{static_url}images/header-logo.png'.format( static_url=settings.STATIC_URL) return '{static_url}images/{uni}-on-edx-logo.png'.format( static_url=settings.STATIC_URL, uni=university)
def safe_get_host(request): """ Get the host name for this request, as safely as possible. If ALLOWED_HOSTS is properly set, this calls request.get_host; otherwise, this returns whatever settings.SITE_NAME is set to. This ensures we will never accept an untrusted value of get_host() """ if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and '*' not in settings.ALLOWED_HOSTS: return request.get_host() else: return MicrositeConfiguration.get_microsite_configuration_value( 'site_domain', settings.SITE_NAME)
def login_page(request): """ Display the login form. """ csrf_token = csrf(request)["csrf_token"] return render_to_response( "login.html", { "csrf": csrf_token, "forgot_password_link": "//{base}/login#forgot-password-modal".format(base=settings.LMS_BASE), "platform_name": MicrositeConfiguration.get_microsite_configuration_value( "platform_name", settings.PLATFORM_NAME ), }, )
def login_page(request): """ Display the login form. """ csrf_token = csrf(request)['csrf_token'] return render_to_response( 'login.html', { 'csrf': csrf_token, 'forgot_password_link': "//{base}/login#forgot-password-modal".format( base=settings.LMS_BASE), 'platform_name': MicrositeConfiguration.get_microsite_configuration_value( 'platform_name', settings.PLATFORM_NAME), })
def settings_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ Course settings for dates and about pages GET html: get the page json: get the CourseDetails model PUT json: update the Course and About xblocks through the CourseDetails model """ locator, course_module = _get_locator_and_course( package_id, branch, version_guid, block, request.user ) if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET': upload_asset_url = locator.url_reverse('assets/') # see if the ORG of this course can be attributed to a 'Microsite'. In that case, the # course about page should be editable in Studio about_page_editable = not MicrositeConfiguration.get_microsite_configuration_value_for_org( course_module.location.org, 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False) ) short_description_editable = settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True) return render_to_response('settings.html', { 'context_course': course_module, 'course_locator': locator, 'lms_link_for_about_page': utils.get_lms_link_for_about_page(course_module.location), 'course_image_url': utils.course_image_url(course_module), 'details_url': locator.url_reverse('/settings/details/'), 'about_page_editable': about_page_editable, 'short_description_editable': short_description_editable, 'upload_asset_url': upload_asset_url }) elif 'application/json' in request.META.get('HTTP_ACCEPT', ''): if request.method == 'GET': return JsonResponse( CourseDetails.fetch(locator), # encoder serializes dates, old locations, and instances encoder=CourseSettingsEncoder ) else: # post or put, doesn't matter. return JsonResponse( CourseDetails.update_from_json(locator, request.json, request.user), encoder=CourseSettingsEncoder )
def refund_cert_callback(sender, course_enrollment=None, **kwargs): """ When a CourseEnrollment object calls its unenroll method, this function checks to see if that unenrollment occurred in a verified certificate that was within the refund deadline. If so, it actually performs the refund. Returns the refunded certificate on a successful refund; else, it returns nothing. """ # Only refund verified cert unenrollments that are within bounds of the expiration date if not course_enrollment.refundable(): return target_certs = CertificateItem.objects.filter(course_id=course_enrollment.course_id, user_id=course_enrollment.user, status='purchased', mode='verified') try: target_cert = target_certs[0] except IndexError: log.error("Matching CertificateItem not found while trying to refund. User %s, Course %s", course_enrollment.user, course_enrollment.course_id) return target_cert.status = 'refunded' target_cert.refund_requested_time = datetime.now(pytz.utc) target_cert.save() target_cert.order.status = 'refunded' target_cert.order.save() order_number = target_cert.order_id # send billing an email so they can handle refunding subject = _("[Refund] User-Requested Refund") message = "User {user} ({user_email}) has requested a refund on Order #{order_number}.".format(user=course_enrollment.user, user_email=course_enrollment.user.email, order_number=order_number) to_email = [settings.PAYMENT_SUPPORT_EMAIL] from_email = [MicrositeConfiguration.get_microsite_configuration_value( 'payment_support_email', settings.PAYMENT_SUPPORT_EMAIL )] try: send_mail(subject, message, from_email, to_email, fail_silently=False) except (smtplib.SMTPException, BotoServerError): err_str = 'Failed sending email to billing request a refund for verified certiciate (User {user}, Course {course}, CourseEnrollmentID {ce_id}, Order #{order})' log.error(err_str.format( user=course_enrollment.user, course=course_enrollment.course_id, ce_id=course_enrollment.id, order=order_number)) return target_cert
def course_about(request, course_id): if MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False) ): raise Http404 course = get_course_with_access(request.user, course_id, 'see_exists') registered = registered_for_course(course, request.user) if has_access(request.user, course, 'load'): course_target = reverse('info', args=[course.id]) else: course_target = reverse('about_course', args=[course.id]) show_courseware_link = (has_access(request.user, course, 'load') or settings.FEATURES.get('ENABLE_LMS_MIGRATION')) # Note: this is a flow for payment for course registration, not the Verified Certificate flow. registration_price = 0 in_cart = False reg_then_add_to_cart_link = "" if (settings.FEATURES.get('ENABLE_SHOPPING_CART') and settings.FEATURES.get('ENABLE_PAID_COURSE_REGISTRATION')): registration_price = CourseMode.min_course_price_for_currency(course_id, settings.PAID_COURSE_REGISTRATION_CURRENCY[0]) if request.user.is_authenticated(): cart = shoppingcart.models.Order.get_cart_for_user(request.user) in_cart = shoppingcart.models.PaidCourseRegistration.contained_in_order(cart, course_id) reg_then_add_to_cart_link = "{reg_url}?course_id={course_id}&enrollment_action=add_to_cart".format( reg_url=reverse('register_user'), course_id=course.id) # see if we have already filled up all allowed enrollments is_course_full = CourseEnrollment.is_course_full(course) return render_to_response('courseware/course_about.html', {'course': course, 'registered': registered, 'course_target': course_target, 'registration_price': registration_price, 'in_cart': in_cart, 'reg_then_add_to_cart_link': reg_then_add_to_cart_link, 'show_courseware_link': show_courseware_link, 'is_course_full': is_course_full})
def course_about(request, course_id): if MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False) ): raise Http404 course = get_course_with_access(request.user, course_id, 'see_exists') registered = registered_for_course(course, request.user) if has_access(request.user, course, 'load'): course_target = reverse('info', args=[course.id]) else: course_target = reverse('about_course', args=[course.id]) show_courseware_link = (has_access(request.user, course, 'load') or settings.FEATURES.get('ENABLE_LMS_MIGRATION')) # Note: this is a flow for payment for course registration, not the Verified Certificate flow. registration_price = 0 in_cart = False reg_then_add_to_cart_link = "" if (settings.FEATURES.get('ENABLE_SHOPPING_CART') and settings.FEATURES.get('ENABLE_PAID_COURSE_REGISTRATION')): registration_price = CourseMode.min_course_price_for_currency(course_id, settings.PAID_COURSE_REGISTRATION_CURRENCY[0]) if request.user.is_authenticated(): cart = shoppingcart.models.Order.get_cart_for_user(request.user) in_cart = shoppingcart.models.PaidCourseRegistration.contained_in_order(cart, course_id) reg_then_add_to_cart_link = "{reg_url}?course_id={course_id}&enrollment_action=add_to_cart".format( reg_url=reverse('register_user'), course_id=course.id) # see if we have already filled up all allowed enrollments is_course_full = CourseEnrollment.is_course_full(course) return render_to_response('courseware/course_about.html', {'course': course, 'registered': registered, 'course_target': course_target, 'registration_price': registration_price, 'in_cart': in_cart, 'reg_then_add_to_cart_link': reg_then_add_to_cart_link, 'show_courseware_link': show_courseware_link, 'is_course_full': is_course_full})
def course_about(request, course_id): if MicrositeConfiguration.get_microsite_configuration_value( "ENABLE_MKTG_SITE", settings.FEATURES.get("ENABLE_MKTG_SITE", False) ): raise Http404 course = get_course_with_access(request.user, course_id, "see_exists") registered = registered_for_course(course, request.user) if has_access(request.user, course, "load"): course_target = reverse("info", args=[course.id]) else: course_target = reverse("about_course", args=[course.id]) show_courseware_link = has_access(request.user, course, "load") or settings.FEATURES.get("ENABLE_LMS_MIGRATION") # Note: this is a flow for payment for course registration, not the Verified Certificate flow. registration_price = 0 in_cart = False reg_then_add_to_cart_link = "" if settings.FEATURES.get("ENABLE_SHOPPING_CART") and settings.FEATURES.get("ENABLE_PAID_COURSE_REGISTRATION"): registration_price = CourseMode.min_course_price_for_currency( course_id, settings.PAID_COURSE_REGISTRATION_CURRENCY[0] ) if request.user.is_authenticated(): cart = shoppingcart.models.Order.get_cart_for_user(request.user) in_cart = shoppingcart.models.PaidCourseRegistration.contained_in_order(cart, course_id) reg_then_add_to_cart_link = "{reg_url}?course_id={course_id}&enrollment_action=add_to_cart".format( reg_url=reverse("register_user"), course_id=course.id ) return render_to_response( "courseware/course_about.html", { "course": course, "registered": registered, "course_target": course_target, "registration_price": registration_price, "in_cart": in_cart, "reg_then_add_to_cart_link": reg_then_add_to_cart_link, "show_courseware_link": show_courseware_link, }, )
def render_to_response(template_name, dictionary=None, context_instance=None, namespace='main', **kwargs): """ Returns a HttpResponse whose content is filled with the result of calling lookup.get_template(args[0]).render with the passed arguments. """ # see if there is an override template defined in the microsite template_name = MicrositeConfiguration.get_microsite_template_path( template_name) dictionary = dictionary or {} return HttpResponse( render_to_string(template_name, dictionary, context_instance, namespace), **kwargs)
def courses(request): """ Render the "find courses" page. If the marketing site is enabled, redirect to that. Otherwise, if subdomain branding is on, this is the university profile page. Otherwise, it's the edX courseware.views.courses page """ enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( 'ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)) if enable_mktg_site: return redirect(marketing_link('COURSES'), permanent=True) if not settings.FEATURES.get('COURSES_ARE_BROWSABLE'): raise Http404 # we do not expect this case to be reached in cases where # marketing is enabled or the courses are not browsable return courseware.views.courses(request)
def courses(request): """ Render the "find courses" page. If the marketing site is enabled, redirect to that. Otherwise, if subdomain branding is on, this is the university profile page. Otherwise, it's the edX courseware.views.courses page """ enable_mktg_site = settings.FEATURES.get( "ENABLE_MKTG_SITE" ) or MicrositeConfiguration.get_microsite_configuration_value("ENABLE_MKTG_SITE", False) if enable_mktg_site: return redirect(marketing_link("COURSES"), permanent=True) if not settings.FEATURES.get("COURSES_ARE_BROWSABLE"): raise Http404 # we do not expect this case to be reached in cases where # marketing is enabled or the courses are not browsable return courseware.views.courses(request)
def ins_selection(request, post_override=None): """ This view allows Student to select Institute in Student Dashboard """ if not request.user.is_authenticated: raise Http404 user = request.user post_vars = post_override if post_override else request.POST institute_id = post_vars['ins_id'] status=Institute_Status.objects.filter(name="Pending")[0].id try: Student_Institute(user=user, institute_id=institute_id,status_id=status).save() except: raise # composes Institute Selection Information Mail subject = render_to_string('emails/select_institute_subject.txt',{}) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/select_institute_body.txt',{}) # don't send email if we are doing load testing or random user generation for some reason if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')): from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) try: ic_role_id = Role.objects.filter(name="Institute Coordinator")[0].id Institute_Designation_object = Institute_Designation.objects.filter(institute_id=institute_id, role_id=ic_role_id)[0] _res = Institute_Designation_object.user.email_user(subject, message, from_address) except: log.warning('Unable to send email to institute coordinator', exc_info=True) js['value'] = _('Could not send e-mail.') # What is the correct status code to use here? I think it's 500, because # the problem is on the server's end -- but also, the account was created. # Seems like the core part of the request was successful. return JsonResponse(js, status=500) return HttpResponse(json.dumps({'success': True}))
def login_page(request): """ Display the login form. """ csrf_token = csrf(request)['csrf_token'] if (settings.FEATURES['AUTH_USE_CERTIFICATES'] and ssl_get_cert_from_request(request)): # SSL login doesn't require a login view, so redirect # to course now that the user is authenticated via # the decorator. return redirect('/course') return render_to_response( 'login.html', { 'csrf': csrf_token, 'forgot_password_link': "//{base}/login#forgot-password-modal".format(base=settings.LMS_BASE), 'platform_name': MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME), } )
def settings_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ Course settings for dates and about pages GET html: get the page json: get the CourseDetails model PUT json: update the Course and About xblocks through the CourseDetails model """ locator, course_module = _get_locator_and_course(package_id, branch, version_guid, block, request.user) if "text/html" in request.META.get("HTTP_ACCEPT", "") and request.method == "GET": upload_asset_url = locator.url_reverse("assets/") # see if the ORG of this course can be attributed to a 'Microsite'. In that case, the # course about page should be editable in Studio about_page_editable = not MicrositeConfiguration.get_microsite_configuration_value_for_org( course_module.location.org, "ENABLE_MKTG_SITE", settings.FEATURES.get("ENABLE_MKTG_SITE", False) ) return render_to_response( "settings.html", { "context_course": course_module, "course_locator": locator, "lms_link_for_about_page": utils.get_lms_link_for_about_page(course_module.location), "course_image_url": utils.course_image_url(course_module), "details_url": locator.url_reverse("/settings/details/"), "about_page_editable": about_page_editable, "upload_asset_url": upload_asset_url, }, ) elif "application/json" in request.META.get("HTTP_ACCEPT", ""): if request.method == "GET": return JsonResponse( CourseDetails.fetch(locator), # encoder serializes dates, old locations, and instances encoder=CourseSettingsEncoder, ) else: # post or put, doesn't matter. return JsonResponse(CourseDetails.update_from_json(locator, request.json), encoder=CourseSettingsEncoder)
def login_page(request): """ Display the login form. """ csrf_token = csrf(request)['csrf_token'] if (settings.FEATURES['AUTH_USE_CERTIFICATES'] and ssl_get_cert_from_request(request)): # SSL login doesn't require a login view, so redirect # to course now that the user is authenticated via # the decorator. return redirect('/course') return render_to_response( 'login.html', { 'csrf': csrf_token, 'forgot_password_link': "//{base}/login#forgot-password-modal".format( base=settings.LMS_BASE), 'platform_name': MicrositeConfiguration.get_microsite_configuration_value( 'platform_name', settings.PLATFORM_NAME), })
def ins_approve(request, post_override=None): """ This view will allow the central coordinater to approve registered institutes """ if not request.user.is_authenticated: raise Http404 post_vars = post_override if post_override else request.POST institute_id = post_vars['ins_id'] status = post_vars['ins_status'] initialize(institute_id) try: Institute_object = Institute_Registration.objects.filter(id=institute_id)[0] status_id = int ( Institute_Status.objects.filter(name=status)[0].id ) Institute_object.status_id = status_id Institute_object.save() except: raise try: ic_role_id = Role.objects.filter(name="Institute Coordinator")[0].id Institute_Designation_object = Institute_Designation.objects.filter(institute_id=institute_id, role_id=ic_role_id)[0] except: raise try: Password = uuid.uuid4().hex[0:10] Institute_Designation_object.user.set_password(Password) Institute_Designation_object.user.is_active=1 Institute_Designation_object.user.save() except: raise if status=="Approved" : context= { "Email" : Institute_Designation_object.user.email, "Password" : Password } # composes Approve Institute email subject = render_to_string('emails/approve_institute_email_subject.txt',context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/approve_institute_email_body.txt',context) else : context= {} #composes Reject Institute email subject = render_to_string('emails/reject_institute_email_subject.txt',context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/reject_institute_email_body.txt',context) # don't send email if we are doing load testing or random user generation for some reason if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')): from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) try: _res = Institute_Designation_object.user.email_user(subject, message, from_address) except: log.warning('Unable to send Approve/Reject email to institute', exc_info=True) js['value'] = _('Could not send Approve/Reject e-mail.') # What is the correct status code to use here? I think it's 500, because # the problem is on the server's end -- but also, the account was created. # Seems like the core part of the request was successful. return JsonResponse(js, status=500) return HttpResponse(json.dumps({'success': True}))
def platform_name(): """ Django template tag that outputs the current platform name: {% platform_name %} """ return MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME)
def send_mail_to_student(student, param_dict): """ Construct the email using templates and then send it. `student` is the student's email address (a `str`), `param_dict` is a `dict` with keys [ `site_name`: name given to edX instance (a `str`) `registration_url`: url for registration (a `str`) `course_id`: id of course (a `str`) `auto_enroll`: user input option (a `str`) `course_url`: url of course (a `str`) `email_address`: email of student (a `str`) `full_name`: student full name (a `str`) `message`: type of email to send and template to use (a `str`) `is_shib_course`: (a `boolean`) ] Returns a boolean indicating whether the email was sent successfully. """ # add some helpers and microconfig subsitutions if 'course' in param_dict: param_dict['course_name'] = param_dict['course'].display_name_with_default param_dict['site_name'] = MicrositeConfiguration.get_microsite_configuration_value( 'SITE_NAME', param_dict['site_name'] ) subject = None message = None # see if we are running in a microsite and that there is an # activation email template definition available as configuration, if so, then render that message_type = param_dict['message'] email_template_dict = { 'allowed_enroll': ( 'emails/enroll_email_allowedsubject.txt', 'emails/enroll_email_allowedmessage.txt' ), 'enrolled_enroll': ( 'emails/enroll_email_enrolledsubject.txt', 'emails/enroll_email_enrolledmessage.txt' ), 'allowed_unenroll': ( 'emails/unenroll_email_subject.txt', 'emails/unenroll_email_allowedmessage.txt' ), 'enrolled_unenroll': ( 'emails/unenroll_email_subject.txt', 'emails/unenroll_email_enrolledmessage.txt' ) } subject_template, message_template = email_template_dict.get(message_type, (None, None)) if subject_template is not None and message_template is not None: subject = render_to_string(subject_template, param_dict) message = render_to_string(message_template, param_dict) if subject and message: # Remove leading and trailing whitespace from body message = message.strip() # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) send_mail(subject, message, from_address, [student], fail_silently=False)
def get_university_for_request(): """ Return the university name specified for the domain, or None if no university was specified """ return MicrositeConfiguration.get_microsite_configuration_value('university')
def purchase(self, first='', last='', street1='', street2='', city='', state='', postalcode='', country='', ccnum='', cardtype='', processor_reply_dump=''): """ Call to mark this order as purchased. Iterates through its OrderItems and calls their purchased_callback `first` - first name of person billed (e.g. John) `last` - last name of person billed (e.g. Smith) `street1` - first line of a street address of the billing address (e.g. 11 Cambridge Center) `street2` - second line of a street address of the billing address (e.g. Suite 101) `city` - city of the billing address (e.g. Cambridge) `state` - code of the state, province, or territory of the billing address (e.g. MA) `postalcode` - postal code of the billing address (e.g. 02142) `country` - country code of the billing address (e.g. US) `ccnum` - last 4 digits of the credit card number of the credit card billed (e.g. 1111) `cardtype` - 3-digit code representing the card type used (e.g. 001) `processor_reply_dump` - all the parameters returned by the processor """ if self.status == 'purchased': return self.status = 'purchased' self.purchase_time = datetime.now(pytz.utc) self.bill_to_first = first self.bill_to_last = last self.bill_to_city = city self.bill_to_state = state self.bill_to_country = country self.bill_to_postalcode = postalcode if settings.FEATURES['STORE_BILLING_INFO']: self.bill_to_street1 = street1 self.bill_to_street2 = street2 self.bill_to_ccnum = ccnum self.bill_to_cardtype = cardtype self.processor_reply_dump = processor_reply_dump # save these changes on the order, then we can tell when we are in an # inconsistent state self.save() # this should return all of the objects with the correct types of the # subclasses orderitems = OrderItem.objects.filter(order=self).select_subclasses() for item in orderitems: item.purchase_item() # send confirmation e-mail subject = _("Order Payment Confirmation") message = render_to_string( 'emails/order_confirmation_email.txt', { 'order': self, 'order_items': orderitems, 'has_billing_info': settings.FEATURES['STORE_BILLING_INFO'] } ) try: from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) send_mail(subject, message, from_address, [self.user.email]) # pylint: disable=E1101 except (smtplib.SMTPException, BotoServerError): # sadly need to handle diff. mail backends individually log.error('Failed sending confirmation e-mail for order %d', self.id) # pylint: disable=E1101
def register_institute(request, post_override=None): """ JSON call to create new institute. """ js = {'success': False} post_vars = post_override if post_override else request.POST extra_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {}) for a in ['name', 'state', 'city']: if a not in post_vars: js['value'] = _("Error (401 {field}). E-mail us.").format(field=a) js['field'] = a return JsonResponse(js, status=400) required_post_vars = ['name', 'state', 'city', 'pincode', 'address', 'website', 'headName', 'headEmail', 'headMobile', 'rccName', 'rccEmail', 'rccMobile', 'studentIdentity'] for field_name in required_post_vars: if field_name in ('state', 'city'): min_length = 1 else: min_length = 2 if len(post_vars[field_name]) < min_length: error_str = { 'name': _('Name must be minimum of two characters long'), 'state': _('A state is required'), 'address': _('Your address is required'), 'city': _('A city is required'), 'pincode' : _('Your Pincode is required'), 'website' : _('Your website is required'), 'headName' : _('Head Name must be minimum of two characters long'), 'headEmail' : _('A properly formatted e-mail is required'), 'headMobile' : _('Head Mobile must be of 10 digits'), 'rccName' : _('RCC Name must be minimum of two characters long'), 'rccEmail' : _('A properly formatted e-mail is required'), 'rccMobile' : _('RCC Mobile must be of 10 digits'), 'honor_code': _('Agreeing to the Honor Code is required'), 'terms_of_service': _('Accepting Terms of Service is required') } js['value'] = error_str[field_name] js['field'] = field_name return JsonResponse(js, status=400) try: validate_email(post_vars['headEmail']) except ValidationError: js['value'] = _("Valid e-mail is required.").format(field=a) js['field'] = 'email' return JsonResponse(js, status=400) try: validate_email(post_vars['rccEmail']) except ValidationError: js['value'] = _("Valid e-mail is required.").format(field=a) js['field'] = 'email' return JsonResponse(js, status=400) if extra_fields.get('honor_code', 'required') == 'required' and \ post_vars.get('honor_code', 'false') != u'true': js['value'] = _("To enroll, you must follow the honor code.").format(field=a) js['field'] = 'honor_code' return JsonResponse(js, status=400) if extra_fields.get('terms_of_service', 'required') == 'required' and \ post_vars.get('terms_of_service', 'false') != u'true': js['value'] = _("To enroll, you must accept terms of service.").format(field=a) js['field'] = 'terms_of_service' return JsonResponse(js, status=400) status=Institute_Status.objects.filter(name="Pending")[0].id institute = Institute_Registration( name=post_vars['name'], state_id=post_vars['state'], city_id=post_vars['city'], pincode=post_vars['pincode'], status_id=status, is_parent=False, address=post_vars['address'], website=post_vars['website']) if post_vars['headEmail'] == post_vars['rccEmail']: js['value'] = _("Please provide different emails for Head and Coordinator").format(email=post_vars['headEmail']) js['field'] = 'email' return JsonResponse(js,status=400) if len(User.objects.filter(email=str(post_vars['headEmail']))) > 0: js = {'success': False} js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['headEmail']) js['field'] = 'email' return JsonResponse(js,status=400) if len(User.objects.filter(email=str(post_vars['rccEmail']))) > 0: js = {'success': False} js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['rccEmail']) js['field'] = 'email' return JsonResponse(js,status=400) try: institute.save() except IntegrityError as e: js = {'success': False} if len(Institute_Registration.objects.filter(name=post_vars['name'])) > 0: js['value'] = _("An Institute with the name '{name}' already exists.").format(name=post_vars['name']) js['field'] = 'name' return JsonResponse(js,status=400) insti_id= institute.id accreditation = request.POST.getlist('accreditation') for index in accreditation: acc = Institute_Accreditation(accreditation_id=index , institute_id=insti_id) acc.save() headUsername = post_vars['headEmail'].split('@') headUsername = GenerateUsername(headUsername[0]) headPass = uuid.uuid4().hex[0:10] user = User(username=headUsername, email=post_vars['headEmail'], is_active=False) user.set_password(headPass) try: user.save() head_user_object = user except IntegrityError as e: js = {'success': False} # Figure out the cause of the integrity error if len(User.objects.filter(email=post_vars['headEmail'])) > 0: js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['headEmail']) js['field'] = 'email' return JsonResponse(js,status=400) profile = UserProfile(user=user) profile.name = post_vars['headName'] profile.year_of_birth = None person = Person(user=user) person.mobile = post_vars.get('headMobile') person.save() try: profile.save() except Exception: log.exception("UserProfile creation failed for user {id}.".format(id=user.id)) head_role_id = Role.objects.filter(name="Institute Head")[0].id designation = Institute_Designation(user=user, institute_id=insti_id, role_id=head_role_id, is_approved=False) designation.save() rccUsername = post_vars['rccEmail'].split('@') rccUsername = GenerateUsername(rccUsername[0]) rccPass = uuid.uuid4().hex[0:10] user = User(username=rccUsername, email=post_vars['rccEmail'], is_active=False) user.set_password(rccPass) try: user.save() rcc_user_object = user except IntegrityError as e: js = {'success': False} # Figure out the cause of the integrity error if len(User.objects.filter(email=post_vars['rccEmail'])) > 0: js['value'] = _("An account with the Email '{email}' already exists.").format(email=post_vars['rccEmail']) js['field'] = 'email' return JsonResponse(js,status=400) profile = UserProfile(user=user) profile.name = post_vars['rccName'] profile.year_of_birth = None person = Person(user=user) person.mobile = post_vars.get('rccMobile') person.save() try: profile.save() except Exception: log.exception("UserProfile creation failed for user {id}.".format(id=user.id)) ic_role_id = Role.objects.filter(name="Institute Coordinator")[0].id designation = Institute_Designation(user=user, institute_id=insti_id, role_id=ic_role_id, is_approved=False) designation.save() #identity_name = post_vars.get('studentIdentity') # student_identity = Identity(name=identity_name) # student_identity.save() # institute_id = Institute_Registration.objects.filter(name=post_vars.get('name'))[0].id #identity_id = Identity.objects.filter(name=identity_name)[0].id #institute_identity = Institute_Identity(institute_id=institute_id, identity_id=identity_id) #institute_identity.save() ''' context = {'name': "test",} # composes thank you email subject = render_to_string('emails/thankyou_email_subject.txt',context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('emails/thankyou_email_body.txt',context) # don't send email if we are doing load testing or random user generation for some reason if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')): from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL ) try: if settings.FEATURES.get('REROUTE_ACTIVATION_EMAIL'): dest_addr = settings.FEATURES['REROUTE_ACTIVATION_EMAIL'] message = ("Thank you for mail %s (%s):\n" % (head_user_object, head_user_object.email) + '-' * 80 + '\n\n' + message) send_mail(subject, message, from_address, [dest_addr], fail_silently=False) else: _res = head_user_object.email_user(subject, message, from_address) _res1 = rcc_user_object.email_user(subject, message, from_address) except: log.warning('Unable to send thank you email to user', exc_info=True) js['value'] = _('Could not send thank you e-mail.') # What is the correct status code to use here? I think it's 500, because # the problem is on the server's end -- but also, the account was created. # Seems like the core part of the request was successful. return JsonResponse(js, status=500) return JsonResponse({'success': True,})
def purchase(self, first='', last='', street1='', street2='', city='', state='', postalcode='', country='', ccnum='', cardtype='', processor_reply_dump=''): """ Call to mark this order as purchased. Iterates through its OrderItems and calls their purchased_callback `first` - first name of person billed (e.g. John) `last` - last name of person billed (e.g. Smith) `street1` - first line of a street address of the billing address (e.g. 11 Cambridge Center) `street2` - second line of a street address of the billing address (e.g. Suite 101) `city` - city of the billing address (e.g. Cambridge) `state` - code of the state, province, or territory of the billing address (e.g. MA) `postalcode` - postal code of the billing address (e.g. 02142) `country` - country code of the billing address (e.g. US) `ccnum` - last 4 digits of the credit card number of the credit card billed (e.g. 1111) `cardtype` - 3-digit code representing the card type used (e.g. 001) `processor_reply_dump` - all the parameters returned by the processor """ if self.status == 'purchased': return self.status = 'purchased' self.purchase_time = datetime.now(pytz.utc) self.bill_to_first = first self.bill_to_last = last self.bill_to_city = city self.bill_to_state = state self.bill_to_country = country self.bill_to_postalcode = postalcode if settings.FEATURES['STORE_BILLING_INFO']: self.bill_to_street1 = street1 self.bill_to_street2 = street2 self.bill_to_ccnum = ccnum self.bill_to_cardtype = cardtype self.processor_reply_dump = processor_reply_dump # save these changes on the order, then we can tell when we are in an # inconsistent state self.save() # this should return all of the objects with the correct types of the # subclasses orderitems = OrderItem.objects.filter(order=self).select_subclasses() for item in orderitems: item.purchase_item() # send confirmation e-mail subject = _("Order Payment Confirmation") message = render_to_string( 'emails/order_confirmation_email.txt', { 'order': self, 'order_items': orderitems, 'has_billing_info': settings.FEATURES['STORE_BILLING_INFO'] }) try: from_address = MicrositeConfiguration.get_microsite_configuration_value( 'email_from_address', settings.DEFAULT_FROM_EMAIL) send_mail(subject, message, from_address, [self.user.email]) # pylint: disable=E1101 except (smtplib.SMTPException, BotoServerError ): # sadly need to handle diff. mail backends individually log.error('Failed sending confirmation e-mail for order %d', self.id) # pylint: disable=E1101