Beispiel #1
0
def login_refresh(request):  # lint-amnesty, pylint: disable=missing-function-docstring
    if not request.user.is_authenticated or request.user.is_anonymous:
        return JsonResponse('Unauthorized', status=401)

    try:
        return get_response_with_refreshed_jwt_cookies(request, request.user)
    except AuthFailedError as error:
        log.exception(error.get_response())
        return JsonResponse(error.get_response(), status=400)
Beispiel #2
0
 def get(self, request, username_or_email):
     try:
         user = User.objects.get(
             Q(username=username_or_email) | Q(email=username_or_email))
     except User.DoesNotExist:
         return JsonResponse([])
     user_social_auths = UserSocialAuth.objects.filter(user=user)
     sso_records = serialize_sso_records(user_social_auths)
     return JsonResponse(sso_records)
Beispiel #3
0
 def get(self, request, username_or_email):  # lint-amnesty, pylint: disable=missing-function-docstring
     try:
         user = User.objects.get(
             Q(username=username_or_email) | Q(email=username_or_email))
     except User.DoesNotExist:
         return JsonResponse([])
     user_social_auths = UserSocialAuth.objects.filter(user=user)
     sso_records = serialize_sso_records(user_social_auths)
     return JsonResponse(sso_records)
Beispiel #4
0
def login_refresh(request):
    if not request.user.is_authenticated or request.user.is_anonymous:
        return JsonResponse('Unauthorized', status=401)

    try:
        return get_response_with_refreshed_jwt_cookies(request, request.user)
    except AuthFailedError as error:
        log.exception(error.get_response())
        return JsonResponse(error.get_response(), status=400)
Beispiel #5
0
def transcript_upload_handler(request):
    """
    View to upload a transcript file.

    Arguments:
        request: A WSGI request object

    Transcript file, edx video id and transcript language are required.
    Transcript file should be in SRT(SubRip) format.

    Returns
        - A 400 if any of the validation fails
        - A 200 if transcript has been uploaded successfully
    """
    error = validate_transcript_upload_data(data=request.POST,
                                            files=request.FILES)
    if error:
        response = JsonResponse({'error': error}, status=400)
    else:
        edx_video_id = request.POST['edx_video_id']
        language_code = request.POST['language_code']
        new_language_code = request.POST['new_language_code']
        transcript_file = request.FILES['file']
        try:
            # Convert SRT transcript into an SJSON format
            # and upload it to S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read().decode('utf-8'),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON).encode()
            create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=language_code,
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': new_language_code
                },
                file_data=ContentFile(sjson_subs),
            )
            response = JsonResponse(status=201)
        except (TranscriptsGenerationException, UnicodeDecodeError):
            response = JsonResponse(
                {
                    'error':
                    _(u'There is a problem with this transcript file. Try to upload a different file.'
                      )
                },
                status=400)

    return response
 def get(self, request, number):
     """ HTTP handler. """
     # If the account activation requirement is disabled for this installation, override the
     # anonymous user object attached to the request with the actual user object (if it exists)
     if not request.user.is_authenticated and is_account_activation_requirement_disabled():
         try:
             request.user = User.objects.get(id=request.session._session_cache['_auth_user_id'])  # lint-amnesty, pylint: disable=protected-access
         except User.DoesNotExist:
             return JsonResponse(status=403)
     try:
         order = ecommerce_api_client(request.user).orders(number).get()
         return JsonResponse(order)
     except exceptions.HttpNotFoundError:
         return JsonResponse(status=404)
Beispiel #7
0
def _update_pagination_context(request):
    """
    Updates session with posted value
    """
    error_msg = _(u'A non zero positive integer is expected')
    try:
        videos_per_page = int(request.POST.get('value'))
        if videos_per_page <= 0:
            return JsonResponse({'error': error_msg}, status=500)
    except ValueError:
        return JsonResponse({'error': error_msg}, status=500)

    request.session['VIDEOS_PER_PAGE'] = videos_per_page
    return JsonResponse()
Beispiel #8
0
 def get(self, request, username_or_email):
     """
     Returns details for the given user, along with
     information about its username and joining date.
     """
     try:
         user = get_user_model().objects.get(
             Q(username=username_or_email) | Q(email=username_or_email)
         )
         data = AccountUserSerializer(user, context={'request': request}).data
         data['status'] = _('Usable') if user.has_usable_password() else _('Unusable')
         return JsonResponse(data)
     except get_user_model().DoesNotExist:
         return JsonResponse([])
Beispiel #9
0
 def get(self, request, *_args, **kwargs):
     """
     HTTP handler.
     """
     try:
         api_url = urljoin(f"{get_ecommerce_api_base_url()}/",
                           f"baskets/{kwargs['basket_id']}/order/")
         response = get_ecommerce_api_client(request.user).get(api_url)
         response.raise_for_status()
         return JsonResponse(response.json())
     except HTTPError as err:
         if err.response.status_code == 404:
             return JsonResponse(status=404)
         raise
Beispiel #10
0
def password_reset(request):
    """
    Attempts to send a password reset e-mail.
    """
    user = request.user
    # Prefer logged-in user's email
    email = user.email if user.is_authenticated else request.POST.get('email')
    AUDIT_LOG.info("Password reset initiated for email %s.", email)

    if getattr(request, 'limited', False):
        AUDIT_LOG.warning("Password reset rate limit exceeded for email %s.",
                          email)
        return JsonResponse(
            {
                'success':
                False,
                'value':
                _("Your previous request is in progress, please try again in a few moments."
                  )
            },
            status=403)

    form = PasswordResetFormNoActive(request.POST)
    if form.is_valid():
        form.save(use_https=request.is_secure(),
                  from_email=configuration_helpers.get_value(
                      'email_from_address', settings.DEFAULT_FROM_EMAIL),
                  request=request)
        # When password change is complete, a "edx.user.settings.changed" event will be emitted.
        # But because changing the password is multi-step, we also emit an event here so that we can
        # track where the request was initiated.
        tracker.emit(
            SETTING_CHANGE_INITIATED, {
                "setting": "password",
                "old": None,
                "new": None,
                "user_id": request.user.id,
            })
        destroy_oauth_tokens(request.user)
    else:
        # bad user? tick the rate limiter counter
        AUDIT_LOG.info("Bad password_reset user passed in.")

    return JsonResponse({
        'success':
        True,
        'value':
        render_to_string('registration/password_reset_done.html', {}),
    })
Beispiel #11
0
def reorder_tabs_handler(course_item, request):
    """
    Helper function for handling reorder of tabs request
    """

    # Tabs are identified by tab_id or locators.
    # The locators are used to identify static tabs since they are xmodules.
    # Although all tabs have tab_ids, newly created static tabs do not know
    # their tab_ids since the xmodule editor uses only locators to identify new objects.
    requested_tab_id_locators = request.json['tabs']

    # original tab list in original order
    old_tab_list = course_item.tabs

    # create a new list in the new order
    new_tab_list = []
    for tab_id_locator in requested_tab_id_locators:
        tab = get_tab_by_tab_id_locator(old_tab_list, tab_id_locator)
        if tab is None:
            return JsonResponse(
                {
                    "error":
                    u"Tab with id_locator '{0}' does not exist.".format(
                        tab_id_locator)
                },
                status=400)
        new_tab_list.append(tab)

    # the old_tab_list may contain additional tabs that were not rendered in the UI because of
    # global or course settings.  so add those to the end of the list.
    non_displayed_tabs = set(old_tab_list) - set(new_tab_list)
    new_tab_list.extend(non_displayed_tabs)

    # validate the tabs to make sure everything is Ok (e.g., did the client try to reorder unmovable tabs?)
    try:
        CourseTabList.validate_tabs(new_tab_list)
    except InvalidTabsException as exception:
        return JsonResponse(
            {
                "error":
                u"New list of tabs is not valid: {0}.".format(str(exception))
            },
            status=400)

    # persist the new order of the tabs
    course_item.tabs = new_tab_list
    modulestore().update_item(course_item, request.user.id)

    return JsonResponse()
Beispiel #12
0
def disable_account_ajax(request):
    """
    Ajax call to change user standing. Endpoint of the form
    in manage_user_standing.html
    """
    if not request.user.is_staff:
        raise Http404
    username = request.POST.get('username')
    context = {}
    if username is None or username.strip() == '':
        context['message'] = _('Please enter a username')
        return JsonResponse(context, status=400)

    account_action = request.POST.get('account_action')
    if account_action is None:
        context['message'] = _('Please choose an option')
        return JsonResponse(context, status=400)

    username = username.strip()
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        context['message'] = _("User with username {} does not exist").format(
            username)
        return JsonResponse(context, status=400)
    else:
        user_account, _success = UserStanding.objects.get_or_create(
            user=user,
            defaults={'changed_by': request.user},
        )
        if account_action == 'disable':
            user_account.account_status = UserStanding.ACCOUNT_DISABLED
            context['message'] = _(
                "Successfully disabled {}'s account").format(username)
            log.info(u"%s disabled %s's account", request.user, username)
        elif account_action == 'reenable':
            user_account.account_status = UserStanding.ACCOUNT_ENABLED
            context['message'] = _(
                "Successfully reenabled {}'s account").format(username)
            log.info(u"%s reenabled %s's account", request.user, username)
        else:
            context['message'] = _("Unexpected account status")
            return JsonResponse(context, status=400)
        user_account.changed_by = request.user
        user_account.standing_last_changed_at = datetime.datetime.now(UTC)
        user_account.save()

    return JsonResponse(context)
Beispiel #13
0
def transcript_credentials_handler(request, course_key_string):
    """
    JSON view handler to update the transcript organization credentials.

    Arguments:
        request: WSGI request object
        course_key_string: A course identifier to extract the org.

    Returns:
        - A 200 response if credentials are valid and successfully updated in edx-video-pipeline.
        - A 404 response if transcript feature is not enabled for this course.
        - A 400 if credentials do not pass validations, hence not updated in edx-video-pipeline.
    """
    course_key = CourseKey.from_string(course_key_string)
    if not VideoTranscriptEnabledFlag.feature_enabled(course_key):
        return HttpResponseNotFound()

    provider = request.json.pop('provider')
    error_message, validated_credentials = validate_transcript_credentials(
        provider=provider, **request.json)
    if error_message:
        response = JsonResponse({'error': error_message}, status=400)
    else:
        # Send the validated credentials to edx-video-pipeline and video-encode-manager
        credentials_payload = dict(validated_credentials,
                                   org=course_key.org,
                                   provider=provider)
        error_response, is_updated = update_3rd_party_transcription_service_credentials(
            **credentials_payload)
        # Send appropriate response based on whether credentials were updated or not.
        if is_updated:
            # Cache credentials state in edx-val.
            update_transcript_credentials_state_for_org(org=course_key.org,
                                                        provider=provider,
                                                        exists=is_updated)
            response = JsonResponse(status=200)
        else:
            # Error response would contain error types and the following
            # error type is received from edx-video-pipeline whenever we've
            # got invalid credentials for a provider. Its kept this way because
            # edx-video-pipeline doesn't support i18n translations yet.
            error_type = error_response.get('error_type')
            if error_type == TranscriptionProviderErrorType.INVALID_CREDENTIALS:
                error_message = _('The information you entered is incorrect.')

            response = JsonResponse({'error': error_message}, status=400)

    return response
Beispiel #14
0
def certificate_activation_handler(request, course_key_string):
    """
    A handler for Certificate Activation/Deactivation

    POST
        json: is_active. update the activation state of certificate
    """
    course_key = CourseKey.from_string(course_key_string)
    store = modulestore()
    try:
        course = _get_course_and_check_access(course_key, request.user)
    except PermissionDenied:
        msg = _('PermissionDenied: Failed in authenticating {user}').format(user=request.user)
        return JsonResponse({"error": msg}, status=403)

    data = json.loads(request.body.decode('utf8'))
    is_active = data.get('is_active', False)
    certificates = CertificateManager.get_certificates(course)

    # for certificate activation/deactivation, we are assuming one certificate in certificates collection.
    for certificate in certificates:
        certificate['is_active'] = is_active
        break

    store.update_item(course, request.user.id)
    cert_event_type = 'activated' if is_active else 'deactivated'
    CertificateManager.track_event(cert_event_type, {
        'course_id': str(course.id),
    })
    return HttpResponse(status=200)
Beispiel #15
0
    def post(self, request, username_or_email):
        """Allows support staff to disable a user's account."""
        user = get_user_model().objects.get(
            Q(username=username_or_email) | Q(email=username_or_email)
        )
        comment = request.data.get("comment")
        if user.has_usable_password():
            user.set_unusable_password()
            UserPasswordToggleHistory.objects.create(
                user=user, comment=comment, created_by=request.user, disabled=True
            )
        else:
            user.set_password(generate_password(length=25))
            UserPasswordToggleHistory.objects.create(
                user=user, comment=comment, created_by=request.user, disabled=False
            )
        user.save()

        if user.has_usable_password():
            password_status = _('Usable')
            msg = _('User Enabled Successfully')
        else:
            password_status = _('Unusable')
            msg = _('User Disabled Successfully')
        return JsonResponse({'success_msg': msg, 'status': password_status})
def cohorting_settings(request, course_key_string):
    """
    The handler for verified track cohorting requests.
    This will raise 404 if user is not staff.

    Returns a JSON representation of whether or not the course has verified track cohorting enabled.
    The "verified_cohort_name" field will only be present if "enabled" is True.

    Example:
        >>> example = {
        >>>               "enabled": True,
        >>>               "verified_cohort_name" : "Micromasters"
        >>>           }
    """
    course_key = CourseKey.from_string(course_key_string)
    get_course_with_access(request.user, 'staff', course_key)

    settings = {}
    verified_track_cohort_enabled = VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(
        course_key)
    settings['enabled'] = verified_track_cohort_enabled
    if verified_track_cohort_enabled:
        settings[
            'verified_cohort_name'] = VerifiedTrackCohortedCourse.verified_cohort_name_for_course(
                course_key)

    return JsonResponse(settings)
Beispiel #17
0
    def get(self, request, course_id):
        """
        Returns the duration config information if FBE is enabled. If
        FBE is not enabled, empty dict is returned.

        * Example Request:
            - GET /support/feature_based_enrollment_details/<course_id>

        * Example Response:
            {
              "course_id": <course_id>,
              "course_name": "FBE course",
              "gating_config": {
                "enabled": true,
                "enabled_as_of": "2030-01-01 00:00:00+00:00",
                "reason": "Site"
              },
              "duration_config": {
                "enabled": true,
                "enabled_as_of": "2030-01-01 00:00:00+00:00",
                "reason": "Site"
              }
            }
        """
        return JsonResponse(get_course_duration_info(course_id))
Beispiel #18
0
 def render_response(self):
     """
     A short method to render_to_response that renders response.
     """
     if self.request.is_ajax():
         return JsonResponse(self.context)
     return render_to_response(self.template, self.context)
Beispiel #19
0
 def test_get_sailthru_list_map_no_list(self, mock_sailthru_client):
     """Test when no list returned from sailthru"""
     mock_sailthru_client.api_get.return_value = SailthruResponse(
         JsonResponse({'lists': []}))
     self.assertEqual(
         _get_list_from_email_marketing_provider(mock_sailthru_client), {})
     mock_sailthru_client.api_get.assert_called_with("list", {})
Beispiel #20
0
 def test_dict(self):
     obj = {"foo": "bar"}
     resp = JsonResponse(obj)
     compare = json.loads(resp.content.decode('utf-8'))
     self.assertEqual(obj, compare)
     self.assertEqual(resp.status_code, 200)
     self.assertEqual(resp["content-type"], "application/json")
Beispiel #21
0
 def test_set_status_arg(self):
     obj = {"error": "resource not found"}
     resp = JsonResponse(obj, 404)
     compare = json.loads(resp.content.decode('utf-8'))
     self.assertEqual(obj, compare)
     self.assertEqual(resp.status_code, 404)
     self.assertEqual(resp["content-type"], "application/json")
Beispiel #22
0
def _list_libraries(request):
    """
    List all accessible libraries, after applying filters in the request
    Query params:
        org - The organization used to filter libraries
        text_search - The string used to filter libraries by searching in title, id or org
    """
    org = request.GET.get('org', '')
    text_search = request.GET.get('text_search', '').lower()

    if org:
        libraries = modulestore().get_libraries(org=org)
    else:
        libraries = modulestore().get_libraries()

    lib_info = [
        {
            "display_name": lib.display_name,
            "library_key": str(lib.location.library_key),
        }
        for lib in libraries
        if (
            (
                text_search in lib.display_name.lower() or
                text_search in lib.location.library_key.org.lower() or
                text_search in lib.location.library_key.library.lower()
            ) and
            has_studio_read_access(request.user, lib.location.library_key)
        )
    ]
    return JsonResponse(lib_info)
Beispiel #23
0
 def test_set_status_arg(self):
     obj = {"error": "resource not found"}
     resp = JsonResponse(obj, 404)
     compare = json.loads(resp.content.decode('utf-8'))
     assert obj == compare
     assert resp.status_code == 404
     assert resp['content-type'] == 'application/json'
Beispiel #24
0
 def test_dict(self):
     obj = {"foo": "bar"}
     resp = JsonResponse(obj)
     compare = json.loads(resp.content.decode('utf-8'))
     assert obj == compare
     assert resp.status_code == 200
     assert resp['content-type'] == 'application/json'
Beispiel #25
0
 def post(self, request, username_or_email):
     """Allows support staff to alter a user's enrollment."""
     try:
         user = User.objects.get(
             Q(username=username_or_email) | Q(email=username_or_email))
         course_id = request.data['course_id']
         course_key = CourseKey.from_string(course_id)
         old_mode = request.data['old_mode']
         new_mode = request.data['new_mode']
         reason = request.data['reason']
         enrollment = CourseEnrollment.objects.get(user=user,
                                                   course_id=course_key)
         if enrollment.mode != old_mode:
             return HttpResponseBadRequest(
                 'User {username} is not enrolled with mode {old_mode}.'.
                 format(username=user.username, old_mode=old_mode))
     except KeyError as err:
         return HttpResponseBadRequest('The field {} is required.'.format(
             str(err)))
     except InvalidKeyError:
         return HttpResponseBadRequest('Could not parse course key.')
     except (CourseEnrollment.DoesNotExist, User.DoesNotExist):
         return HttpResponseBadRequest(
             'Could not find enrollment for user {username} in course {course}.'
             .format(username=username_or_email, course=str(course_key)))
     try:
         # Wrapped in a transaction so that we can be sure the
         # ManualEnrollmentAudit record is always created correctly.
         with transaction.atomic():
             update_enrollment(user.username,
                               course_id,
                               mode=new_mode,
                               include_expired=True)
             manual_enrollment = ManualEnrollmentAudit.create_manual_enrollment_audit(
                 request.user,
                 enrollment.user.email,
                 ENROLLED_TO_ENROLLED,
                 reason=reason,
                 enrollment=enrollment)
             if new_mode == CourseMode.CREDIT_MODE:
                 provider_ids = get_credit_provider_attribute_values(
                     course_key, 'id')
                 credit_provider_attr = {
                     'namespace': 'credit',
                     'name': 'provider_id',
                     'value': provider_ids[0],
                 }
                 CourseEnrollmentAttribute.add_enrollment_attr(
                     enrollment=enrollment,
                     data_list=[credit_provider_attr])
             entitlement = CourseEntitlement.get_fulfillable_entitlement_for_user_course_run(
                 user=user, course_run_key=course_id)
             if entitlement is not None and entitlement.mode == new_mode:
                 entitlement.set_enrollment(
                     CourseEnrollment.get_enrollment(user, course_id))
             return JsonResponse(
                 ManualEnrollmentSerializer(
                     instance=manual_enrollment).data)
     except CourseModeNotFoundError as err:
         return HttpResponseBadRequest(str(err))
Beispiel #26
0
def edxnotes_visibility(request, course_id):
    """
    Handle ajax call from "Show notes" checkbox.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)
    field_data_cache = FieldDataCache([course], course_key, request.user)
    course_module = get_module_for_descriptor(request.user,
                                              request,
                                              course,
                                              field_data_cache,
                                              course_key,
                                              course=course)

    if not is_feature_enabled(course, request.user):
        raise Http404

    try:
        visibility = json.loads(request.body.decode('utf8'))["visibility"]
        course_module.edxnotes_visibility = visibility
        course_module.save()
        return JsonResponse(status=200)
    except (ValueError, KeyError):
        log.warning(
            u"Could not decode request body as JSON and find a boolean visibility field: '%s'",
            request.body)
        return JsonResponseBadRequest()
Beispiel #27
0
def create_order(request):
    """
    This endpoint is named 'create_order' for backward compatibility, but its
    actual use is to add a single product to the user's cart and request
    immediate checkout.
    """
    course_id = request.POST['course_id']
    course_id = CourseKey.from_string(course_id)
    donation_for_course = request.session.get('donation_for_course', {})
    contribution = request.POST.get("contribution", donation_for_course.get(six.text_type(course_id), 0))
    try:
        amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
    except decimal.InvalidOperation:
        return HttpResponseBadRequest(_("Selected price is not valid number."))

    current_mode = None
    sku = request.POST.get('sku', None)

    if sku:
        try:
            current_mode = CourseMode.objects.get(sku=sku)
        except CourseMode.DoesNotExist:
            log.exception(u'Failed to find CourseMode with SKU [%s].', sku)

    if not current_mode:
        # Check if there are more than 1 paid(mode with min_price>0 e.g verified/professional/no-id-professional) modes
        # for course exist then choose the first one
        paid_modes = CourseMode.paid_modes_for_course(course_id)
        if paid_modes:
            if len(paid_modes) > 1:
                log.warning(u"Multiple paid course modes found for course '%s' for create order request", course_id)
            current_mode = paid_modes[0]

    # Make sure this course has a paid mode
    if not current_mode:
        log.warning(u"Create order requested for course '%s' without a paid mode.", course_id)
        return HttpResponseBadRequest(_("This course doesn't support paid certificates"))

    if CourseMode.is_professional_mode(current_mode):
        amount = current_mode.min_price

    if amount < current_mode.min_price:
        return HttpResponseBadRequest(_("No selected price or selected price is below minimum."))

    # if request.POST doesn't contain 'processor' then the service's default payment processor will be used.
    payment_data = checkout_with_ecommerce_service(
        request.user,
        course_id,
        current_mode,
        request.POST.get('processor')
    )

    if 'processor' not in request.POST:
        # (XCOM-214) To be removed after release.
        # the absence of this key in the POST payload indicates that the request was initiated from
        # a stale js client, which expects a response containing only the 'payment_form_data' part of
        # the payment data result.
        payment_data = payment_data['payment_form_data']
    return JsonResponse(payment_data)
Beispiel #28
0
def _assets_json(request, course_key):
    '''
    Display an editable asset library.

    Supports start (0-based index into the list of assets) and max query parameters.
    '''
    request_options = _parse_request_to_dictionary(request)

    filter_parameters = {}

    if request_options['requested_asset_type']:
        filters_are_invalid_error = _get_error_if_invalid_parameters(request_options['requested_asset_type'])

        if filters_are_invalid_error is not None:
            return filters_are_invalid_error

        filter_parameters.update(_get_content_type_filter_for_mongo(request_options['requested_asset_type']))

    if request_options['requested_text_search']:
        filter_parameters.update(_get_displayname_search_filter_for_mongo(request_options['requested_text_search']))

    sort_type_and_direction = _get_sort_type_and_direction(request_options)

    requested_page_size = request_options['requested_page_size']
    current_page = _get_current_page(request_options['requested_page'])
    first_asset_to_display_index = _get_first_asset_index(current_page, requested_page_size)

    query_options = {
        'current_page': current_page,
        'page_size': requested_page_size,
        'sort': sort_type_and_direction,
        'filter_params': filter_parameters
    }

    assets, total_count = _get_assets_for_page(course_key, query_options)

    if request_options['requested_page'] > 0 and first_asset_to_display_index >= total_count and total_count > 0:  # lint-amnesty, pylint: disable=chained-comparison
        _update_options_to_requery_final_page(query_options, total_count)
        current_page = query_options['current_page']
        first_asset_to_display_index = _get_first_asset_index(current_page, requested_page_size)
        assets, total_count = _get_assets_for_page(course_key, query_options)

    last_asset_to_display_index = first_asset_to_display_index + len(assets)
    assets_in_json_format = _get_assets_in_json_format(assets, course_key)

    response_payload = {
        'start': first_asset_to_display_index,
        'end': last_asset_to_display_index,
        'page': current_page,
        'pageSize': requested_page_size,
        'totalCount': total_count,
        'assets': assets_in_json_format,
        'sort': request_options['requested_sort'],
        'direction': request_options['requested_sort_direction'],
        'assetTypes': _get_requested_file_types_from_requested_filter(request_options['requested_asset_type']),
        'textSearch': request_options['requested_text_search'],
    }

    return JsonResponse(response_payload)
Beispiel #29
0
def upload_transcript(request):
    """
    Upload a transcript file

    Arguments:
        request: A WSGI request object

        Transcript file in SRT format
    """
    edx_video_id = request.POST['edx_video_id']
    language_code = request.POST['language_code']
    new_language_code = request.POST['new_language_code']
    transcript_file = request.FILES['file']
    try:
        # Convert SRT transcript into an SJSON format
        # and upload it to S3.
        sjson_subs = Transcript.convert(
            content=transcript_file.read().decode('utf-8'),
            input_format=Transcript.SRT,
            output_format=Transcript.SJSON).encode()
        create_or_update_video_transcript(
            video_id=edx_video_id,
            language_code=language_code,
            metadata={
                'provider': TranscriptProvider.CUSTOM,
                'file_format': Transcript.SJSON,
                'language_code': new_language_code
            },
            file_data=ContentFile(sjson_subs),
        )
        response = JsonResponse(status=201)
    except (TranscriptsGenerationException, UnicodeDecodeError):
        LOGGER.error(
            "Unable to update transcript on edX video %s for language %s",
            edx_video_id, new_language_code)
        response = JsonResponse(
            {
                'error':
                _('There is a problem with this transcript file. Try to upload a different file.'
                  )
            },
            status=400)
    finally:
        LOGGER.info("Updated transcript on edX video %s for language %s",
                    edx_video_id, new_language_code)
    return response
Beispiel #30
0
 def test_update_user_error_nonretryable(self, mock_sailthru, mock_log_error, mock_retry):
     """
     Ensure that non-retryable error is not retried
     """
     mock_sailthru.return_value = SailthruResponse(JsonResponse({'error': 1, 'errormsg': 'Got an error'}))
     update_user.delay({}, self.user.email)
     self.assertTrue(mock_log_error.called)
     self.assertFalse(mock_retry.called)