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
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
def create_new_course(request): """ Create a new course. Returns the URL for the course overview page. """ if not auth.has_access(request.user, CourseCreatorRole()): raise PermissionDenied() org = request.json.get('org') number = request.json.get('number') display_name = request.json.get('display_name') run = request.json.get('run') # allow/disable unicode characters in course_id according to settings if not settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID'): if _has_non_ascii_characters(org) or _has_non_ascii_characters(number) or _has_non_ascii_characters(run): return JsonResponse( {'error': _('Special characters not allowed in organization, course number, and course run.')}, status=400 ) try: course_key = SlashSeparatedCourseKey(org, number, run) # instantiate the CourseDescriptor and then persist it # note: no system to pass if display_name is None: metadata = {} else: metadata = {'display_name': display_name} # 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} # Create the course then fetch it from the modulestore # Check if role permissions group for a course named like this already exists # Important because role groups are case insensitive if CourseRole.course_group_already_exists(course_key): raise InvalidLocationError() fields = {} fields.update(definition_data) fields.update(metadata) # Creating the course raises InvalidLocationError if an existing course with this org/name is found new_course = modulestore('direct').create_course( course_key.org, course_key.offering, fields=fields, ) # can't use auth.add_users here b/c it requires request.user to already have Instructor perms in this course # however, we can assume that b/c this user had authority to create the course, the user can add themselves CourseInstructorRole(new_course.id).add_users(request.user) auth.add_users(request.user, CourseStaffRole(new_course.id), request.user) # seed the forums seed_permissions_roles(new_course.id) # auto-enroll the course creator in the course so that "View Live" will # work. CourseEnrollment.enroll(request.user, new_course.id) _users_assign_default_role(new_course.id) return JsonResponse({ 'url': reverse_course_url('course_handler', new_course.id) }) except InvalidLocationError: return JsonResponse({ 'ErrMsg': _( 'There is already a course defined with the same ' 'organization, course number, and course run. Please ' 'change either organization or course number to be unique.' ), 'OrgErrMsg': _( 'Please change either the organization or ' 'course number so that it is unique.'), 'CourseErrMsg': _( 'Please change either the organization or ' 'course number so that it is unique.'), }) except InvalidKeyError as error: return JsonResponse({ "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=error.message)} )
def create_new_course(request): """ Create a new course. Returns the URL for the course overview page. """ if not auth.has_access(request.user, CourseCreatorRole()): raise PermissionDenied() org = request.json.get('org') number = request.json.get('number') display_name = request.json.get('display_name') run = request.json.get('run') # allow/disable unicode characters in course_id according to settings if not settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID'): if _has_non_ascii_characters(org) or _has_non_ascii_characters( number) or _has_non_ascii_characters(run): return JsonResponse( { 'error': _('Special characters not allowed in organization, course number, and course run.' ) }, status=400) try: course_key = SlashSeparatedCourseKey(org, number, run) # instantiate the CourseDescriptor and then persist it # note: no system to pass if display_name is None: metadata = {} else: metadata = {'display_name': display_name} # 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} # Create the course then fetch it from the modulestore # Check if role permissions group for a course named like this already exists # Important because role groups are case insensitive if CourseRole.course_group_already_exists(course_key): raise InvalidLocationError() fields = {} fields.update(definition_data) fields.update(metadata) # Creating the course raises InvalidLocationError if an existing course with this org/name is found new_course = modulestore('direct').create_course( course_key.org, course_key.offering, fields=fields, ) # can't use auth.add_users here b/c it requires request.user to already have Instructor perms in this course # however, we can assume that b/c this user had authority to create the course, the user can add themselves CourseInstructorRole(new_course.id).add_users(request.user) auth.add_users(request.user, CourseStaffRole(new_course.id), request.user) # seed the forums seed_permissions_roles(new_course.id) # auto-enroll the course creator in the course so that "View Live" will # work. CourseEnrollment.enroll(request.user, new_course.id) _users_assign_default_role(new_course.id) return JsonResponse( {'url': reverse_course_url('course_handler', new_course.id)}) except InvalidLocationError: return JsonResponse({ 'ErrMsg': _('There is already a course defined with the same ' 'organization, course number, and course run. Please ' 'change either organization or course number to be unique.'), 'OrgErrMsg': _('Please change either the organization or ' 'course number so that it is unique.'), 'CourseErrMsg': _('Please change either the organization or ' 'course number so that it is unique.'), }) except InvalidKeyError as error: return JsonResponse({ "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format( name=display_name, err=error.message) })
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