diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 092a0be8c6..b998d7eb11 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -2,10 +2,11 @@ from collections import defaultdict from fs.errors import ResourceNotFoundError import logging import inspect +import re from path import path from django.http import Http404 - +from django.conf import settings from .module_render import get_module from xmodule.course_module import CourseDescriptor from xmodule.modulestore import Location, XML_MODULESTORE_TYPE @@ -294,3 +295,18 @@ def sort_by_announcement(courses): courses = sorted(courses, key=key) return courses + +def get_cms_course_link_by_id(course_id): + """ + Returns a proto-relative link to course_index for editing the course in cms, assuming that the course is actually + cms-backed. If course_id is improperly formatted, just return the root of the cms + """ + format_str = r'^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$' + host = "//{}/".format(settings.CMS_BASE) # protocol-relative + m = re.match(format_str, course_id) + if m: + return "{host}{org}/{course}/course/{name}".format(host=host, + org=m.group('org'), + course=m.group('course'), + name=m.group('name')) + return host diff --git a/lms/djangoapps/courseware/tests/test_courses.py b/lms/djangoapps/courseware/tests/test_courses.py index 60594602a4..6bba730100 100644 --- a/lms/djangoapps/courseware/tests/test_courses.py +++ b/lms/djangoapps/courseware/tests/test_courses.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.test import TestCase from django.http import Http404 -from courseware.courses import get_course_by_id +from courseware.courses import get_course_by_id, get_cms_course_link_by_id class CoursesTest(TestCase): def test_get_course_by_id_invalid_chars(self): @@ -14,3 +14,11 @@ class CoursesTest(TestCase): get_course_by_id('MITx/foobar/statistics=introduction') get_course_by_id('MITx/foobar/business and management') get_course_by_id('MITx/foobar/NiñøJoséMaríáßç') + + def test_get_cms_course_link_by_id(self): + """ + Tests that get_cms_course_link_by_id returns the right thing + """ + self.assertEqual("//localhost:8001/", get_cms_course_link_by_id("blah_bad_course_id")) + self.assertEqual("//localhost:8001/", get_cms_course_link_by_id("too/too/many/slashes")) + self.assertEqual("//localhost:8001/org/num/course/name", get_cms_course_link_by_id('org/num/name')) \ No newline at end of file diff --git a/lms/djangoapps/instructor/views/legacy.py b/lms/djangoapps/instructor/views/legacy.py index b9295557d7..3dfa0e85f9 100644 --- a/lms/djangoapps/instructor/views/legacy.py +++ b/lms/djangoapps/instructor/views/legacy.py @@ -33,7 +33,7 @@ from xmodule.html_module import HtmlDescriptor from courseware import grades from courseware.access import (has_access, get_access_group_name, course_beta_test_group_name) -from courseware.courses import get_course_with_access +from courseware.courses import get_course_with_access, get_cms_course_link_by_id from courseware.models import StudentModule from django_comment_common.models import (Role, FORUM_ROLE_ADMINISTRATOR, @@ -799,16 +799,23 @@ def instructor_dashboard(request, course_id): else: email_editor = None + # determine if this is a studio-backed course so we can 1) provide a link to edit this course in studio + # 2) enable course email + studio_url = None + is_studio_course = modulestore().get_modulestore_type(course_id) == MONGO_MODULESTORE_TYPE + if is_studio_course: + studio_url = get_cms_course_link_by_id(course_id) + # Flag for whether or not we display the email tab (depending upon # what backing store this course using (Mongo vs. XML)) - if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and \ - modulestore().get_modulestore_type(course_id) == MONGO_MODULESTORE_TYPE: + if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and is_studio_course: show_email_tab = True # display course stats only if there is no other table to display: course_stats = None if not datatable: course_stats = get_course_stats_table() + #---------------------------------------- # context for rendering @@ -821,6 +828,7 @@ def instructor_dashboard(request, course_id): 'course_stats': course_stats, 'msg': msg, 'modeflag': {idash_mode: 'selectedmode'}, + 'studio_url': studio_url, 'to_option': email_to_option, # email 'subject': email_subject, # email @@ -843,7 +851,6 @@ def instructor_dashboard(request, course_id): return render_to_response('courseware/instructor_dashboard.html', context) - def _do_remote_gradebook(user, course, action, args=None, files=None): ''' Perform remote gradebook action. Returns msg, datatable. diff --git a/lms/envs/aws.py b/lms/envs/aws.py index a22fbc5bb6..35275036e5 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -111,6 +111,8 @@ SITE_NAME = ENV_TOKENS['SITE_NAME'] SESSION_ENGINE = ENV_TOKENS.get('SESSION_ENGINE', SESSION_ENGINE) SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') +CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org') + # allow for environments to specify what cookie name our login subsystem should use # this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can # happen with some browsers (e.g. Firefox) diff --git a/lms/envs/common.py b/lms/envs/common.py index 9d886f8dc1..5bd9cdc5d5 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -353,6 +353,9 @@ DEBUG = False TEMPLATE_DEBUG = False USE_TZ = True +# CMS base +CMS_BASE = 'localhost:8001' + # Site info SITE_ID = 1 SITE_NAME = "edx.org" diff --git a/lms/templates/courseware/instructor_dashboard.html b/lms/templates/courseware/instructor_dashboard.html index fae76cca93..35b37dc291 100644 --- a/lms/templates/courseware/instructor_dashboard.html +++ b/lms/templates/courseware/instructor_dashboard.html @@ -109,7 +109,7 @@ function goto( mode)
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BETA_DASHBOARD'): - + %endif
@@ -125,11 +125,16 @@ function goto( mode) ${_("DataDump")} | ${_("Manage Groups")} %if show_email_tab: - | Email + | ${_("Email")} %endif %if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_ANALYTICS'): | ${_("Analytics")} %endif + %if studio_url: + ## not checking access because if user can see this, they are at least course staff (with studio edit access) + | ${_('Edit Course')} + %endif + ]