示例#1
0
def _create_new_course(request, course_key, fields):
    """
    Create a new course.
    Returns the URL for the course overview page.
    """
    # Set a unique wiki_slug for newly created courses. To maintain active wiki_slugs for
    # existing xml courses this cannot be changed in CourseDescriptor.
    # # TODO get rid of defining wiki slug in this org/course/run specific way and reconcile
    # w/ xmodule.course_module.CourseDescriptor.__init__
    wiki_slug = u"{0}.{1}.{2}".format(course_key.org, course_key.course, course_key.run)
    definition_data = {'wiki_slug': wiki_slug}
    fields.update(definition_data)

    # Creating the course raises InvalidLocationError if an existing course with this org/name is found
    new_course = modulestore().create_course(
        course_key.org,
        course_key.course,
        course_key.run,
        request.user.id,
        fields=fields,
    )

    # Make sure user has instructor and staff access to the new course
    add_instructor(new_course.id, request.user, request.user)

    # Initialize permissions for user in the new course
    initialize_permissions(new_course.id, request.user)

    return JsonResponse({
        'url': reverse_course_url('course_handler', new_course.id)
    })
示例#2
0
def rerun_course(source_course_key_string,
                 destination_course_key_string,
                 user_id,
                 fields=None):
    """
    Reruns a course in a new celery task.
    """
    # import here, at top level this import prevents the celery workers from starting up correctly
    from edxval.api import copy_course_videos

    try:
        # deserialize the payload
        source_course_key = CourseKey.from_string(source_course_key_string)
        destination_course_key = CourseKey.from_string(
            destination_course_key_string)
        fields = deserialize_fields(fields) if fields else None

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key,
                               destination_course_key,
                               user_id,
                               fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key,
                               User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        # call edxval to attach videos to the rerun
        copy_course_videos(source_course_key, destination_course_key)

        return "succeeded"

    except DuplicateCourseError as exc:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key)
        logging.exception(u'Course Rerun Error')
        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key)
        logging.exception(u'Course Rerun Error')

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return "exception: " + unicode(exc)
示例#3
0
def rerun_course(source_course_key_string,
                 destination_course_key_string,
                 user_id,
                 fields=None):
    """
    Reruns a course in a new celery task.
    """
    try:
        # deserialize the keys
        source_course_key = CourseKey.from_string(source_course_key_string)
        destination_course_key = CourseKey.from_string(
            destination_course_key_string)

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key,
                               destination_course_key,
                               user_id,
                               fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key,
                               User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        return "succeeded"

    except DuplicateCourseError as exc:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key,
                                        exception=exc)

        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key,
                                        exception=exc)

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return "exception: " + unicode(exc)
示例#4
0
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None):
    """
    Reruns a course in a new celery task.
    """
    # import here, at top level this import prevents the celery workers from starting up correctly
    from edxval.api import copy_course_videos

    try:
        # deserialize the payload
        source_course_key = CourseKey.from_string(source_course_key_string)
        destination_course_key = CourseKey.from_string(destination_course_key_string)
        fields = deserialize_fields(fields) if fields else None

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key, destination_course_key, user_id, fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key, User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        # call edxval to attach videos to the rerun
        copy_course_videos(source_course_key, destination_course_key)

        return "succeeded"

    except DuplicateCourseError as exc:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key)
        logging.exception(u'Course Rerun Error')
        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key)
        logging.exception(u'Course Rerun Error')

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return "exception: " + unicode(exc)
示例#5
0
def get_master_course(user=None, command=None):
    from contentstore.utils import add_instructor, initialize_permissions
    from courseware.courses import get_course_by_id
    from opaque_keys.edx.locations import SlashSeparatedCourseKey
    from student.roles import CourseRole
    from xmodule.modulestore.exceptions import InvalidLocationError

    if not user:
        user = User.objects.get(id=ADMIN_USER_ID)

    display_name = "LabsterX Master"
    org, number, run = COURSE_ID.split('/')

    try:
        course_key = SlashSeparatedCourseKey(org, number, run)
        fields = {'display_name': display_name}

        wiki_slug = u"{0}.{1}.{2}".format(course_key.org, course_key.course, course_key.run)
        definition_data = {'wiki_slug': wiki_slug}
        fields.update(definition_data)

        if CourseRole.course_group_already_exists(course_key):
            raise InvalidLocationError()

        course = get_modulestore().create_course(
            course_key.org,
            course_key.course,
            course_key.run,
            user.id,
            fields=fields,
        )

        # Make sure user has instructor and staff access to the new course
        add_instructor(course.id, user, user)

        # Initialize permissions for user in the new course
        initialize_permissions(course.id, user)
        command and command.stdout.write("name: {}\n".format(course.display_name))

    except InvalidLocationError:
        course = get_course_by_id(course_key)

    return course
示例#6
0
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None):
    """
    Reruns a course in a new celery task.
    """
    try:
        # deserialize the keys
        source_course_key = CourseKey.from_string(source_course_key_string)
        destination_course_key = CourseKey.from_string(destination_course_key_string)

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key, destination_course_key, user_id, fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key, User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        return "succeeded"

    except DuplicateCourseError as exc:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key, exception=exc)

        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key, exception=exc)

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return "exception: " + unicode(exc)
示例#7
0
def rerun_course(source_course_key, destination_course_key, user_id, fields=None):
    """
    Reruns a course in a new celery task.
    """
    try:
        modulestore().clone_course(source_course_key, destination_course_key, user_id, fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key, User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key, exception=exc)

        # cleanup any remnants of the course
        modulestore().delete_course(destination_course_key, user_id)
示例#8
0
def get_or_create_course(source, target, user):
    source_course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(source))

    display_name = source_course.display_name
    org, number, run = target.split('/')

    course_key = SlashSeparatedCourseKey(org, number, run)
    fields = {'display_name': display_name}

    wiki_slug = u"{0}.{1}.{2}".format(course_key.org, course_key.course, course_key.run)
    definition_data = {'wiki_slug': wiki_slug}
    fields.update(definition_data)

    try:
        if CourseRole.course_group_already_exists(course_key):
            raise InvalidLocationError()

        course = modulestore().create_course(
            course_key.org,
            course_key.course,
            course_key.run,
            user.id,
            fields=fields,
        )

    except InvalidLocationError:
        course = get_course(course_key)

    else:
        # Make sure user has instructor and staff access to the new course
        add_instructor(course.id, user, user)

        # Initialize permissions for user in the new course
        initialize_permissions(course.id, user)

    return course
示例#9
0
def rerun_course(source_course_key_string,
                 destination_course_key_string,
                 user_id,
                 fields=None):
    """
    Reruns a course in a new celery task.
    """
    # import here, at top level this import prevents the celery workers from starting up correctly
    from edxval.api import copy_course_videos

    source_course_key = CourseKey.from_string(source_course_key_string)
    destination_course_key = CourseKey.from_string(
        destination_course_key_string)
    try:
        # deserialize the payload
        fields = deserialize_fields(fields) if fields else None

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key,
                               destination_course_key,
                               user_id,
                               fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key,
                               User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        # call edxval to attach videos to the rerun
        copy_course_videos(source_course_key, destination_course_key)

        # Copy OrganizationCourse
        organization_course = OrganizationCourse.objects.filter(
            course_id=source_course_key_string).first()

        if organization_course:
            clone_instance(organization_course,
                           {'course_id': destination_course_key_string})

        # Copy RestrictedCourse
        restricted_course = RestrictedCourse.objects.filter(
            course_key=source_course_key).first()

        if restricted_course:
            country_access_rules = CountryAccessRule.objects.filter(
                restricted_course=restricted_course)
            new_restricted_course = clone_instance(
                restricted_course, {'course_key': destination_course_key})
            for country_access_rule in country_access_rules:
                clone_instance(country_access_rule,
                               {'restricted_course': new_restricted_course})

        return "succeeded"

    except DuplicateCourseError:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key)
        LOGGER.exception(u'Course Rerun Error')
        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key)
        LOGGER.exception(u'Course Rerun Error')

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return u"exception: " + text_type(exc)
示例#10
0
def rerun_course(source_course_key_string, destination_course_key_string, user_id, fields=None):
    """
    Reruns a course in a new celery task.
    """
    # import here, at top level this import prevents the celery workers from starting up correctly
    from edxval.api import copy_course_videos

    source_course_key = CourseKey.from_string(source_course_key_string)
    destination_course_key = CourseKey.from_string(destination_course_key_string)
    try:
        # deserialize the payload
        fields = deserialize_fields(fields) if fields else None

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key, destination_course_key, user_id, fields=fields)

        # set initial permissions for the user to access the course.
        initialize_permissions(destination_course_key, User.objects.get(id=user_id))

        # update state: Succeeded
        CourseRerunState.objects.succeeded(course_key=destination_course_key)

        # call edxval to attach videos to the rerun
        copy_course_videos(source_course_key, destination_course_key)

        # Copy OrganizationCourse
        organization_course = OrganizationCourse.objects.filter(course_id=source_course_key_string).first()

        if organization_course:
            clone_instance(organization_course, {'course_id': destination_course_key_string})

        # Copy RestrictedCourse
        restricted_course = RestrictedCourse.objects.filter(course_key=source_course_key).first()

        if restricted_course:
            country_access_rules = CountryAccessRule.objects.filter(restricted_course=restricted_course)
            new_restricted_course = clone_instance(restricted_course, {'course_key': destination_course_key})
            for country_access_rule in country_access_rules:
                clone_instance(country_access_rule, {'restricted_course': new_restricted_course})

        return "succeeded"

    except DuplicateCourseError:
        # do NOT delete the original course, only update the status
        CourseRerunState.objects.failed(course_key=destination_course_key)
        LOGGER.exception(u'Course Rerun Error')
        return "duplicate course"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        CourseRerunState.objects.failed(course_key=destination_course_key)
        LOGGER.exception(u'Course Rerun Error')

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return u"exception: " + text_type(exc)
示例#11
0
def force_create_course(source, target, user, extra_fields=None):
    source_course_key = SlashSeparatedCourseKey.from_deprecated_string(source)
    source_course = get_course_by_id(source_course_key)
    display_name = source_course.display_name

    fields = {'display_name': display_name}
    # duplicated_fields = [
    #     'key_dates', 'video',
    #     'course_staff_short', 'course_staff_extended',
    #     'requirements', 'textbook', 'faq', 'more_info',
    #     'number', 'instructors', 'end_date',
    #     'prerequisites', 'ocw_links',
    # ]

    # for field in duplicated_fields:
    #     fields[field] = getattr(source_course, field)

    course = None
    start_index = 0
    org, original_number, run = target.split('/')

    number = original_number
    while course is None:
        course_key = SlashSeparatedCourseKey(org, number, run)

        wiki_slug = u"{0}.{1}.{2}".format(course_key.org, course_key.course, course_key.run)
        definition_data = {'wiki_slug': wiki_slug}
        fields.update(definition_data)
        if extra_fields:
            fields.update(extra_fields)

        try:
            if CourseRole.course_group_already_exists(course_key):
                raise InvalidLocationError()

            course = modulestore().create_course(
                course_key.org,
                course_key.course,
                course_key.run,
                user.id,
                fields=fields,
            )

        except InvalidLocationError:
            start_index += 1
            number = "{}{}".format(original_number, start_index)
            continue

        else:
            # Make sure user has instructor and staff access to the new course
            add_instructor(course.id, user, user)

            # Initialize permissions for user in the new course
            initialize_permissions(course.id, user)

    copy_about_fields(user, source_course_key, course_key, course)

    UserProfile.objects\
        .filter(user_id=user.id)\
        .exclude(user_type=UserProfile.USER_TYPE_TEACHER)\
        .update(user_type=UserProfile.USER_TYPE_TEACHER)

    return course
示例#12
0
def clone_course(source_course_key_string,
                 destination_course_key_string,
                 user_id,
                 fields=None):
    """
    Reruns a course in a new celery task.
    """
    # import here, at top level this import prevents the celery workers from starting up correctly
    from edxval.api import copy_course_videos
    from contentstore.utils import initialize_permissions
    from contentstore.courseware_index import SearchIndexingError
    from contentstore.views.course import reindex_course_and_check_access
    # deserialize the payload
    source_course_key = CourseKey.from_string(source_course_key_string)
    destination_course_key = CourseKey.from_string(
        destination_course_key_string)

    try:

        # use the split modulestore as the store for the rerun course,
        # as the Mongo modulestore doesn't support multiple runs of the same course.
        store = modulestore()
        with store.default_store('split'):
            store.clone_course(source_course_key,
                               destination_course_key,
                               user_id,
                               fields=fields)

        # set initial permissions for the user to access the course.
        user = User.objects.get(id=user_id)
        initialize_permissions(destination_course_key, user)

        # add course intructor and staff roles to the new user
        CourseInstructorRole(destination_course_key).add_users(user)
        CourseStaffRole(destination_course_key).add_users(user)

        # call edxval to attach videos to the rerun
        copy_course_videos(source_course_key, destination_course_key)

        return "succeeded"

    except DuplicateCourseError as exc:
        # do NOT delete the original course, only update the status
        logging.exception(u'Course Clone Error')
        return "duplicate course"

    except SearchIndexingError as search_err:
        logging.exception(u'Course Clone index Error')
        return "index error"

    # catch all exceptions so we can update the state and properly cleanup the course.
    except Exception as exc:  # pylint: disable=broad-except
        # update state: Failed
        logging.exception(u'Course Clone Error')

        try:
            # cleanup any remnants of the course
            modulestore().delete_course(destination_course_key, user_id)
        except ItemNotFoundError:
            # it's possible there was an error even before the course module was created
            pass

        return "exception: " + unicode(exc)