Python opaque_keys.edx.keys.CourseKey.from_string() Examples

The following are 30 code examples of opaque_keys.edx.keys.CourseKey.from_string(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module opaque_keys.edx.keys.CourseKey , or try the search function .
Example #1
Source File: utils.py    From micromasters with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def parse_edx_key(edx_course_key):
    """
    Attempts to parse a CourseRun's edx_course_key as an edX opaque key and return the portion
    of the key that indicates the course's semester/year

    Args:
        edx_course_key (str): An edX course key (CourseRun.edx_course_key)

    Returns:
        str: The 'run' portion of a parsed CourseKey (opaque_keys.edx.keys.CourseKey#run),
        eg: '1T2016'. Return None if the parse fails.
    """
    try:
        course_key = CourseKey.from_string(edx_course_key)
    except InvalidKeyError:
        return None
    return course_key.run if course_key else None 
Example #2
Source File: filters.py    From figures with MIT License 6 votes vote down vote up
def filter_enrolled_in_course_id(self, queryset,
                                     name, value):  # pylint: disable=unused-argument
        '''

        This method converts the course id string to a CourseLocator object
        and returns the filtered queryset. This is required because
        CourseEnrollment course_id fields are of type CourseKeyField

        Query parameters with plus signs '+' in the string are automatically
        replaced with spaces, so we need to put the '+' back in for CourseKey
        to be able to create a course key object from the string
        '''
        course_key = CourseKey.from_string(value.replace(' ', '+'))
        enrollments = get_enrolled_in_exclude_admins(course_id=course_key)
        user_ids = enrollments.values_list('user__id', flat=True)
        return queryset.filter(id__in=user_ids) 
Example #3
Source File: views.py    From figures with MIT License 6 votes vote down vote up
def site_course_helper(self, pk):
        """Hep

        Improvements:
        * make this a decorator
        * Test this with both course id strings and CourseKey objects
        """
        course_id = pk.replace(' ', '+')
        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            raise NotFound()

        site = django.contrib.sites.shortcuts.get_current_site(self.request)
        if figures.helpers.is_multisite():
            if site != figures.sites.get_site_for_course(course_id):
                raise NotFound()
        else:
            get_object_or_404(CourseOverview,
                              pk=course_key)
        return site, course_id 
Example #4
Source File: views.py    From jupyter-edx-grader-xblock with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def get(self, request, course_id, unit_id, filename):
        """Serve autograded notebook as file download
        
        Denies access if instructor has not set `allow_graded_dl` to True
        """
        usage_key = UsageKey.from_string(unit_id)
        xblock = modulestore().get_item(usage_key)

        if xblock.allow_graded_dl:
            response = self.get_nb(request, FEEDBACK, course_id, unit_id, filename, 
                    ext=".html", username=request.user.username)
            response['Content-Disposition'] = 'attachment;'\
                'filename="{}_autograded.html"'.format(filename)
            return response
        else:
            msg = "Instructor has not enabled downloading of autograded notebooks"
            return HttpResponse(msg, status=403) 
Example #5
Source File: test_utils.py    From course-discovery with GNU Affero General Public License v3.0 6 votes vote down vote up
def make_studio_data(self, run, add_pacing=True, add_schedule=True, team=None):
        key = CourseKey.from_string(run.key)
        data = {
            'title': run.title,
            'org': key.org,
            'number': key.course,
            'run': key.run,
            'team': team or [],
        }
        if add_pacing:
            data['pacing_type'] = run.pacing_type
        if add_schedule:
            data['schedule'] = {
                'start': serialize_datetime(run.start),
                'end': serialize_datetime(run.end),
            }
        return data 
Example #6
Source File: views.py    From jupyter-edx-grader-xblock with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def validate_user(self, request, course_id):
        """Validate that course exists and user is enrolled in course"""
        try:
            course_key = CourseKey.from_string(course_id)
            c = CourseEnrollment.objects.get(user_id=request.user.id, course_id=course_key)
            if not c.is_active:
                msg = "Access Denied. {} is not currently enrolled in {}"\
                        .format(request.user.username, course_id)
                raise ValidationError(msg, 403)

        # Something wrong with CourseKey
        except InvalidKeyError as e:
            msg = "Course: {} not found".format(course_id)
            raise ValidationError(msg, 404)

        # Enrollment does not exist for user
        except CourseEnrollment.DoesNotExist:
            log.error("User: {} tried to access student notebook in: {}"\
                .format(request.user.username, course_id))
            msg = "Access Denied. Either course {} does not exist or user {} is not currently enrolled"\
                    .format(course_id, request.user.username)
            raise ValidationError(msg, 403) 
Example #7
Source File: helpers.py    From figures with MIT License 6 votes vote down vote up
def as_course_key(course_id):
    '''Returns course id as a CourseKey instance

    Convenience method to return the paramater unchanged if it is of type
    ``CourseKey`` or attempts to convert to ``CourseKey`` if of type str or
    unicode.

    Raises TypeError if an unsupported type is provided
    '''
    if isinstance(course_id, CourseKey):
        return course_id
    elif isinstance(course_id, basestring):  # noqa: F821
        return CourseKey.from_string(course_id)
    else:
        raise TypeError('Unable to convert course id with type "{}"'.format(
            type(course_id))) 
Example #8
Source File: test_emails.py    From course-discovery with GNU Affero General Public License v3.0 6 votes vote down vote up
def setUp(self):
        super().setUp()
        self.org = OrganizationFactory(name='MyOrg', key='myorg')
        self.course_run = CourseRunFactory(draft=True, title_override='MyCourse')
        self.course = self.course_run.course
        self.course.authoring_organizations.add(self.org)
        self.partner = self.course.partner
        self.group = GroupFactory()
        self.pc = self.make_user(email='pc@example.com')
        self.editor = self.make_user(groups=[self.group])
        self.editor2 = self.make_user(groups=[self.group])
        self.non_editor = self.make_user(groups=[self.group])
        self.legal = self.make_user(groups=[Group.objects.get(name=LEGAL_TEAM_GROUP_NAME)])

        CourseEditorFactory(user=self.editor, course=self.course)
        CourseEditorFactory(user=self.editor2, course=self.course)
        OrganizationExtensionFactory(group=self.group, organization=self.org)
        OrganizationUserRoleFactory(user=self.pc, organization=self.org, role=InternalUserRole.ProjectCoordinator)

        self.publisher_url = '{}courses/{}'.format(self.partner.publisher_url, self.course_run.course.uuid)
        self.studio_url = '{}course/{}'.format(self.partner.studio_url, self.course_run.key)
        self.admin_url = 'https://{}/admin/course_metadata/courserun/{}/change/'.format(
            self.partner.site.domain, self.course_run.id
        )
        self.run_num = CourseKey.from_string(self.course_run.key).run 
Example #9
Source File: user.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def course_team_handler(request, course_key_string=None, email=None):
    """
    The restful handler for course team users.

    GET
        html: return html page for managing course team
        json: return json representation of a particular course team member (email is required).
    POST or PUT
        json: modify the permissions for a particular course team member (email is required, as well as role in the payload).
    DELETE:
        json: remove a particular course team member from the course team (email is required).
    """
    course_key = CourseKey.from_string(course_key_string) if course_key_string else None
    if not has_course_access(request.user, course_key):
        raise PermissionDenied()

    if 'application/json' in request.META.get('HTTP_ACCEPT', 'application/json'):
        return _course_team_user(request, course_key, email)
    elif request.method == 'GET':  # assume html
        return _manage_users(request, course_key)
    else:
        return HttpResponseNotFound() 
Example #10
Source File: tabs.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def get_tab_by_locator(tab_list, usage_key_string):
    """
    Look for a tab with the specified locator.  Returns the first matching tab.
    """
    tab_location = UsageKey.from_string(usage_key_string)
    item = modulestore().get_item(tab_location)
    static_tab = StaticTab(
        name=item.display_name,
        url_slug=item.location.name,
    )
    return CourseTabList.get_tab_by_id(tab_list, static_tab.tab_id)


# "primitive" tab edit functions driven by the command line.
# These should be replaced/deleted by a more capable GUI someday.
# Note that the command line UI identifies the tabs with 1-based
# indexing, but this implementation code is standard 0-based. 
Example #11
Source File: item.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def orphan_handler(request, course_key_string):
    """
    View for handling orphan related requests. GET gets all of the current orphans.
    DELETE removes all orphans (requires is_staff access)

    An orphan is a block whose category is not in the DETACHED_CATEGORY list, is not the root, and is not reachable
    from the root via children
    """
    course_usage_key = CourseKey.from_string(course_key_string)
    if request.method == 'GET':
        if has_course_access(request.user, course_usage_key):
            return JsonResponse([unicode(item) for item in modulestore().get_orphans(course_usage_key)])
        else:
            raise PermissionDenied()
    if request.method == 'DELETE':
        if request.user.is_staff:
            store = modulestore()
            items = store.get_orphans(course_usage_key)
            for itemloc in items:
                # need to delete all versions
                store.delete_item(itemloc, request.user.id, revision=ModuleStoreEnum.RevisionOption.all)
            return JsonResponse({'deleted': [unicode(item) for item in items]})
        else:
            raise PermissionDenied() 
Example #12
Source File: course.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def course_info_handler(request, course_key_string):
    """
    GET
        html: return html for editing the course info handouts and updates.
    """
    course_key = CourseKey.from_string(course_key_string)
    with modulestore().bulk_operations(course_key):
        course_module = _get_course_module(course_key, request.user)
        if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
            return render_to_response(
                'course_info.html',
                {
                    'context_course': course_module,
                    'updates_url': reverse_course_url('course_info_update_handler', course_key),
                    'handouts_locator': course_key.make_usage_key('course_info', 'handouts'),
                    'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_module.id)
                }
            )
        else:
            return HttpResponseBadRequest("Only supports html requests")


# pylint: disable=unused-argument 
Example #13
Source File: test_course_create_rerun.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_rerun(self):
        """
        Just testing the functionality the view handler adds over the tasks tested in test_clone_course
        """
        response = self.client.ajax_post('/course/', {
            'source_course_key': unicode(self.source_course_key),
            'org': self.source_course_key.org, 'course': self.source_course_key.course, 'run': 'copy',
            'display_name': 'not the same old name',
        })
        self.assertEqual(response.status_code, 200)
        data = parse_json(response)
        dest_course_key = CourseKey.from_string(data['destination_course_key'])

        self.assertEqual(dest_course_key.run, 'copy')
        dest_course = self.store.get_course(dest_course_key)
        self.assertEqual(dest_course.start, CourseFields.start.default) 
Example #14
Source File: test_contentstore.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_capa_module(self):
        """Test that a problem treats markdown specially."""
        course = CourseFactory.create()

        problem_data = {
            'parent_locator': unicode(course.location),
            'category': 'problem'
        }

        resp = self.client.ajax_post(reverse_url('xblock_handler'), problem_data)
        self.assertEqual(resp.status_code, 200)
        payload = parse_json(resp)
        problem_loc = UsageKey.from_string(payload['locator'])
        problem = self.store.get_item(problem_loc)
        # should be a CapaDescriptor
        self.assertIsInstance(problem, CapaDescriptor, "New problem is not a CapaDescriptor")
        context = problem.get_context()
        self.assertIn('markdown', context, "markdown is missing from context")
        self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields") 
Example #15
Source File: test_contentstore.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def post_rerun_request(
            self, source_course_key, destination_course_data=None, response_code=200, expect_error=False
    ):
        """Create and send an ajax post for the rerun request"""

        # create data to post
        rerun_course_data = {'source_course_key': unicode(source_course_key)}
        if not destination_course_data:
            destination_course_data = self.destination_course_data
        rerun_course_data.update(destination_course_data)
        destination_course_key = _get_course_id(destination_course_data)

        # post the request
        course_url = get_url('course_handler', destination_course_key, 'course_key_string')
        response = self.client.ajax_post(course_url, rerun_course_data)

        # verify response
        self.assertEqual(response.status_code, response_code)
        if not expect_error:
            json_resp = parse_json(response)
            self.assertNotIn('ErrMsg', json_resp)
            destination_course_key = CourseKey.from_string(json_resp['destination_course_key'])
        return destination_course_key 
Example #16
Source File: __init__.py    From edx-analytics-dashboard with GNU Affero General Public License v3.0 6 votes vote down vote up
def get_context_data(self, **kwargs):
        context = super(CourseContextMixin, self).get_context_data(**kwargs)
        context.update(self.get_default_data())

        user = self.request.user
        context['js_data'] = context.get('js_data', {})
        context['js_data'].update({
            'course': {
                'courseId': self.course_id,
                'org': CourseKey.from_string(self.course_id).org
            },
            'user': {
                'username': user.get_username(),
                'userTrackingID': permissions.get_user_tracking_id(self.request.user),
                'name': user.get_full_name(),
                'email': user.email,
                'ignoreInReporting': self._ignore_in_reporting(user)
            },
        })

        return context 
Example #17
Source File: opaque_key_util.py    From edx-analytics-pipeline with GNU Affero General Public License v3.0 6 votes vote down vote up
def get_filename_safe_course_id(course_id, replacement_char='_'):
    """
    Create a representation of a course_id that can be used safely in a filepath.
    """
    try:
        course_key = CourseKey.from_string(course_id)
        # Ignore the namespace of the course_id altogether, for backwards compatibility.
        filename = course_key._to_string()  # pylint: disable=protected-access
    except InvalidKeyError:
        # If the course_id doesn't parse, we will still return a value here.
        filename = course_id

    # The safest characters are A-Z, a-z, 0-9, <underscore>, <period> and <hyphen>.
    # We represent the first four with \w.
    # TODO: Once we support courses with unicode characters, we will need to revisit this.
    return re.sub(r'[^\w\.\-]', unicode(replacement_char), filename) 
Example #18
Source File: export.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def handle(self, *args, **options):
        "Execute the command"
        if len(args) != 2:
            raise CommandError("export requires two arguments: <course id> <output path>")

        try:
            course_key = CourseKey.from_string(args[0])
        except InvalidKeyError:
            course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])

        output_path = args[1]

        print("Exporting course id = {0} to {1}".format(course_key, output_path))

        root_dir = os.path.dirname(output_path)
        course_dir = os.path.splitext(os.path.basename(output_path))[0]

        export_to_xml(modulestore(), contentstore(), course_key, root_dir, course_dir) 
Example #19
Source File: opaque_key_util.py    From edx-analytics-pipeline with GNU Affero General Public License v3.0 6 votes vote down vote up
def get_course_key_from_url(url):
    """
    Extracts the course from the given `url`, if possible.

    """
    url = url or ''

    match = COURSE_REGEX.match(url)
    course_key = None
    if match:
        course_id_string = match.group('course_id')
        try:
            course_key = CourseKey.from_string(course_id_string)
        except InvalidKeyError:
            pass

    return course_key 
Example #20
Source File: utils.py    From ecommerce with GNU Affero General Public License v3.0 6 votes vote down vote up
def _get_course_id_and_organization(seat_stockrecord):
    """
    Return course_id and organization of given product

    Arguments:
        seat_stockrecord: stock record from offer catalogue

    Returns
        course_id (str or None if entitlement)
        course_organization (str or None if entitlement)
    """
    if seat_stockrecord.product.is_course_entitlement_product:
        return None, None
    course_id = seat_stockrecord.product.attr.course_key
    course_organization = CourseKey.from_string(course_id).org
    return course_id, course_organization 
Example #21
Source File: empty_asset_trashcan.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def handle(self, *args, **options):
        if len(args) != 1 and len(args) != 0:
            raise CommandError("empty_asset_trashcan requires one or no arguments: |<course_id>|")

        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]
        else:
            course_ids = [course.id for course in modulestore().get_courses()]

        if query_yes_no("Emptying trashcan. Confirm?", default="no"):
            empty_asset_trashcan(course_ids) 
Example #22
Source File: views.py    From ecommerce with GNU Affero General Public License v3.0 6 votes vote down vote up
def _get_courses(self):
        course_keys = []
        course_ids = self.request.GET.getlist('course_id')
        for course_id in course_ids:
            try:
                course_run_key = CourseKey.from_string(course_id)
            except InvalidKeyError:
                # An `InvalidKeyError` is thrown because this course key not a course run key
                # We will get the title from the discovery.
                try:
                    course = get_course_detail(self.request.site, course_id)
                    course_keys.append(course.get('title'))
                except (ReqConnectionError, SlumberHttpBaseException, Timeout) as exc:
                    logger.exception(
                        '[Account activation failure] User tried to excess the course from discovery and failed.'
                        'User: %s, course: %s, Message: %s',
                        self.request.user.id,
                        course_id,
                        exc
                    )
                    raise Http404
            else:
                course_run = get_object_or_404(Course, id=course_run_key)
                course_keys.append(course_run.name)
        return course_keys 
Example #23
Source File: test_models.py    From edx-enterprise with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_audit_param_in_course_run_enrollment_url(self, config_mock):
        """
        The ``get_course_run_enrollment_url`` method returns ``audit=true`` in the query string when
        publish_audit_enrollment_urls is enabled for the EnterpriseCustomerCatalog
        """
        config_mock.get_value.return_value = 'value'
        course_run_id = 'course-v1:edX+DemoX+Demo_Course_1'
        course_run_key = CourseKey.from_string(course_run_id)

        enterprise_catalog = EnterpriseCustomerCatalog(
            uuid=self.catalog_uuid,
            enterprise_customer=factories.EnterpriseCustomerFactory(
                uuid=self.enterprise_uuid,
                name=self.enterprise_name
            ),
            publish_audit_enrollment_urls=True
        )
        enrollment_url = enterprise_catalog.get_course_run_enrollment_url(course_run_key=course_run_key)
        assert_url_contains_query_parameters(enrollment_url, {'audit': 'true'}) 
Example #24
Source File: views.py    From edx-enterprise with GNU Affero General Public License v3.0 6 votes vote down vote up
def is_course_run_id(self, course_id):
        """
        Returns True if the course_id is in the correct format of a course_run_id, false otherwise.

        Arguments:
            course_id (str): The course_key or course run id

        Returns:
            (Boolean): True or False
        """
        try:
            # Check if we have a course ID or a course run ID
            CourseKey.from_string(course_id)
        except InvalidKeyError:
            # The ID we have is for a course instead of a course run
            return False
        # If here, the course_id is a course_run_id
        return True 
Example #25
Source File: dashboard_extras.py    From edx-analytics-dashboard with GNU Affero General Public License v3.0 5 votes vote down vote up
def format_course_key(course_key, separator=u'/'):
    if isinstance(course_key, six.string_types):
        course_key = CourseKey.from_string(course_key)

    return separator.join([course_key.org, course_key.course, course_key.run]) 
Example #26
Source File: opaque_key_util.py    From edx-analytics-pipeline with GNU Affero General Public License v3.0 5 votes vote down vote up
def get_org_id_for_course(course_id):
    """
    Args:
        course_id(unicode): The identifier for the course.

    Returns:
        The org_id extracted from the course_id, or None if none is found.
    """

    try:
        course_key = CourseKey.from_string(course_id)
        return course_key.org
    except InvalidKeyError:
        return None 
Example #27
Source File: views.py    From figures with MIT License 5 votes vote down vote up
def retrieve(self, request, *args, **kwargs):
        course_id_str = kwargs.get('pk', '')
        course_key = CourseKey.from_string(course_id_str.replace(' ', '+'))
        site = django.contrib.sites.shortcuts.get_current_site(self.request)

        if figures.helpers.is_multisite():
            if site != figures.sites.get_site_for_course(course_key):
                # Raising NotFound instead of PermissionDenied
                raise NotFound()
        data = retrieve_live_course_mau_data(site, course_key)
        serializer = self.serializer_class(data)
        return Response(serializer.data) 
Example #28
Source File: utils.py    From ecommerce with GNU Affero General Public License v3.0 5 votes vote down vote up
def get_course_info_from_catalog(site, product):
    """ Get course or course_run information from Discovery Service and cache """
    if product.is_course_entitlement_product:
        response = get_course_detail(site, product.attr.UUID)
    else:
        response = get_course_run_detail(site, CourseKey.from_string(product.attr.course_key))
    return response 
Example #29
Source File: test_vouchers.py    From ecommerce with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_get_offers_for_single_course_voucher(self):
        """ Verify that the course offers data is returned for a single course voucher. """
        self.mock_access_token_response()
        course, seat = self.create_course_and_seat()
        new_range = RangeFactory(products=[seat, ])
        voucher, __ = prepare_voucher(_range=new_range, benefit_value=10)
        benefit = voucher.offers.first().benefit
        request = self.prepare_offers_listing_request(voucher.code)
        self.mock_course_run_detail_endpoint(
            course, discovery_api_url=self.site_configuration.discovery_api_url
        )
        offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
        first_offer = offers[0]

        self.assertEqual(len(offers), 1)
        self.assertDictEqual(first_offer, {
            'benefit': {
                'type': get_benefit_type(benefit),
                'value': benefit.value
            },
            'contains_verified': True,
            'course_start_date': '2013-02-05T05:00:00Z',
            'id': course.id,
            'image_url': '/path/to/image.jpg',
            'multiple_credit_providers': False,
            'organization': CourseKey.from_string(course.id).org,
            'credit_provider_price': None,
            'seat_type': seat.attr.certificate_type,
            'stockrecords': serializers.StockRecordSerializer(seat.stockrecords.first()).data,
            'title': course.name,
            'voucher_end_date': voucher.end_datetime,
        }) 
Example #30
Source File: test_utils.py    From ecommerce with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_get_course_run_info_from_catalog(self, course_run):
        """ Check to see if course info gets cached """
        self.mock_access_token_response()
        if course_run:
            resource = "course_runs"
            course = CourseFactory(partner=self.partner)
            product = course.create_or_update_seat('verified', None, 100)
            key = CourseKey.from_string(product.attr.course_key)
            self.mock_course_run_detail_endpoint(
                course, discovery_api_url=self.site_configuration.discovery_api_url
            )
        else:
            resource = "courses"
            product = create_or_update_course_entitlement(
                'verified', 100, self.partner, 'foo-bar', 'Foo Bar Entitlement')
            key = product.attr.UUID
            self.mock_course_detail_endpoint(
                discovery_api_url=self.site_configuration.discovery_api_url,
                course=product
            )

        cache_key = get_cache_key(
            site_domain=self.site.domain,
            resource="{}-{}".format(resource, key)
        )
        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertFalse(course_cached_response.is_found)

        response = get_course_info_from_catalog(self.request.site, product)

        if course_run:
            self.assertEqual(response['title'], course.name)
        else:
            self.assertEqual(response['title'], product.title)

        course_cached_response = TieredCache.get_cached_response(cache_key)
        self.assertEqual(course_cached_response.value, response)