From 819a56fee328ea6cf1ae29d903de3e65415a68f0 Mon Sep 17 00:00:00 2001 From: cahrens Date: Tue, 8 Aug 2017 16:32:55 -0400 Subject: [PATCH] Remove usages of deprecated SlashSeparatedCourseKey. --- .../management/commands/clone_course.py | 15 +--- .../management/commands/edit_course_tabs.py | 9 +-- .../commands/empty_asset_trashcan.py | 9 +-- .../management/commands/export.py | 6 +- .../management/commands/git_export.py | 6 +- .../management/commands/reindex_library.py | 7 +- common/djangoapps/course_modes/admin.py | 6 +- common/djangoapps/course_modes/views.py | 3 +- .../djangoapps/django_comment_common/tests.py | 4 +- .../commands/anonymized_id_mapping.py | 4 +- .../management/commands/change_enrollment.py | 7 +- .../commands/create_random_users.py | 7 +- .../management/commands/create_user.py | 9 +-- common/djangoapps/student/models.py | 5 +- .../student/tests/test_auto_auth.py | 3 - common/djangoapps/student/tests/tests.py | 9 +-- common/djangoapps/student/views.py | 5 +- common/djangoapps/terrain/steps.py | 4 +- common/djangoapps/track/contexts.py | 3 +- common/djangoapps/util/request.py | 4 +- common/djangoapps/util/tests/test_file.py | 31 +++----- .../lib/xmodule/xmodule/modulestore/mixed.py | 8 +- .../xmodule/xmodule/modulestore/mongo/base.py | 16 ++-- .../xmodule/modulestore/mongoengine_fields.py | 4 +- common/lib/xmodule/xmodule/modulestore/xml.py | 9 ++- common/lib/xmodule/xmodule/tests/__init__.py | 15 ++-- .../xmodule/xmodule/tests/test_conditional.py | 5 +- .../lib/xmodule/xmodule/tests/test_content.py | 5 +- .../xmodule/tests/test_course_module.py | 4 +- .../lib/xmodule/xmodule/tests/test_import.py | 3 +- lms/djangoapps/branding/__init__.py | 6 +- lms/djangoapps/bulk_email/forms.py | 12 +-- .../management/commands/cert_whitelist.py | 9 +-- .../management/commands/gen_cert_report.py | 9 +-- .../management/commands/regenerate_user.py | 14 +--- .../management/commands/ungenerated_certs.py | 15 +--- lms/djangoapps/certificates/views/xqueue.py | 6 +- lms/djangoapps/class_dashboard/views.py | 8 +- .../course_structure_api/v0/tests.py | 2 +- lms/djangoapps/course_wiki/views.py | 4 +- lms/djangoapps/courseware/module_render.py | 5 +- lms/djangoapps/dashboard/git_import.py | 7 +- lms/djangoapps/dashboard/sysadmin.py | 6 +- .../grades/management/commands/get_grades.py | 9 +-- lms/djangoapps/instructor/views/api.py | 79 +++++++++---------- lms/djangoapps/instructor/views/coupons.py | 4 +- .../instructor/views/instructor_dashboard.py | 3 +- .../instructor/views/registration_codes.py | 6 +- lms/djangoapps/notes/api.py | 4 +- lms/djangoapps/notes/tests.py | 6 +- lms/djangoapps/notes/views.py | 4 +- lms/djangoapps/shoppingcart/views.py | 4 +- lms/djangoapps/staticbook/views.py | 8 +- lms/djangoapps/support/views/refund.py | 3 +- .../courseware_search/lms_result_processor.py | 4 +- .../lms_search_initializer.py | 7 +- .../core/djangoapps/course_groups/views.py | 13 ++- .../core/djangoapps/external_auth/views.py | 6 +- openedx/core/djangoapps/user_api/views.py | 4 +- 59 files changed, 175 insertions(+), 317 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/clone_course.py b/cms/djangoapps/contentstore/management/commands/clone_course.py index 2430fb0e8e..b8a8c9a752 100644 --- a/cms/djangoapps/contentstore/management/commands/clone_course.py +++ b/cms/djangoapps/contentstore/management/commands/clone_course.py @@ -2,9 +2,7 @@ Script for cloning a course """ from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from student.roles import CourseInstructorRole, CourseStaffRole from xmodule.modulestore import ModuleStoreEnum @@ -18,22 +16,13 @@ class Command(BaseCommand): """Clone a MongoDB-backed course to another location""" help = 'Clone a MongoDB backed course to another location' - def course_key_from_arg(self, arg): - """ - Convert the command line arg into a course key - """ - try: - return CourseKey.from_string(arg) - except InvalidKeyError: - return SlashSeparatedCourseKey.from_deprecated_string(arg) - def handle(self, *args, **options): "Execute the command" if len(args) != 2: raise CommandError("clone requires 2 arguments: ") - source_course_id = self.course_key_from_arg(args[0]) - dest_course_id = self.course_key_from_arg(args[1]) + source_course_id = CourseKey.from_string(args[0]) + dest_course_id = CourseKey.from_string(args[1]) mstore = modulestore() diff --git a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py index e63a4f97cb..9d3891f7f7 100644 --- a/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py +++ b/cms/djangoapps/contentstore/management/commands/edit_course_tabs.py @@ -8,9 +8,7 @@ # from optparse import make_option from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from contentstore.views import tabs from courseware.courses import get_course_by_id @@ -67,12 +65,7 @@ command again, adding --insert or --delete to edit the list. if not options['course']: raise CommandError(Command.course_option.help) - try: - course_key = CourseKey.from_string(options['course']) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course']) - - course = get_course_by_id(course_key) + course = get_course_by_id(CourseKey.from_string(options['course'])) print 'Warning: this command directly edits the list of course tabs in mongo.' print 'Tabs before any changes:' diff --git a/cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py b/cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py index 91cc8b3c24..3c7288552c 100644 --- a/cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py +++ b/cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py @@ -1,7 +1,5 @@ from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.contentstore.utils import empty_asset_trashcan from xmodule.modulestore.django import modulestore @@ -17,12 +15,7 @@ class Command(BaseCommand): raise CommandError("empty_asset_trashcan requires one or no arguments: ||") if len(args) == 1: - try: - course_key = CourseKey.from_string(args[0]) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0]) - - course_ids = [course_key] + course_ids = [CourseKey.from_string(args[0])] else: course_ids = [course.id for course in modulestore().get_courses()] diff --git a/cms/djangoapps/contentstore/management/commands/export.py b/cms/djangoapps/contentstore/management/commands/export.py index 7cb621dfae..ea351658ee 100644 --- a/cms/djangoapps/contentstore/management/commands/export.py +++ b/cms/djangoapps/contentstore/management/commands/export.py @@ -6,7 +6,6 @@ import os from django.core.management.base import BaseCommand, CommandError from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.contentstore.django import contentstore from xmodule.modulestore.django import modulestore @@ -31,10 +30,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(options['course_id']) except InvalidKeyError: - try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course_id']) - except InvalidKeyError: - raise CommandError("Invalid course_key: '%s'." % options['course_id']) + raise CommandError("Invalid course_key: '%s'." % options['course_id']) if not modulestore().get_course(course_key): raise CommandError("Course with %s key not found." % options['course_id']) diff --git a/cms/djangoapps/contentstore/management/commands/git_export.py b/cms/djangoapps/contentstore/management/commands/git_export.py index cafa7bab33..bbf9d5a2a9 100644 --- a/cms/djangoapps/contentstore/management/commands/git_export.py +++ b/cms/djangoapps/contentstore/management/commands/git_export.py @@ -20,7 +20,6 @@ from django.core.management.base import BaseCommand, CommandError from django.utils.translation import ugettext as _ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey import contentstore.git_export_utils as git_export_utils from contentstore.git_export_utils import GitExportError @@ -59,10 +58,7 @@ class Command(BaseCommand): try: course_key = CourseKey.from_string(args[0]) except InvalidKeyError: - try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0]) - except InvalidKeyError: - raise CommandError(unicode(GitExportError.BAD_COURSE)) + raise CommandError(unicode(GitExportError.BAD_COURSE)) try: git_export_utils.export_to_git( diff --git a/cms/djangoapps/contentstore/management/commands/reindex_library.py b/cms/djangoapps/contentstore/management/commands/reindex_library.py index 99d984f66e..596373ffea 100644 --- a/cms/djangoapps/contentstore/management/commands/reindex_library.py +++ b/cms/djangoapps/contentstore/management/commands/reindex_library.py @@ -3,9 +3,7 @@ from optparse import make_option from textwrap import dedent from django.core.management import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locator import LibraryLocator from contentstore.courseware_index import LibrarySearchIndexer @@ -42,10 +40,7 @@ class Command(BaseCommand): def _parse_library_key(self, raw_value): """ Parses library key from string """ - try: - result = CourseKey.from_string(raw_value) - except InvalidKeyError: - result = SlashSeparatedCourseKey.from_deprecated_string(raw_value) + result = CourseKey.from_string(raw_value) if not isinstance(result, LibraryLocator): raise CommandError(u"Argument {0} is not a library key".format(raw_value)) diff --git a/common/djangoapps/course_modes/admin.py b/common/djangoapps/course_modes/admin.py index f7898418a4..086c19e213 100644 --- a/common/djangoapps/course_modes/admin.py +++ b/common/djangoapps/course_modes/admin.py @@ -9,7 +9,6 @@ from django.contrib import admin from pytz import timezone, UTC from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys import InvalidKeyError from util.date_utils import get_time_display @@ -86,10 +85,7 @@ class CourseModeForm(forms.ModelForm): try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: - try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) - except InvalidKeyError: - raise forms.ValidationError("Cannot make a valid CourseKey from id {}!".format(course_id)) + raise forms.ValidationError("Cannot make a valid CourseKey from id {}!".format(course_id)) if not modulestore().has_course(course_key): raise forms.ValidationError("Cannot find course with id {} in the modulestore".format(course_id)) diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py index 86f7db25ca..74a5c55ccf 100644 --- a/common/djangoapps/course_modes/views.py +++ b/common/djangoapps/course_modes/views.py @@ -17,7 +17,6 @@ from django.utils.translation import get_language, to_locale from django.views.generic.base import View from ipware.ip import get_ip from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from course_modes.models import CourseMode from courseware.access import has_access @@ -234,7 +233,7 @@ class ChooseModeView(View): below the minimum, otherwise redirects to the verification flow. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) user = request.user # This is a bit redundant with logic in student.views.change_enrollment, diff --git a/common/djangoapps/django_comment_common/tests.py b/common/djangoapps/django_comment_common/tests.py index d988d6ab20..c543ec6014 100644 --- a/common/djangoapps/django_comment_common/tests.py +++ b/common/djangoapps/django_comment_common/tests.py @@ -1,6 +1,6 @@ from django.test import TestCase from nose.plugins.attrib import attr -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import CourseLocator from django_comment_common.models import Role from models import CourseDiscussionSettings @@ -33,7 +33,7 @@ class RoleAssignmentTest(TestCase): "hacky", "hacky@fake.edx.org" ) - self.course_key = SlashSeparatedCourseKey("edX", "Fake101", "2012") + self.course_key = CourseLocator("edX", "Fake101", "2012") CourseEnrollment.enroll(self.staff_user, self.course_key) CourseEnrollment.enroll(self.student_user, self.course_key) diff --git a/common/djangoapps/student/management/commands/anonymized_id_mapping.py b/common/djangoapps/student/management/commands/anonymized_id_mapping.py index 4a1cf1b50a..ce08b39446 100644 --- a/common/djangoapps/student/management/commands/anonymized_id_mapping.py +++ b/common/djangoapps/student/management/commands/anonymized_id_mapping.py @@ -14,7 +14,7 @@ from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError from student.models import anonymous_id_for_user -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey class Command(BaseCommand): @@ -36,7 +36,7 @@ class Command(BaseCommand): raise CommandError("Usage: unique_id_mapping %s" % " ".join(("<%s>" % arg for arg in Command.args))) - course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0]) + course_key = CourseKey.from_string(args[0]) # Generate the output filename from the course ID. # Change slashes to dashes first, and then append .csv extension. diff --git a/common/djangoapps/student/management/commands/change_enrollment.py b/common/djangoapps/student/management/commands/change_enrollment.py index 8b5c1346f1..38c12d8d0d 100644 --- a/common/djangoapps/student/management/commands/change_enrollment.py +++ b/common/djangoapps/student/management/commands/change_enrollment.py @@ -4,9 +4,7 @@ import logging from django.core.management.base import BaseCommand, CommandError from django.db import transaction -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from optparse import make_option from student.models import CourseEnrollment, User @@ -86,10 +84,7 @@ class Command(BaseCommand): if not options['from_mode'] or not options['to_mode']: raise CommandError('You must specify a "to" and "from" mode as parameters') - try: - course_key = CourseKey.from_string(options['course_id']) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course_id']) + course_key = CourseKey.from_string(options['course_id']) enrollment_args = dict( course_id=course_key, diff --git a/common/djangoapps/student/management/commands/create_random_users.py b/common/djangoapps/student/management/commands/create_random_users.py index b8929679a2..7c58f1eb71 100644 --- a/common/djangoapps/student/management/commands/create_random_users.py +++ b/common/djangoapps/student/management/commands/create_random_users.py @@ -5,9 +5,7 @@ import uuid from django.core.management.base import BaseCommand from student.models import CourseEnrollment -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from student.forms import AccountCreationForm from student.views import _do_create_account @@ -55,10 +53,7 @@ Examples: num = int(args[0]) if len(args) == 2: - try: - course_key = CourseKey.from_string(args[1]) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(args[1]) + course_key = CourseKey.from_string(args[1]) else: course_key = None diff --git a/common/djangoapps/student/management/commands/create_user.py b/common/djangoapps/student/management/commands/create_user.py index b1cabee6d2..c98452ae49 100644 --- a/common/djangoapps/student/management/commands/create_user.py +++ b/common/djangoapps/student/management/commands/create_user.py @@ -5,9 +5,7 @@ from django.contrib.auth.models import User from django.core.management.base import BaseCommand from django.utils import translation -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from student.forms import AccountCreationForm from student.models import CourseEnrollment, create_comments_service_user from student.views import _do_create_account, AccountValidationError @@ -74,12 +72,7 @@ class Command(TrackedCommand): # parse out the course into a coursekey if options['course']: - try: - course = CourseKey.from_string(options['course']) - # if it's not a new-style course key, parse it from an old-style - # course key - except InvalidKeyError: - course = SlashSeparatedCourseKey.from_deprecated_string(options['course']) + course = CourseKey.from_string(options['course']) form = AccountCreationForm( data={ diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index f6b4452ec8..02bba4e008 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -40,7 +40,6 @@ from edx_rest_api_client.exceptions import SlumberBaseException from eventtracking import tracker from model_utils.models import TimeStampedModel from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from pytz import UTC from simple_history.models import HistoricalRecords from slumber.exceptions import HttpClientError, HttpServerError @@ -1429,8 +1428,8 @@ class CourseEnrollment(models.Model): """ assert isinstance(course_id_partial, CourseKey) assert not course_id_partial.run # None or empty string - course_key = SlashSeparatedCourseKey(course_id_partial.org, course_id_partial.course, '') - querystring = unicode(course_key.to_deprecated_string()) + course_key = CourseKey.from_string('/'.join([course_id_partial.org, course_id_partial.course, ''])) + querystring = unicode(course_key) try: return cls.objects.filter( user=user, diff --git a/common/djangoapps/student/tests/test_auto_auth.py b/common/djangoapps/student/tests/test_auto_auth.py index d75cb11dd8..c3db357612 100644 --- a/common/djangoapps/student/tests/test_auto_auth.py +++ b/common/djangoapps/student/tests/test_auto_auth.py @@ -6,7 +6,6 @@ from django.contrib.auth.models import User from django.test import TestCase from django.test.client import Client from mock import patch, Mock -from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locator import CourseLocator from django_comment_common.models import ( @@ -32,8 +31,6 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase): COURSE_ID_MONGO = 'edX/Test101/2014_Spring' COURSE_ID_SPLIT = 'course-v1:edX+Test101+2014_Spring' COURSE_IDS_DDT = ( - (COURSE_ID_MONGO, SlashSeparatedCourseKey.from_deprecated_string(COURSE_ID_MONGO)), - (COURSE_ID_SPLIT, SlashSeparatedCourseKey.from_deprecated_string(COURSE_ID_SPLIT)), (COURSE_ID_MONGO, CourseLocator.from_string(COURSE_ID_MONGO)), (COURSE_ID_SPLIT, CourseLocator.from_string(COURSE_ID_SPLIT)), ) diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py index f2b7e49549..88478ef0c7 100644 --- a/common/djangoapps/student/tests/tests.py +++ b/common/djangoapps/student/tests/tests.py @@ -18,7 +18,8 @@ from django.test.client import Client from markupsafe import escape from mock import Mock, patch from nose.plugins.attrib import attr -from opaque_keys.edx.locations import CourseLocator, SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.locations import CourseLocator from pyquery import PyQuery as pq import shoppingcart # pylint: disable=import-error @@ -749,10 +750,8 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') def test_enrollment(self): user = User.objects.create_user("joe", "joe@joe.com", "password") - course_id = SlashSeparatedCourseKey("edX", "Test101", "2013") - # Cannot be converted to CourseLocator or CourseKey.from_string because both do not support - # course keys without a run. The test specifically tests functionality when run is not specified. - course_id_partial = SlashSeparatedCourseKey("edX", "Test101", None) + course_id = CourseKey.from_string("edX/Test101/2013") + course_id_partial = CourseKey.from_string("edX/Test101/") # Test basic enrollment self.assertFalse(CourseEnrollment.is_enrolled(user, course_id)) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index f71f451b6a..0c24bbfbb6 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -40,7 +40,6 @@ from django.views.generic import TemplateView from ipware.ip import get_ip from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locator import CourseLocator from provider.oauth2.models import Client from pytz import UTC @@ -1205,7 +1204,7 @@ def change_enrollment(request, check_access=True): return HttpResponseBadRequest(_("Course id not specified")) try: - course_id = SlashSeparatedCourseKey.from_deprecated_string(request.POST.get("course_id")) + course_id = CourseKey.from_string(request.POST.get("course_id")) except InvalidKeyError: log.warning( u"User %s tried to %s with invalid course id: %s", @@ -2831,7 +2830,7 @@ def change_email_settings(request): user = request.user course_id = request.POST.get("course_id") - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) receive_emails = request.POST.get("receive_emails") if receive_emails: optout_object = Optout.objects.filter(user=user, course_id=course_key) diff --git a/common/djangoapps/terrain/steps.py b/common/djangoapps/terrain/steps.py index a8acf5f474..9c91474ff0 100644 --- a/common/djangoapps/terrain/steps.py +++ b/common/djangoapps/terrain/steps.py @@ -19,7 +19,7 @@ from logging import getLogger import lettuce.django from lettuce import step, world from nose.tools import assert_equals # pylint: disable=no-name-in-module -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from .course_helpers import * from .ui_helpers import * @@ -116,7 +116,7 @@ def i_am_not_logged_in(step): @step('I am staff for course "([^"]*)"$') def i_am_staff_for_course_by_id(step, course_id): - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) world.register_by_course_key(course_key, True) diff --git a/common/djangoapps/track/contexts.py b/common/djangoapps/track/contexts.py index f4656ff42a..309c436bf0 100644 --- a/common/djangoapps/track/contexts.py +++ b/common/djangoapps/track/contexts.py @@ -3,7 +3,6 @@ import logging from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from util.request import COURSE_REGEX @@ -22,7 +21,7 @@ def course_context_from_url(url): if match: course_id_string = match.group('course_id') try: - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id_string) + course_id = CourseKey.from_string(course_id_string) except InvalidKeyError: log.warning( 'unable to parse course_id "{course_id}"'.format( diff --git a/common/djangoapps/util/request.py b/common/djangoapps/util/request.py index 3576cdfeec..16ae251a4d 100644 --- a/common/djangoapps/util/request.py +++ b/common/djangoapps/util/request.py @@ -3,7 +3,7 @@ import re from django.conf import settings from opaque_keys import InvalidKeyError -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -44,6 +44,6 @@ def course_id_from_url(url): return None try: - return SlashSeparatedCourseKey.from_deprecated_string(course_id) + return CourseKey.from_string(course_id) except InvalidKeyError: return None diff --git a/common/djangoapps/util/tests/test_file.py b/common/djangoapps/util/tests/test_file.py index d49c5dd257..2df186bafd 100644 --- a/common/djangoapps/util/tests/test_file.py +++ b/common/djangoapps/util/tests/test_file.py @@ -13,7 +13,8 @@ from django.http import HttpRequest from django.test import TestCase from django.utils.timezone import UTC from mock import Mock, patch -from opaque_keys.edx.locations import CourseLocator, SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.locations import CourseLocator import util.file from util.file import ( @@ -30,19 +31,13 @@ class FilenamePrefixGeneratorTestCase(TestCase): """ Tests for course_filename_prefix_generator """ - @ddt.data(CourseLocator, SlashSeparatedCourseKey) - def test_locators(self, course_key_class): - self.assertEqual( - course_filename_prefix_generator(course_key_class(org='foo', course='bar', run='baz')), - u'foo_bar_baz' - ) + @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) + def test_locators(self, course_key): + self.assertEqual(course_filename_prefix_generator(course_key), u'foo_bar_baz') - @ddt.data(CourseLocator, SlashSeparatedCourseKey) - def test_custom_separator(self, course_key_class): - self.assertEqual( - course_filename_prefix_generator(course_key_class(org='foo', course='bar', run='baz'), separator='-'), - u'foo-bar-baz' - ) + @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) + def test_custom_separator(self, course_key): + self.assertEqual(course_filename_prefix_generator(course_key, separator='-'), u'foo-bar-baz') @ddt.ddt @@ -62,21 +57,19 @@ class FilenameGeneratorTestCase(TestCase): mocked_datetime.now.return_value = self.NOW self.addCleanup(datetime_patcher.stop) - @ddt.data(CourseLocator, SlashSeparatedCourseKey) - def test_filename_generator(self, course_key_class): + @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) + def test_filename_generator(self, course_key): """ Tests that the generator creates names based on course_id, base name, and date. """ self.assertEqual( u'foo_bar_baz_file_1974-06-22-010203', - course_and_time_based_filename_generator(course_key_class(org='foo', course='bar', run='baz'), 'file') + course_and_time_based_filename_generator(course_key, 'file') ) self.assertEqual( u'foo_bar_baz_base_name_ø_1974-06-22-010203', - course_and_time_based_filename_generator( - course_key_class(org='foo', course='bar', run='baz'), ' base` name ø ' - ) + course_and_time_based_filename_generator(course_key, ' base` name ø ') ) diff --git a/common/lib/xmodule/xmodule/modulestore/mixed.py b/common/lib/xmodule/xmodule/modulestore/mixed.py index 244907e321..11a9f3d9a3 100644 --- a/common/lib/xmodule/xmodule/modulestore/mixed.py +++ b/common/lib/xmodule/xmodule/modulestore/mixed.py @@ -14,7 +14,6 @@ from contracts import contract, new_contract from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, AssetKey from opaque_keys.edx.locator import LibraryLocator -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.assetstore import AssetMetadata from . import ModuleStoreWriteBase, ModuleStoreEnum, XMODULE_FIELDS_WITH_USAGE_KEYS @@ -161,11 +160,8 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase): try: self.mappings[CourseKey.from_string(course_id)] = store_name except InvalidKeyError: - try: - self.mappings[SlashSeparatedCourseKey.from_deprecated_string(course_id)] = store_name - except InvalidKeyError: - log.exception("Invalid MixedModuleStore configuration. Unable to parse course_id %r", course_id) - continue + log.exception("Invalid MixedModuleStore configuration. Unable to parse course_id %r", course_id) + continue for store_settings in stores: key = store_settings['NAME'] diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index aad2b8c236..e1dc91afb4 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -26,7 +26,7 @@ from contracts import contract, new_contract from fs.osfs import OSFS from mongodb_proxy import autoretry_read from opaque_keys.edx.keys import UsageKey, CourseKey, AssetKey -from opaque_keys.edx.locations import Location, BlockUsageLocator, SlashSeparatedCourseKey +from opaque_keys.edx.locations import Location, BlockUsageLocator from opaque_keys.edx.locator import CourseLocator, LibraryLocator from path import Path as path from pytz import UTC @@ -1021,7 +1021,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo courses_summaries = [] for course in course_records: if not (course['_id']['org'] == 'edx' and course['_id']['course'] == 'templates'): - locator = SlashSeparatedCourseKey(course['_id']['org'], course['_id']['course'], course['_id']['name']) + locator = CourseKey.from_string('/'.join( + [course['_id']['org'], course['_id']['course'], course['_id']['name']] + )) course_summary = extract_course_summary(course) courses_summaries.append( CourseSummary(locator, **course_summary) @@ -1045,7 +1047,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo base_list = sum( [ self._load_items( - SlashSeparatedCourseKey(course['_id']['org'], course['_id']['course'], course['_id']['name']), + CourseKey.from_string('/'.join( + [course['_id']['org'], course['_id']['course'], course['_id']['name']] + )), [course] ) for course @@ -1136,7 +1140,9 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo course_query = {'_id': location.to_deprecated_son()} course = self.collection.find_one(course_query, projection={'_id': True}) if course: - return SlashSeparatedCourseKey(course['_id']['org'], course['_id']['course'], course['_id']['name']) + return CourseKey.from_string('/'.join([ + course['_id']['org'], course['_id']['course'], course['_id']['name']] + )) else: return None @@ -1289,7 +1295,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo Raises: InvalidLocationError: If a course with the same org, course, and run already exists """ - course_id = SlashSeparatedCourseKey(org, course, run) + course_id = CourseKey.from_string('/'.join([org, course, run])) # Check if a course with this org/course has been defined before (case-insensitive) course_search_location = SON([ diff --git a/common/lib/xmodule/xmodule/modulestore/mongoengine_fields.py b/common/lib/xmodule/xmodule/modulestore/mongoengine_fields.py index 1daf4e9646..03a033f857 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongoengine_fields.py +++ b/common/lib/xmodule/xmodule/modulestore/mongoengine_fields.py @@ -2,7 +2,7 @@ Custom field types for mongoengine """ import mongoengine -from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location +from opaque_keys.edx.locations import Location from types import NoneType from opaque_keys.edx.keys import CourseKey, UsageKey @@ -36,7 +36,7 @@ class CourseKeyField(mongoengine.StringField): if course_key == '': return None if isinstance(course_key, basestring): - return SlashSeparatedCourseKey.from_deprecated_string(course_key) + return CourseKey.from_string(course_key) else: return course_key diff --git a/common/lib/xmodule/xmodule/modulestore/xml.py b/common/lib/xmodule/xmodule/modulestore/xml.py index 1421beb118..fbcfd25a93 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml.py +++ b/common/lib/xmodule/xmodule/modulestore/xml.py @@ -26,7 +26,8 @@ from xmodule.x_module import ( from xmodule.modulestore.xml_exporter import DEFAULT_CONTENT_FIELDS from xmodule.modulestore import ModuleStoreEnum, ModuleStoreReadBase, LIBRARY_ROOT, COURSE_ROOT from xmodule.tabs import CourseTabList -from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location +from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.locations import Location from opaque_keys.edx.locator import CourseLocator, LibraryLocator, BlockUsageLocator from xblock.field_data import DictFieldData @@ -357,7 +358,7 @@ class XMLModuleStore(ModuleStoreReadBase): self.errored_courses = {} # course_dir -> errorlog, for dirs that failed to load if course_ids is not None: - course_ids = [SlashSeparatedCourseKey.from_deprecated_string(course_id) for course_id in course_ids] + course_ids = [CourseKey.from_string(course_id) for course_id in course_ids] self.load_error_modules = load_error_modules @@ -629,9 +630,9 @@ class XMLModuleStore(ModuleStoreReadBase): if not url_name: raise ValueError("Can't load a course without a 'url_name' " "(or 'name') set. Set url_name.") - # Have to use SlashSeparatedCourseKey here because it makes sure the same format is + # Have to use older key format here because it makes sure the same format is # always used, preventing duplicate keys. - return SlashSeparatedCourseKey(org, course, url_name) + return CourseKey.from_string('/'.join([org, course, url_name])) def load_extra_content(self, system, course_descriptor, category, base_dir, course_dir, url_name): self._load_extra_content(system, course_descriptor, category, base_dir, course_dir) diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index 498e145479..4289a52bb9 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -17,21 +17,18 @@ import unittest from contextlib import contextmanager, nested from functools import wraps -from lazy import lazy -from mock import Mock, patch -from operator import attrgetter +from mock import Mock from path import Path as path -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from xblock.field_data import DictFieldData -from xblock.fields import ScopeIds, Scope, Reference, ReferenceList, ReferenceValueDict +from xblock.fields import ScopeIds, Reference, ReferenceList, ReferenceValueDict from xmodule.assetstore import AssetMetadata from xmodule.error_module import ErrorDescriptor from xmodule.mako_module import MakoDescriptorSystem from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES, ModuleStoreDraftAndPublished -from xmodule.modulestore.inheritance import InheritanceMixin, own_metadata -from xmodule.modulestore.mongo.draft import DraftModuleStore +from xmodule.modulestore.draft_and_published import ModuleStoreDraftAndPublished +from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.xml import CourseLocationManager from xmodule.x_module import ModuleSystem, XModuleDescriptor, XModuleMixin @@ -86,7 +83,7 @@ class TestModuleSystem(ModuleSystem): # pylint: disable=abstract-method return rt_repr -def get_test_system(course_id=SlashSeparatedCourseKey('org', 'course', 'run')): +def get_test_system(course_id=CourseKey.from_string('/'.join(['org', 'course', 'run']))): """ Construct a test ModuleSystem instance. diff --git a/common/lib/xmodule/xmodule/tests/test_conditional.py b/common/lib/xmodule/xmodule/tests/test_conditional.py index 17e06b0704..73d9ddd041 100644 --- a/common/lib/xmodule/xmodule/tests/test_conditional.py +++ b/common/lib/xmodule/xmodule/tests/test_conditional.py @@ -8,7 +8,8 @@ from mock import Mock, patch from xblock.field_data import DictFieldData from xblock.fields import ScopeIds from xmodule.error_module import NonStaffErrorDescriptor -from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location +from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.locations import Location from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, CourseLocationManager from xmodule.conditional_module import ConditionalDescriptor from xmodule.tests import DATA_DIR, get_test_system, get_test_descriptor_system @@ -29,7 +30,7 @@ class DummySystem(ImportSystem): super(DummySystem, self).__init__( xmlstore=xmlstore, - course_id=SlashSeparatedCourseKey(ORG, COURSE, 'test_run'), + course_id=CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])), course_dir='test_dir', error_tracker=Mock(), load_error_modules=load_error_modules, diff --git a/common/lib/xmodule/xmodule/tests/test_content.py b/common/lib/xmodule/xmodule/tests/test_content.py index 76b199628b..ef34f67285 100644 --- a/common/lib/xmodule/xmodule/tests/test_content.py +++ b/common/lib/xmodule/xmodule/tests/test_content.py @@ -8,7 +8,8 @@ from path import Path as path from xmodule.contentstore.content import StaticContent, StaticContentStream from xmodule.contentstore.content import ContentStore -from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation +from opaque_keys.edx.keys import CourseKey +from opaque_keys.edx.locations import AssetLocation from xmodule.static_content import _write_js, _list_descriptors SAMPLE_STRING = """ @@ -158,7 +159,7 @@ class ContentTest(unittest.TestCase): # We had a bug that __ got converted into a single _. Make sure that substitution of INVALID_CHARS (like space) # still happen. asset_location = StaticContent.compute_location( - SlashSeparatedCourseKey('mitX', '400', 'ignore'), 'subs__1eo_jXvZnE .srt.sjson' + CourseKey.from_string('mitX/400/ignore'), 'subs__1eo_jXvZnE .srt.sjson' ) self.assertEqual( AssetLocation(u'mitX', u'400', u'ignore', u'asset', u'subs__1eo_jXvZnE_.srt.sjson', None), diff --git a/common/lib/xmodule/xmodule/tests/test_course_module.py b/common/lib/xmodule/xmodule/tests/test_course_module.py index 99e89b680e..94c97097a7 100644 --- a/common/lib/xmodule/xmodule/tests/test_course_module.py +++ b/common/lib/xmodule/xmodule/tests/test_course_module.py @@ -12,7 +12,7 @@ from xblock.runtime import KvsFieldData, DictKeyValueStore import xmodule.course_module from xmodule.modulestore.xml import ImportSystem, XMLModuleStore -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey ORG = 'test_org' @@ -39,7 +39,7 @@ class DummySystem(ImportSystem): xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) - course_id = SlashSeparatedCourseKey(ORG, COURSE, 'test_run') + course_id = CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])) course_dir = "test_dir" error_tracker = Mock() diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index cd752004eb..efad2d853a 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -20,7 +20,6 @@ from xmodule.fields import Date from xmodule.tests import DATA_DIR from xmodule.modulestore.inheritance import InheritanceMixin from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xblock.core import XBlock from xblock.fields import Scope, String, Integer @@ -40,7 +39,7 @@ class DummySystem(ImportSystem): xmlstore = LibraryXMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) else: xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) - course_id = SlashSeparatedCourseKey(ORG, COURSE, 'test_run') + course_id = CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])) course_dir = "test_dir" error_tracker = Mock() diff --git a/lms/djangoapps/branding/__init__.py b/lms/djangoapps/branding/__init__.py index cd603b03a7..b8d909af53 100644 --- a/lms/djangoapps/branding/__init__.py +++ b/lms/djangoapps/branding/__init__.py @@ -7,11 +7,9 @@ This module provides functions to retrieve basic branded parts such as the site visible courses, university name and logo. """ -from xmodule.modulestore.django import modulestore -from xmodule.course_module import CourseDescriptor from django.conf import settings -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -53,7 +51,7 @@ def get_visible_courses(org=None, filter_=None): subdomain = configuration_helpers.get_value('subdomain', 'default') if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG: filtered_visible_ids = frozenset( - [SlashSeparatedCourseKey.from_deprecated_string(c) for c in settings.COURSE_LISTINGS[subdomain]] + [CourseKey.from_string(c) for c in settings.COURSE_LISTINGS[subdomain]] ) if filtered_visible_ids: diff --git a/lms/djangoapps/bulk_email/forms.py b/lms/djangoapps/bulk_email/forms.py index 0b3097eebc..cf3fdf6bd2 100644 --- a/lms/djangoapps/bulk_email/forms.py +++ b/lms/djangoapps/bulk_email/forms.py @@ -7,7 +7,6 @@ from django import forms from django.core.exceptions import ValidationError from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from bulk_email.models import COURSE_EMAIL_MESSAGE_BODY_TAG, CourseAuthorization, CourseEmailTemplate from xmodule.modulestore.django import modulestore @@ -84,13 +83,10 @@ class CourseAuthorizationAdminForm(forms.ModelForm): try: course_key = CourseKey.from_string(cleaned_id) except InvalidKeyError: - try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(cleaned_id) - except InvalidKeyError: - msg = u'Course id invalid.' - msg += u' --- Entered course id was: "{0}". '.format(cleaned_id) - msg += 'Please recheck that you have supplied a valid course id.' - raise forms.ValidationError(msg) + msg = u'Course id invalid.' + msg += u' --- Entered course id was: "{0}". '.format(cleaned_id) + msg += 'Please recheck that you have supplied a valid course id.' + raise forms.ValidationError(msg) if not modulestore().has_course(course_key): msg = u'COURSE NOT FOUND' diff --git a/lms/djangoapps/certificates/management/commands/cert_whitelist.py b/lms/djangoapps/certificates/management/commands/cert_whitelist.py index 8a668c5c37..3666306137 100644 --- a/lms/djangoapps/certificates/management/commands/cert_whitelist.py +++ b/lms/djangoapps/certificates/management/commands/cert_whitelist.py @@ -8,9 +8,7 @@ from optparse import make_option from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from certificates.models import CertificateWhitelist @@ -92,12 +90,7 @@ class Command(BaseCommand): cert_whitelist.save() # try to parse the serialized course key into a CourseKey - try: - course = CourseKey.from_string(course_id) - except InvalidKeyError: - print(("Course id {} could not be parsed as a CourseKey; " - "falling back to SSCK.from_dep_str").format(course_id)) - course = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course = CourseKey.from_string(course_id) if options['add'] and options['del']: raise CommandError("Either remove or add a user, not both") diff --git a/lms/djangoapps/certificates/management/commands/gen_cert_report.py b/lms/djangoapps/certificates/management/commands/gen_cert_report.py index 6cc36ca1c4..b658621464 100644 --- a/lms/djangoapps/certificates/management/commands/gen_cert_report.py +++ b/lms/djangoapps/certificates/management/commands/gen_cert_report.py @@ -7,9 +7,7 @@ from optparse import make_option from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError from django.db.models import Count -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from certificates.models import GeneratedCertificate @@ -51,12 +49,7 @@ class Command(BaseCommand): # Find all courses that have ended if options['course']: - try: - course_id = CourseKey.from_string(options['course']) - except InvalidKeyError: - print ("Course id {} could not be parsed as a CourseKey; " - "falling back to SSCK.from_dep_str").format(options['course']) - course_id = SlashSeparatedCourseKey.from_deprecated_string(options['course']) + course_id = CourseKey.from_string(options['course']) else: raise CommandError("You must specify a course") diff --git a/lms/djangoapps/certificates/management/commands/regenerate_user.py b/lms/djangoapps/certificates/management/commands/regenerate_user.py index ec3857ad30..b6c441c83a 100644 --- a/lms/djangoapps/certificates/management/commands/regenerate_user.py +++ b/lms/djangoapps/certificates/management/commands/regenerate_user.py @@ -6,9 +6,7 @@ from optparse import make_option from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from badges.events.course_complete import get_completion_badge from certificates.api import regenerate_user_certificates @@ -76,17 +74,7 @@ class Command(BaseCommand): if options['course']: # try to parse out the course from the serialized form - try: - course_id = CourseKey.from_string(options['course']) - except InvalidKeyError: - LOGGER.warning( - ( - u"Course id %s could not be parsed as a CourseKey; " - u"falling back to SlashSeparatedCourseKey.from_deprecated_string()" - ), - options['course'] - ) - course_id = SlashSeparatedCourseKey.from_deprecated_string(options['course']) + course_id = CourseKey.from_string(options['course']) else: raise CommandError("You must specify a course") diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py index b016848780..ac4ef411c4 100644 --- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py +++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py @@ -8,9 +8,7 @@ from optparse import make_option from django.contrib.auth.models import User from django.core.management.base import BaseCommand, CommandError -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from pytz import UTC from certificates.api import generate_user_certificates @@ -88,18 +86,7 @@ class Command(BaseCommand): STATUS_INTERVAL = 500 if options['course']: - # try to parse out the course from the serialized form - try: - course = CourseKey.from_string(options['course']) - except InvalidKeyError: - LOGGER.warning( - ( - u"Course id %s could not be parsed as a CourseKey; " - u"falling back to SlashSeparatedCourseKey.from_deprecated_string()" - ), - options['course'] - ) - course = SlashSeparatedCourseKey.from_deprecated_string(options['course']) + course = CourseKey.from_string(options['course']) ended_courses = [course] else: raise CommandError("You must specify a course") diff --git a/lms/djangoapps/certificates/views/xqueue.py b/lms/djangoapps/certificates/views/xqueue.py index ce13ed5bf6..c187c1c883 100644 --- a/lms/djangoapps/certificates/views/xqueue.py +++ b/lms/djangoapps/certificates/views/xqueue.py @@ -9,7 +9,7 @@ from django.db import transaction from django.http import Http404, HttpResponse, HttpResponseForbidden from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey import dogstats_wrapper as dog_stats_api from capa.xqueue_interface import XQUEUE_METRIC_NAME @@ -42,7 +42,7 @@ def request_certificate(request): if request.user.is_authenticated(): username = request.user.username student = User.objects.get(username=username) - course_key = SlashSeparatedCourseKey.from_deprecated_string(request.POST.get('course_id')) + course_key = CourseKey.from_string(request.POST.get('course_id')) course = modulestore().get_course(course_key, depth=2) status = certificate_status_for_student(student, course_key)['status'] @@ -72,7 +72,7 @@ def update_certificate(request): xqueue_header = json.loads(request.POST.get('xqueue_header')) try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(xqueue_body['course_id']) + course_key = CourseKey.from_string(xqueue_body['course_id']) cert = GeneratedCertificate.eligible_certificates.get( user__username=xqueue_body['username'], diff --git a/lms/djangoapps/class_dashboard/views.py b/lms/djangoapps/class_dashboard/views.py index be090347a4..596753c88e 100644 --- a/lms/djangoapps/class_dashboard/views.py +++ b/lms/djangoapps/class_dashboard/views.py @@ -6,7 +6,7 @@ import json import logging from django.http import HttpResponse -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from class_dashboard import dashboard_data from courseware.access import has_access @@ -38,7 +38,7 @@ def all_sequential_open_distrib(request, course_id): data = {} # Only instructor for this particular course can request this information - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) if has_instructor_access_for_class(request.user, course_key): try: data = dashboard_data.get_d3_sequential_open_distrib(course_key) @@ -64,7 +64,7 @@ def all_problem_grade_distribution(request, course_id): data = {} # Only instructor for this particular course can request this information - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) if has_instructor_access_for_class(request.user, course_key): try: data = dashboard_data.get_d3_problem_grade_distrib(course_key) @@ -95,7 +95,7 @@ def section_problem_grade_distrib(request, course_id, section): data = {} # Only instructor for this particular course can request this information - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) if has_instructor_access_for_class(request.user, course_key): try: data = dashboard_data.get_d3_section_grade_distrib(course_key, section) diff --git a/lms/djangoapps/course_structure_api/v0/tests.py b/lms/djangoapps/course_structure_api/v0/tests.py index 82b8368625..3f4338769f 100644 --- a/lms/djangoapps/course_structure_api/v0/tests.py +++ b/lms/djangoapps/course_structure_api/v0/tests.py @@ -100,7 +100,7 @@ class CourseViewTestsMixin(object): start=datetime(2014, 6, 16, 14, 30), end=datetime(2015, 1, 16), org="MTD", - # Use mongo so that we can get a test with a SlashSeparatedCourseKey + # Use mongo so that we can get a test with the deprecated key format. default_store=ModuleStoreEnum.Type.mongo ) diff --git a/lms/djangoapps/course_wiki/views.py b/lms/djangoapps/course_wiki/views.py index 7dde563838..e6cd127870 100644 --- a/lms/djangoapps/course_wiki/views.py +++ b/lms/djangoapps/course_wiki/views.py @@ -8,7 +8,7 @@ import re from django.conf import settings from django.shortcuts import redirect from django.utils.translation import ugettext as _ -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from wiki.core.exceptions import NoRootURL from wiki.models import Article, URLPath @@ -36,7 +36,7 @@ def course_wiki_redirect(request, course_id, wiki_path=""): # pylint: disable=u as it's home page. A course's wiki must be an article on the root (for example, "/6.002x") to keep things simple. """ - course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id)) + course = get_course_by_id(CourseKey.from_string(course_id)) course_slug = course_wiki_slug(course) valid_slug = True diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 3aa22050a6..02e8e4b0af 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -19,7 +19,6 @@ from django.views.decorators.csrf import csrf_exempt from edx_proctoring.services import ProctoringService from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, UsageKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from requests.auth import HTTPBasicAuth from xblock.core import XBlock from xblock.django.request import django_to_webob_request, webob_to_django_response @@ -886,7 +885,7 @@ def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_inf user = request.user try: - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) usage_key = course_id.make_usage_key_from_deprecated_string(unquote_slashes(usage_id)) except InvalidKeyError: raise Http404("Invalid location") @@ -1038,7 +1037,7 @@ def xblock_view(request, course_id, usage_id, view_name): raise PermissionDenied try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) except InvalidKeyError: raise Http404("Invalid location") diff --git a/lms/djangoapps/dashboard/git_import.py b/lms/djangoapps/dashboard/git_import.py index 283f40821a..eb0dd1ee6c 100644 --- a/lms/djangoapps/dashboard/git_import.py +++ b/lms/djangoapps/dashboard/git_import.py @@ -15,9 +15,7 @@ from django.core import management from django.core.management.base import CommandError from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from dashboard.models import CourseImportLog @@ -295,10 +293,7 @@ def add_repo(repo, rdir_in, branch=None): match = re.search(r'(?ms)===> IMPORTING courselike (\S+)', ret_import) if match: course_id = match.group(1) - try: - course_key = CourseKey.from_string(course_id) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) cdir = '{0}/{1}'.format(git_repo_dir, course_key.course) log.debug('Studio course dir = %s', cdir) diff --git a/lms/djangoapps/dashboard/sysadmin.py b/lms/djangoapps/dashboard/sysadmin.py index 2df1caa66a..41242cc245 100644 --- a/lms/djangoapps/dashboard/sysadmin.py +++ b/lms/djangoapps/dashboard/sysadmin.py @@ -26,7 +26,7 @@ from django.views.decorators.cache import cache_control from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import condition from django.views.generic.base import TemplateView -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from path import Path as path import dashboard.git_import as git_import @@ -472,7 +472,7 @@ class Courses(SysadminDashboardView): elif action == 'del_course': course_id = request.POST.get('course_id', '').strip() - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course_found = False if course_key in courses: course_found = True @@ -584,7 +584,7 @@ class GitLogs(TemplateView): course_id = kwargs.get('course_id') if course_id: - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) page_size = 10 diff --git a/lms/djangoapps/grades/management/commands/get_grades.py b/lms/djangoapps/grades/management/commands/get_grades.py index 93f072488a..2cfe4a8cf6 100644 --- a/lms/djangoapps/grades/management/commands/get_grades.py +++ b/lms/djangoapps/grades/management/commands/get_grades.py @@ -11,9 +11,7 @@ from django.contrib.auth.models import User from django.core.handlers.base import BaseHandler from django.core.management.base import BaseCommand, CommandError from django.test.client import RequestFactory -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from lms.djangoapps.certificates.models import GeneratedCertificate from lms.djangoapps.courseware import courses @@ -81,12 +79,7 @@ class Command(BaseCommand): # parse out the course into a coursekey if options['course']: - try: - course_key = CourseKey.from_string(options['course']) - # if it's not a new-style course key, parse it from an old-style - # course key - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course']) + course_key = CourseKey.from_string(options['course']) print "Fetching enrolled students for {0}".format(course_key) enrolled_students = User.objects.filter( diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index cb9e2852b8..ae87e1d753 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -32,7 +32,6 @@ from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_http_methods, require_POST from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, UsageKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey import instructor_analytics.basic import instructor_analytics.csvs @@ -313,7 +312,7 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man ): return HttpResponseForbidden() - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) warnings = [] row_errors = [] general_errors = [] @@ -620,7 +619,7 @@ def students_update_enrollment(request, course_id): ] } """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) action = request.POST.get('action') identifiers_raw = request.POST.get('identifiers') identifiers = _split_input_list(identifiers_raw) @@ -761,7 +760,7 @@ def bulk_beta_modify_access(request, course_id): anything split_input_list can handle. - action is one of ['add', 'remove'] """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) action = request.POST.get('action') identifiers_raw = request.POST.get('identifiers') identifiers = _split_input_list(identifiers_raw) @@ -849,7 +848,7 @@ def modify_access(request, course_id): rolename is one of ['instructor', 'staff', 'beta', 'ccx_coach'] action is one of ['allow', 'revoke'] """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'instructor', course_id, depth=None ) @@ -932,7 +931,7 @@ def list_course_role_members(request, course_id): ] } """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'instructor', course_id, depth=None ) @@ -1008,7 +1007,7 @@ def get_grading_config(request, course_id): """ Respond with json which contains a html formatted grade summary. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'staff', course_id, depth=None ) @@ -1028,7 +1027,7 @@ def get_sale_records(request, course_id, csv=False): # pylint: disable=unused-a """ return the summary of all sales records for a particular course """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) query_features = [ 'company_name', 'company_contact_name', 'company_contact_email', 'total_codes', 'total_used_codes', 'total_amount', 'created', 'customer_reference_number', 'recipient_name', 'recipient_email', 'created_by', @@ -1059,7 +1058,7 @@ def get_sale_order_records(request, course_id): # pylint: disable=unused-argume """ return the summary of all sales records for a particular course """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) query_features = [ ('id', 'Order Id'), ('company_name', 'Company Name'), @@ -1117,7 +1116,7 @@ def sale_validation(request, course_id): except KeyError: return HttpResponseBadRequest("Missing required event_type parameter") - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) try: obj_invoice = CourseRegistrationCodeInvoiceItem.objects.select_related('invoice').get( invoice_id=invoice_number, @@ -1328,7 +1327,7 @@ def add_users_to_cohorts(request, course_id): containing cohort assignments for users. This method spawns a celery task to do the assignments, and a CSV file with results is provided via data downloads. """ - course_key = SlashSeparatedCourseKey.from_string(course_id) + course_key = CourseKey.from_string(course_id) try: def validator(file_storage, file_to_validate): @@ -1370,7 +1369,7 @@ def get_coupon_codes(request, course_id): # pylint: disable=unused-argument """ Respond with csv which contains a summary of all Active Coupons. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) coupons = Coupon.objects.filter(course_id=course_id) query_features = [ @@ -1403,7 +1402,7 @@ def get_enrollment_report(request, course_id): """ get the enrollment report for the particular course. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) report_type = _('detailed enrollment') lms.djangoapps.instructor_task.api.submit_detailed_enrollment_features_csv(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -1422,7 +1421,7 @@ def get_exec_summary_report(request, course_id): """ get the executive summary report for the particular course. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) report_type = _('executive summary') lms.djangoapps.instructor_task.api.submit_executive_summary_report(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -1440,7 +1439,7 @@ def get_course_survey_results(request, course_id): """ get the survey results report for the particular course. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) report_type = _('survey') lms.djangoapps.instructor_task.api.submit_course_survey_report(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -1558,7 +1557,7 @@ def get_registration_codes(request, course_id): """ Respond with csv which contains a summary of all Registration Codes. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) #filter all the course registration codes registration_codes = CourseRegistrationCode.objects.filter( @@ -1764,7 +1763,7 @@ def active_registration_codes(request, course_id): """ Respond with csv which contains a summary of all Active Registration Codes. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) # find all the registration codes in this course registration_codes_list = CourseRegistrationCode.objects.filter( @@ -1795,7 +1794,7 @@ def spent_registration_codes(request, course_id): """ Respond with csv which contains a summary of all Spent(used) Registration Codes. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) # find the redeemed registration codes if any exist in the db code_redemption_set = RegistrationCodeRedemption.objects.select_related('registration_code').filter( @@ -1828,7 +1827,7 @@ def get_anon_ids(request, course_id): # pylint: disable=unused-argument # TODO: the User.objects query and CSV generation here could be # centralized into instructor_analytics. Currently instructor_analytics # has similar functionality but not quite what's needed. - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) def csv_response(filename, header, rows): """Returns a CSV http response for the given header and rows (excel/utf-8).""" @@ -1870,7 +1869,7 @@ def get_student_progress_url(request, course_id): 'progress_url': '/../...' } """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) user = get_student_from_identifier(request.POST.get('unique_student_identifier')) progress_url = reverse('student_progress', kwargs={'course_id': course_id.to_deprecated_string(), 'student_id': user.id}) @@ -1909,7 +1908,7 @@ def reset_student_attempts(request, course_id): requires instructor access mutually exclusive with all_students """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'staff', course_id, depth=None ) @@ -1993,7 +1992,7 @@ def reset_student_attempts_for_entrance_exam(request, course_id): # pylint: dis requires instructor access mutually exclusive with all_students """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'staff', course_id, depth=None ) @@ -2065,7 +2064,7 @@ def rescore_problem(request, course_id): all_students and unique_student_identifier cannot both be present. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) problem_to_reset = strip_if_string(request.POST.get('problem_to_reset')) student_identifier = request.POST.get('unique_student_identifier', None) student = None @@ -2192,7 +2191,7 @@ def rescore_entrance_exam(request, course_id): all_students and unique_student_identifier cannot both be present. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_with_access( request.user, 'staff', course_id, depth=None ) @@ -2241,7 +2240,7 @@ def list_background_email_tasks(request, course_id): # pylint: disable=unused-a """ List background email tasks. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) task_type = 'bulk_course_email' # Specifying for the history of a single task type tasks = lms.djangoapps.instructor_task.api.get_instructor_task_history( @@ -2263,7 +2262,7 @@ def list_email_content(request, course_id): # pylint: disable=unused-argument """ List the content of bulk emails sent """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) task_type = 'bulk_course_email' # First get tasks list of bulk emails sent emails = lms.djangoapps.instructor_task.api.get_instructor_task_history(course_id, task_type=task_type) @@ -2288,7 +2287,7 @@ def list_instructor_tasks(request, course_id): - `problem_location_str` and `unique_student_identifier` lists task history for problem AND student (intersection) """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) problem_location_str = strip_if_string(request.POST.get('problem_location_str', False)) student = request.POST.get('unique_student_identifier', None) if student is not None: @@ -2332,7 +2331,7 @@ def list_entrance_exam_instructor_tasks(request, course_id): # pylint: disable= - unique_student_identifier is an email or username - all_students is a boolean """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_by_id(course_id) student = request.POST.get('unique_student_identifier', None) if student is not None: @@ -2370,7 +2369,7 @@ def list_report_downloads(_request, course_id): """ List grade CSV files that are available for download for this course. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD') response_payload = { @@ -2391,7 +2390,7 @@ def list_financial_report_downloads(_request, course_id): """ List grade CSV files that are available for download for this course. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) report_store = ReportStore.from_config(config_name='FINANCIAL_REPORTS') response_payload = { @@ -2413,7 +2412,7 @@ def export_ora2_data(request, course_id): """ Pushes a Celery task which will aggregate ora2 responses for a course into a .csv """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) report_type = _('ORA data') lms.djangoapps.instructor_task.api.submit_export_ora2_data(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -2432,7 +2431,7 @@ def calculate_grades_csv(request, course_id): AlreadyRunningError is raised if the course's grades are already being updated. """ report_type = _('grade') - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) lms.djangoapps.instructor_task.api.submit_calculate_grades_csv(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -2453,7 +2452,7 @@ def problem_grade_report(request, course_id): AlreadyRunningError is raised if the course's grades are already being updated. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) report_type = _('problem grade') lms.djangoapps.instructor_task.api.submit_problem_grade_report(request, course_key) success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type) @@ -2477,7 +2476,7 @@ def list_forum_members(request, course_id): Takes query parameter `rolename`. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_by_id(course_id) has_instructor_access = has_access(request.user, 'instructor', course) has_forum_admin = has_forum_access( @@ -2634,7 +2633,7 @@ def update_forum_role_membership(request, course_id): FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA] - `action` is one of ['allow', 'revoke'] """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) course = get_course_by_id(course_id) has_instructor_access = has_access(request.user, 'instructor', course) has_forum_admin = has_forum_access( @@ -2711,7 +2710,7 @@ def change_due_date(request, course_id): """ Grants a due date extension to a student for a particular unit. """ - course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id)) + course = get_course_by_id(CourseKey.from_string(course_id)) student = require_student_from_identifier(request.POST.get('student')) unit = find_unit(course, request.POST.get('url')) due_date = parse_datetime(request.POST.get('due_datetime')) @@ -2733,7 +2732,7 @@ def reset_due_date(request, course_id): """ Rescinds a due date extension for a student on a particular unit. """ - course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id)) + course = get_course_by_id(CourseKey.from_string(course_id)) student = require_student_from_identifier(request.POST.get('student')) unit = find_unit(course, request.POST.get('url')) set_due_date_extension(course, unit, student, None) @@ -2760,7 +2759,7 @@ def show_unit_extensions(request, course_id): """ Shows all of the students which have due date extensions for the given unit. """ - course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id)) + course = get_course_by_id(CourseKey.from_string(course_id)) unit = find_unit(course, request.POST.get('url')) return JsonResponse(dump_module_extensions(course, unit)) @@ -2777,7 +2776,7 @@ def show_student_extensions(request, course_id): particular course. """ student = require_student_from_identifier(request.POST.get('student')) - course = get_course_by_id(SlashSeparatedCourseKey.from_deprecated_string(course_id)) + course = get_course_by_id(CourseKey.from_string(course_id)) return JsonResponse(dump_student_extensions(course, student)) @@ -2863,7 +2862,7 @@ def mark_student_can_skip_entrance_exam(request, course_id): # pylint: disable= Mark a student to skip entrance exam. Takes `unique_student_identifier` as required POST parameter. """ - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) student_identifier = request.POST.get('unique_student_identifier') student = get_student_from_identifier(student_identifier) diff --git a/lms/djangoapps/instructor/views/coupons.py b/lms/djangoapps/instructor/views/coupons.py index 1b3e8bd921..bf17c234c6 100644 --- a/lms/djangoapps/instructor/views/coupons.py +++ b/lms/djangoapps/instructor/views/coupons.py @@ -9,7 +9,7 @@ from django.contrib.auth.decorators import login_required from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import ugettext as _ from django.views.decorators.http import require_POST -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import CourseKey from shoppingcart.models import Coupon, CourseRegistrationCode from util.json_request import JsonResponse @@ -57,7 +57,7 @@ def add_coupon(request, course_id): # check if the code is already in the Coupons Table and active try: - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_id = CourseKey.from_string(course_id) coupon = Coupon.objects.get(is_active=True, code=code, course_id=course_id) except Coupon.DoesNotExist: # check if the coupon code is in the CourseRegistrationCode Table diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py index 14368e72e2..4329834fad 100644 --- a/lms/djangoapps/instructor/views/instructor_dashboard.py +++ b/lms/djangoapps/instructor/views/instructor_dashboard.py @@ -20,7 +20,6 @@ from django.views.decorators.http import require_POST from mock import patch from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xblock.field_data import DictFieldData from xblock.fields import ScopeIds @@ -411,7 +410,7 @@ def set_course_mode_price(request, course_id): status=400) # status code 400: Bad Request currency = request.POST['currency'] - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course_honor_mode = CourseMode.objects.filter(mode_slug='honor', course_id=course_key) if not course_honor_mode: diff --git a/lms/djangoapps/instructor/views/registration_codes.py b/lms/djangoapps/instructor/views/registration_codes.py index 7e72566c2a..ad8c00fe6e 100644 --- a/lms/djangoapps/instructor/views/registration_codes.py +++ b/lms/djangoapps/instructor/views/registration_codes.py @@ -7,7 +7,7 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ from django.views.decorators.cache import cache_control from django.views.decorators.http import require_GET, require_POST -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import CourseKey from courseware.courses import get_course_by_id from lms.djangoapps.instructor.enrollment import get_email_params, send_mail_to_student @@ -27,7 +27,7 @@ def look_up_registration_code(request, course_id): Look for the registration_code in the database. and check if it is still valid, allowed to redeem or not. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) code = request.GET.get('registration_code') course = get_course_by_id(course_key, depth=0) try: @@ -65,7 +65,7 @@ def registration_code_details(request, course_id): 3) Unredeem. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) code = request.POST.get('registration_code') action_type = request.POST.get('action_type') course = get_course_by_id(course_key, depth=0) diff --git a/lms/djangoapps/notes/api.py b/lms/djangoapps/notes/api.py index a892bf05e5..ebcc5c061c 100644 --- a/lms/djangoapps/notes/api.py +++ b/lms/djangoapps/notes/api.py @@ -5,7 +5,7 @@ import logging from django.contrib.auth.decorators import login_required from django.core.exceptions import ValidationError from django.http import Http404, HttpResponse -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from courseware.courses import get_course_with_access from notes.models import Note @@ -51,7 +51,7 @@ def api_request(request, course_id, **kwargs): disabled for the course. ''' assert isinstance(course_id, basestring) - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) # Verify that the api should be accessible to this course if not api_enabled(request, course_key): diff --git a/lms/djangoapps/notes/tests.py b/lms/djangoapps/notes/tests.py index bf14fb8865..12cafcd0c4 100644 --- a/lms/djangoapps/notes/tests.py +++ b/lms/djangoapps/notes/tests.py @@ -10,7 +10,7 @@ from django.core.urlresolvers import reverse from django.test import RequestFactory, TestCase from django.test.client import Client from mock import Mock, patch -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import CourseLocator from courseware.tabs import CourseTab, get_course_tab_list from notes import api, models, utils @@ -107,7 +107,7 @@ class ApiTest(TestCase): self.student = User.objects.create_user('student', 'student@test.com', self.password) self.student2 = User.objects.create_user('student2', 'student2@test.com', self.password) self.instructor = User.objects.create_user('instructor', 'instructor@test.com', self.password) - self.course_key = SlashSeparatedCourseKey('HarvardX', 'CB22x', 'The_Ancient_Greek_Hero') + self.course_key = CourseLocator('HarvardX', 'CB22x', 'The_Ancient_Greek_Hero') self.note = { 'user': self.student, 'course_id': self.course_key, @@ -394,7 +394,7 @@ class NoteTest(TestCase): self.password = 'abc' self.student = User.objects.create_user('student', 'student@test.com', self.password) - self.course_key = SlashSeparatedCourseKey('HarvardX', 'CB22x', 'The_Ancient_Greek_Hero') + self.course_key = CourseLocator('HarvardX', 'CB22x', 'The_Ancient_Greek_Hero') self.note = { 'user': self.student, 'course_id': self.course_key, diff --git a/lms/djangoapps/notes/views.py b/lms/djangoapps/notes/views.py index 47690c4e41..339d38c00e 100644 --- a/lms/djangoapps/notes/views.py +++ b/lms/djangoapps/notes/views.py @@ -6,7 +6,7 @@ from django.conf import settings from django.contrib.auth.decorators import login_required from django.http import Http404 from django.utils.translation import ugettext_noop -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from courseware.courses import get_course_with_access from courseware.tabs import EnrolledTab @@ -19,7 +19,7 @@ from xmodule.annotator_token import retrieve_token @login_required def notes(request, course_id): ''' Displays the student's notes. ''' - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key) if not notes_enabled_for_course(course): raise Http404 diff --git a/lms/djangoapps/shoppingcart/views.py b/lms/djangoapps/shoppingcart/views.py index 2273851482..cc094a5301 100644 --- a/lms/djangoapps/shoppingcart/views.py +++ b/lms/djangoapps/shoppingcart/views.py @@ -24,7 +24,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods, require_POST from ipware.ip import get_ip from opaque_keys import InvalidKeyError -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import CourseLocator from course_modes.models import CourseMode @@ -110,7 +110,7 @@ def add_course_to_cart(request, course_id): log.info(u"Anon user trying to add course %s to cart", course_id) return HttpResponseForbidden(_('You must be logged-in to add to a shopping cart')) cart = Order.get_cart_for_user(request.user) - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) # All logging from here handled by the model try: paid_course_item = PaidCourseRegistration.add_to_order(cart, course_key) diff --git a/lms/djangoapps/staticbook/views.py b/lms/djangoapps/staticbook/views.py index 78f9bec0bc..ba41ad0b4b 100644 --- a/lms/djangoapps/staticbook/views.py +++ b/lms/djangoapps/staticbook/views.py @@ -4,7 +4,7 @@ Views for serving static textbooks. from django.contrib.auth.decorators import login_required from django.http import Http404 -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from courseware.access import has_access from courseware.courses import get_course_with_access @@ -19,7 +19,7 @@ def index(request, course_id, book_index, page=None): """ Serve static image-based textbooks. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key) staff_access = bool(has_access(request.user, 'staff', course)) @@ -76,7 +76,7 @@ def pdf_index(request, course_id, book_index, chapter=None, page=None): page: (optional) one-based page number to display within the PDF. Defaults to first page. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key) staff_access = bool(has_access(request.user, 'staff', course)) @@ -144,7 +144,7 @@ def html_index(request, course_id, book_index, chapter=None): Defaults to first chapter. Specifying this assumes that there are separate HTML files for each chapter in a textbook. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key) staff_access = bool(has_access(request.user, 'staff', course)) notes_enabled = notes_enabled_for_course(course) diff --git a/lms/djangoapps/support/views/refund.py b/lms/djangoapps/support/views/refund.py index bc4104688b..dd5e65e4dd 100644 --- a/lms/djangoapps/support/views/refund.py +++ b/lms/djangoapps/support/views/refund.py @@ -21,7 +21,6 @@ from django.utils.translation import ugettext as _ from django.views.generic.edit import FormView from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from student.models import CourseEnrollment from support.decorators import require_support_permission @@ -57,7 +56,7 @@ class RefundForm(forms.Form): course_key = CourseKey.from_string(course_id) except InvalidKeyError: try: - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) except InvalidKeyError: raise forms.ValidationError(_("Invalid course id")) return course_key diff --git a/lms/lib/courseware_search/lms_result_processor.py b/lms/lib/courseware_search/lms_result_processor.py index 50ae2ad4a6..c1045c9de3 100644 --- a/lms/lib/courseware_search/lms_result_processor.py +++ b/lms/lib/courseware_search/lms_result_processor.py @@ -4,7 +4,7 @@ This file contains implementation override of SearchResultProcessor which will a * Confirms user access to object """ from django.core.urlresolvers import reverse -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from search.result_processor import SearchResultProcessor from lms.djangoapps.course_blocks.api import get_course_blocks @@ -22,7 +22,7 @@ class LmsSearchResultProcessor(SearchResultProcessor): def get_course_key(self): """ fetch course key object from string representation - retain result for subsequent uses """ if self._course_key is None: - self._course_key = SlashSeparatedCourseKey.from_deprecated_string(self._results_fields["course"]) + self._course_key = CourseKey.from_string(self._results_fields["course"]) return self._course_key def get_usage_key(self): diff --git a/lms/lib/courseware_search/lms_search_initializer.py b/lms/lib/courseware_search/lms_search_initializer.py index 0c62d05c3f..d22208675d 100644 --- a/lms/lib/courseware_search/lms_search_initializer.py +++ b/lms/lib/courseware_search/lms_search_initializer.py @@ -3,9 +3,7 @@ This file contains implementation override of SearchInitializer which will allow * To set initial set of masquerades and other parameters """ -from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from search.initializer import SearchInitializer from courseware.access import has_access @@ -17,9 +15,6 @@ class LmsSearchInitializer(SearchInitializer): def initialize(self, **kwargs): if 'request' in kwargs and kwargs['request'] and kwargs['course_id']: request = kwargs['request'] - try: - course_key = CourseKey.from_string(kwargs['course_id']) - except InvalidKeyError: - course_key = SlashSeparatedCourseKey.from_deprecated_string(kwargs['course_id']) + course_key = CourseKey.from_string(kwargs['course_id']) staff_access = bool(has_access(request.user, 'staff', course_key)) setup_masquerade(request, course_key, staff_access) diff --git a/openedx/core/djangoapps/course_groups/views.py b/openedx/core/djangoapps/course_groups/views.py index 53fc71cb45..fb0a04bbb9 100644 --- a/openedx/core/djangoapps/course_groups/views.py +++ b/openedx/core/djangoapps/course_groups/views.py @@ -16,12 +16,9 @@ from django.utils.translation import ugettext from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_http_methods, require_POST from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import SlashSeparatedCourseKey from courseware.courses import get_course_with_access from edxmako.shortcuts import render_to_response -from lms.djangoapps.django_comment_client.constants import TYPE_ENTRY -from lms.djangoapps.django_comment_client.utils import get_discussion_categories_ids, get_discussion_category_map from util.json_request import JsonResponse, expect_json from . import cohorts @@ -145,7 +142,7 @@ def cohort_handler(request, course_key_string, cohort_id=None): If no cohort ID is specified, creates a new cohort and returns the JSON representation of the updated cohort. """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key_string) + course_key = CourseKey.from_string(course_key_string) course = get_course_with_access(request.user, 'staff', course_key) if request.method == 'GET': if not cohort_id: @@ -221,7 +218,7 @@ def users_in_cohort(request, course_key_string, cohort_id): } """ # this is a string when we get it here - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key_string) + course_key = CourseKey.from_string(course_key_string) get_course_with_access(request.user, 'staff', course_key) @@ -278,7 +275,7 @@ def add_users_to_cohort(request, course_key_string, cohort_id): Raises Http404 if the cohort cannot be found for the given course. """ # this is a string when we get it here - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key_string) + course_key = CourseKey.from_string(course_key_string) get_course_with_access(request.user, 'staff', course_key) try: @@ -344,7 +341,7 @@ def remove_user_from_cohort(request, course_key_string, cohort_id): 'msg': error_msg} """ # this is a string when we get it here - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key_string) + course_key = CourseKey.from_string(course_key_string) get_course_with_access(request.user, 'staff', course_key) username = request.POST.get('username') @@ -374,7 +371,7 @@ def debug_cohort_mgmt(request, course_key_string): Debugging view for dev. """ # this is a string when we get it here - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key_string) + course_key = CourseKey.from_string(course_key_string) # add staff check to make sure it's safe if it's accidentally deployed. get_course_with_access(request.user, 'staff', course_key) diff --git a/openedx/core/djangoapps/external_auth/views.py b/openedx/core/djangoapps/external_auth/views.py index 2c982d8e07..440d893fc6 100644 --- a/openedx/core/djangoapps/external_auth/views.py +++ b/openedx/core/djangoapps/external_auth/views.py @@ -25,7 +25,7 @@ from django.utils.http import is_safe_url, urlquote from django.utils.translation import ugettext as _ from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie from django_openid_auth import auth as openid_auth -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from openid.consumer.consumer import SUCCESS from openid.extensions import ax, sreg from openid.server.server import ProtocolError, Server, UntrustedReturnURL @@ -553,7 +553,7 @@ def course_specific_login(request, course_id): Dispatcher function for selecting the specific login method required by the course """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = modulestore().get_course(course_key) if not course: # couldn't find the course, will just return vanilla signin page @@ -576,7 +576,7 @@ def course_specific_register(request, course_id): Dispatcher function for selecting the specific registration method required by the course """ - course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course_key = CourseKey.from_string(course_id) course = modulestore().get_course(course_key) if not course: diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py index cf9c85481b..ed339cd4a7 100644 --- a/openedx/core/djangoapps/user_api/views.py +++ b/openedx/core/djangoapps/user_api/views.py @@ -10,7 +10,7 @@ from django.views.decorators.debug import sensitive_post_parameters from django_filters.rest_framework import DjangoFilterBackend from opaque_keys import InvalidKeyError from opaque_keys.edx import locator -from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.keys import CourseKey from rest_framework import authentication, generics, status, viewsets from rest_framework.exceptions import ParseError from rest_framework.views import APIView @@ -216,7 +216,7 @@ class ForumRoleUsersListView(generics.ListAPIView): course_id_string = self.request.query_params.get('course_id') if not course_id_string: raise ParseError('course_id must be specified') - course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id_string) + course_id = CourseKey.from_string(course_id_string) role = Role.objects.get_or_create(course_id=course_id, name=name)[0] users = role.users.prefetch_related("preferences").select_related("profile").all() return users