Skip to content

Commit

Permalink
Showing 13 changed files with 555 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""
Serializers for v1 contentstore API.
"""
from .settings import CourseSettingsSerializer
from .home import CourseHomeSerializer
from .course_details import CourseDetailsSerializer
from .course_rerun import CourseRerunSerializer
from .proctoring import (
LimitedProctoredExamSettingsSerializer,
ProctoredExamConfigurationSerializer,
ProctoredExamSettingsSerializer,
)
from .settings import CourseSettingsSerializer
19 changes: 19 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/serializers/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Common API Serializers
"""

from rest_framework import serializers

from openedx.core.lib.api.serializers import CourseKeyField


class CourseCommonSerializer(serializers.Serializer):
"""Serializer for course renders"""
course_key = CourseKeyField()
display_name = serializers.CharField()
lms_link = serializers.CharField()
number = serializers.CharField()
org = serializers.CharField()
rerun_link = serializers.CharField()
run = serializers.CharField()
url = serializers.CharField()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
API Serializers for course rerun
"""

from rest_framework import serializers


class CourseRerunSerializer(serializers.Serializer):
""" Serializer for course rerun """
allow_unicode_course_id = serializers.BooleanField()
course_creator_status = serializers.CharField()
display_name = serializers.CharField()
number = serializers.CharField()
org = serializers.CharField()
run = serializers.CharField()
62 changes: 62 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/serializers/home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
API Serializers for course home
"""

from rest_framework import serializers

from openedx.core.lib.api.serializers import CourseKeyField

from .common import CourseCommonSerializer


class UnsucceededCourseSerializer(serializers.Serializer):
"""Serializer for unsucceeded course"""
display_name = serializers.CharField()
course_key = CourseKeyField()
org = serializers.CharField()
number = serializers.CharField()
run = serializers.CharField()
is_failed = serializers.BooleanField()
is_in_progress = serializers.BooleanField()
dismiss_link = serializers.CharField()


class LibraryViewSerializer(serializers.Serializer):
"""Serializer for library view"""
display_name = serializers.CharField()
library_key = serializers.CharField()
url = serializers.CharField()
org = serializers.CharField()
number = serializers.CharField()
can_edit = serializers.BooleanField()


class CourseHomeSerializer(serializers.Serializer):
"""Serializer for course home"""
allow_course_reruns = serializers.BooleanField()
allow_to_create_new_org = serializers.BooleanField()
allow_unicode_course_id = serializers.BooleanField()
allowed_organizations = serializers.ListSerializer(
child=serializers.CharField(),
allow_empty=True
)
archived_courses = CourseCommonSerializer(required=False, many=True)
can_create_organizations = serializers.BooleanField()
course_creator_status = serializers.CharField()
courses = CourseCommonSerializer(required=False, many=True)
in_process_course_actions = UnsucceededCourseSerializer(many=True, required=False, allow_null=True)
libraries = LibraryViewSerializer(many=True, required=False, allow_null=True)
libraries_enabled = serializers.BooleanField()
library_authoring_mfe_url = serializers.CharField()
optimization_enabled = serializers.BooleanField()
redirect_to_library_authoring_mfe = serializers.BooleanField()
request_course_creator_url = serializers.CharField()
rerun_creator_status = serializers.BooleanField()
show_new_library_button = serializers.BooleanField()
split_studio_home = serializers.BooleanField()
studio_name = serializers.CharField()
studio_short_name = serializers.CharField()
studio_request_email = serializers.CharField()
tech_support_email = serializers.CharField()
platform_name = serializers.CharField()
user_is_active = serializers.BooleanField()
18 changes: 3 additions & 15 deletions cms/djangoapps/contentstore/rest_api/v1/serializers/settings.py
Original file line number Diff line number Diff line change
@@ -4,23 +4,11 @@

from rest_framework import serializers

from openedx.core.lib.api.serializers import CourseKeyField


class PossiblePreRequisiteCourseSerializer(serializers.Serializer):
""" Serializer for possible pre requisite course """
course_key = CourseKeyField()
display_name = serializers.CharField()
lms_link = serializers.CharField()
number = serializers.CharField()
org = serializers.CharField()
rerun_link = serializers.CharField()
run = serializers.CharField()
url = serializers.CharField()
from .common import CourseCommonSerializer


class CourseSettingsSerializer(serializers.Serializer):
""" Serializer for course settings """
"""Serializer for course settings"""
about_page_editable = serializers.BooleanField()
can_show_certificate_available_date_field = serializers.BooleanField()
course_display_name = serializers.CharField()
@@ -36,7 +24,7 @@ class CourseSettingsSerializer(serializers.Serializer):
lms_link_for_about_page = serializers.URLField()
marketing_enabled = serializers.BooleanField()
mfe_proctored_exam_settings_url = serializers.CharField(required=False, allow_null=True, allow_blank=True)
possible_pre_requisite_courses = PossiblePreRequisiteCourseSerializer(required=False, many=True)
possible_pre_requisite_courses = CourseCommonSerializer(required=False, many=True)
short_description_editable = serializers.BooleanField()
show_min_grade_warning = serializers.BooleanField()
sidebar_html_enabled = serializers.BooleanField()
36 changes: 36 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/tests/test_course_rerun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
Unit tests for course rerun.
"""
from django.urls import reverse
from rest_framework import status

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.rest_api.v1.mixins import PermissionAccessMixin


class CourseRerunViewTest(CourseTestCase, PermissionAccessMixin):
"""
Tests for CourseRerunView.
"""

def setUp(self):
super().setUp()
self.url = reverse(
"cms.djangoapps.contentstore:v1:course_rerun",
kwargs={"course_id": self.course.id},
)

def test_course_rerun_response(self):
"""Check successful response content"""
response = self.client.get(self.url)
expected_response = {
"allow_unicode_course_id": False,
"course_creator_status": "granted",
"display_name": self.course.display_name,
"number": self.course.id.course,
"org": self.course.id.org,
"run": self.course.id.run,
}

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(expected_response, response.data)
92 changes: 92 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/tests/test_home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""
Unit tests for home page view.
"""
import ddt
import json
from django.conf import settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_switch
from rest_framework import status

from cms.djangoapps.contentstore.tests.utils import CourseTestCase
from cms.djangoapps.contentstore.views.course import ENABLE_GLOBAL_STAFF_OPTIMIZATION
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory


@ddt.ddt
class HomePageViewTest(CourseTestCase):
"""
Tests for HomePageView.
"""
MODULESTORE = TEST_DATA_SPLIT_MODULESTORE

def setUp(self):
super().setUp()
self.url = reverse("cms.djangoapps.contentstore:v1:home")

def test_home_page_response(self):
"""Check successful response content"""
response = self.client.get(self.url)
course_id = str(self.course.id)

expected_response = {
"allow_course_reruns": True,
"allow_to_create_new_org": False,
"allow_unicode_course_id": False,
"allowed_organizations": [],
"archived_courses": [],
"can_create_organizations": True,
"course_creator_status": "granted",
"courses": [{
"course_key": course_id,
"display_name": self.course.display_name,
"lms_link": f'//{settings.LMS_BASE}/courses/{course_id}/jump_to/{self.course.location}',
"number": self.course.number,
"org": self.course.org,
"rerun_link": f'/course_rerun/{course_id}',
"run": self.course.id.run,
"url": f'/course/{course_id}',
}],
"in_process_course_actions": [],
"libraries": [],
"libraries_enabled": True,
"library_authoring_mfe_url": settings.LIBRARY_AUTHORING_MICROFRONTEND_URL,
"optimization_enabled": False,
"redirect_to_library_authoring_mfe": False,
"request_course_creator_url": "/request_course_creator",
"rerun_creator_status": True,
"show_new_library_button": True,
"split_studio_home": False,
"studio_name": settings.STUDIO_NAME,
"studio_short_name": settings.STUDIO_SHORT_NAME,
"studio_request_email": "",
"tech_support_email": "[email protected]",
"platform_name": settings.PLATFORM_NAME,
"user_is_active": True,
}

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(expected_response, json.loads(json.dumps(response.data)))

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_passed(self):
"""Test home page when org filter passed as a query param"""
foo_course = self.store.make_course_key('foo-org', 'bar-number', 'baz-run')
test_course = CourseFactory.create(
org=foo_course.org,
number=foo_course.course,
run=foo_course.run
)
CourseOverviewFactory.create(id=test_course.id, org='foo-org')
response = self.client.get(self.url, {"org": "foo-org"})
self.assertEqual(len(response.data['courses']), 1)
self.assertEqual(response.status_code, status.HTTP_200_OK)

@override_waffle_switch(ENABLE_GLOBAL_STAFF_OPTIMIZATION, True)
def test_org_query_if_empty(self):
"""Test home page with an empty org query param"""
response = self.client.get(self.url)
self.assertEqual(len(response.data['courses']), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)
14 changes: 13 additions & 1 deletion cms/djangoapps/contentstore/rest_api/v1/urls.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
""" Contenstore API v1 URLs. """

from django.urls import re_path
from django.urls import re_path, path

from openedx.core.constants import COURSE_ID_PATTERN

from .views import (
CourseDetailsView,
CourseRerunView,
CourseSettingsView,
HomePageView,
ProctoredExamSettingsView,
)

app_name = 'v1'

urlpatterns = [
path(
'home',
HomePageView.as_view(),
name="home"
),
re_path(
fr'^proctored_exam_settings/{COURSE_ID_PATTERN}$',
ProctoredExamSettingsView.as_view(),
@@ -28,4 +35,9 @@
CourseDetailsView.as_view(),
name="course_details"
),
re_path(
fr'^course_rerun/{COURSE_ID_PATTERN}$',
CourseRerunView.as_view(),
name="course_rerun"
),
]
2 changes: 2 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/views/__init__.py
Original file line number Diff line number Diff line change
@@ -2,5 +2,7 @@
Views for v1 contentstore API.
"""
from .course_details import CourseDetailsView
from .course_rerun import CourseRerunView
from .home import HomePageView
from .settings import CourseSettingsView
from .proctoring import ProctoredExamSettingsView
76 changes: 76 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/views/course_rerun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
""" API Views for course rerun """

import edx_api_doc_tools as apidocs
from opaque_keys.edx.keys import CourseKey
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

from cms.djangoapps.contentstore.utils import get_course_rerun_context
from cms.djangoapps.contentstore.rest_api.v1.serializers import CourseRerunSerializer
from common.djangoapps.student.roles import GlobalStaff
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, verify_course_exists, view_auth_classes
from xmodule.modulestore.django import modulestore


@view_auth_classes(is_authenticated=True)
class CourseRerunView(DeveloperErrorViewMixin, APIView):
"""
View for course rerun.
"""

@apidocs.schema(
parameters=[
apidocs.string_parameter("course_id", apidocs.ParameterLocation.PATH, description="Course ID"),
],
responses={
200: CourseRerunSerializer,
401: "The requester is not authenticated.",
403: "The requester cannot access the specified course.",
404: "The requested course does not exist.",
},
)
@verify_course_exists()
def get(self, request: Request, course_id: str):
"""
Get an object containing course rerun.
**Example Request**
GET /api/contentstore/v1/course_rerun/{course_id}
**Response Values**
If the request is successful, an HTTP 200 "OK" response is returned.
The HTTP 200 response contains a single dict that contains keys that
are the course's rerun.
**Example Response**
```json
{
"allow_unicode_course_id": False,
"course_creator_status": "granted",
"number": "101",
"display_name": "new edx course",
"org": "edx",
"run": "2023",
}
```
"""

if not GlobalStaff().has_user(request.user):
self.permission_denied(request)

course_key = CourseKey.from_string(course_id)
with modulestore().bulk_operations(course_key):
course_block = modulestore().get_course(course_key)
course_rerun_context = get_course_rerun_context(course_key, course_block, request.user)
course_rerun_context.update({
'org': course_key.org,
'number': course_key.course,
'run': course_key.run,
})
serializer = CourseRerunSerializer(course_rerun_context)
return Response(serializer.data)
120 changes: 120 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v1/views/home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
""" API Views for course home """

import edx_api_doc_tools as apidocs
from django.conf import settings
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from openedx.core.lib.api.view_utils import view_auth_classes

from ....utils import get_home_context
from ..serializers import CourseHomeSerializer


@view_auth_classes(is_authenticated=True)
class HomePageView(APIView):
"""
View for getting all courses and libraries available to the logged in user.
"""
@apidocs.schema(
parameters=[
apidocs.string_parameter(
"org",
apidocs.ParameterLocation.QUERY,
description="Query param to filter by course org",
)],
responses={
200: CourseHomeSerializer,
401: "The requester is not authenticated.",
},
)
def get(self, request: Request):
"""
Get an object containing all courses and libraries on home page.
**Example Request**
GET /api/contentstore/v1/home
**Response Values**
If the request is successful, an HTTP 200 "OK" response is returned.
The HTTP 200 response contains a single dict that contains keys that
are the course's home.
**Example Response**
```json
{
"allow_course_reruns": true,
"allow_to_create_new_org": true,
"allow_unicode_course_id": false,
"allowed_organizations": [],
"archived_courses": [
{
"course_key": "course-v1:edX+P315+2T2023",
"display_name": "Quantum Entanglement",
"lms_link": "//localhost:18000/courses/course-v1:edX+P315+2T2023",
"number": "P315",
"org": "edX",
"rerun_link": "/course_rerun/course-v1:edX+P315+2T2023",
"run": "2T2023"
"url": "/course/course-v1:edX+P315+2T2023"
},
],
"can_create_organizations": true,
"course_creator_status": "granted",
"courses": [
{
"course_key": "course-v1:edX+E2E-101+course",
"display_name": "E2E Test Course",
"lms_link": "//localhost:18000/courses/course-v1:edX+E2E-101+course",
"number": "E2E-101",
"org": "edX",
"rerun_link": "/course_rerun/course-v1:edX+E2E-101+course",
"run": "course",
"url": "/course/course-v1:edX+E2E-101+course"
},
],
"in_process_course_actions": [],
"libraries": [
{
"display_name": "My First Library",
"library_key": "library-v1:new+CPSPR",
"url": "/library/library-v1:new+CPSPR",
"org": "new",
"number": "CPSPR",
"can_edit": true
}
],
"libraries_enabled": true,
"library_authoring_mfe_url": "//localhost:3001/course/course-v1:edX+P315+2T2023",
"optimization_enabled": true,
"redirect_to_library_authoring_mfe": false,
"request_course_creator_url": "/request_course_creator",
"rerun_creator_status": true,
"show_new_library_button": true,
"split_studio_home": false,
"studio_name": "Studio",
"studio_short_name": "Studio",
"studio_request_email": "",
"tech_support_email": "technical@example.com",
"platform_name": "Your Platform Name Here"
"user_is_active": true,
}
```
"""

home_context = get_home_context(request)
home_context.update({
'allow_to_create_new_org': settings.FEATURES.get('ENABLE_CREATOR_GROUP', True) and request.user.is_staff,
'studio_name': settings.STUDIO_NAME,
'studio_short_name': settings.STUDIO_SHORT_NAME,
'studio_request_email': settings.FEATURES.get('STUDIO_REQUEST_EMAIL', ''),
'tech_support_email': settings.TECH_SUPPORT_EMAIL,
'platform_name': settings.PLATFORM_NAME,
'user_is_active': request.user.is_active,
})
serializer = CourseHomeSerializer(home_context)
return Response(serializer.data)
109 changes: 107 additions & 2 deletions cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
from pytz import UTC

from cms.djangoapps.contentstore.toggles import exam_setting_view_enabled
from common.djangoapps.course_action_state.models import CourseRerunUIStateManager
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student import auth
from common.djangoapps.student.models import CourseEnrollment
@@ -48,8 +49,7 @@
from openedx.features.content_type_gating.partitions import CONTENT_TYPE_GATING_SCHEME
from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML
from cms.djangoapps.contentstore.toggles import (
use_new_text_editor,
use_new_video_editor,
split_library_view_on_dashboard,
use_new_advanced_settings_page,
use_new_course_outline_page,
use_new_export_page,
@@ -58,8 +58,10 @@
use_new_home_page,
use_new_import_page,
use_new_schedule_details_page,
use_new_text_editor,
use_new_unit_page,
use_new_updates_page,
use_new_video_editor,
use_new_video_uploads_page,
)
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
@@ -1062,3 +1064,106 @@ def get_course_settings(request, course_key, course_block):
)

return settings_context


def get_home_context(request):
"""
Utils is used to get context of course grading.
It is used for both DRF and django views.
"""

from cms.djangoapps.contentstore.views.course import (
get_allowed_organizations,
get_allowed_organizations_for_libraries,
get_courses_accessible_to_user,
user_can_create_organizations,
_accessible_libraries_iter,
_get_course_creator_status,
_format_library_for_view,
_process_courses_list,
ENABLE_GLOBAL_STAFF_OPTIMIZATION,
)
from cms.djangoapps.contentstore.views.library import (
LIBRARY_AUTHORING_MICROFRONTEND_URL,
LIBRARIES_ENABLED,
should_redirect_to_library_authoring_mfe,
user_can_create_library,
)

optimization_enabled = GlobalStaff().has_user(request.user) and ENABLE_GLOBAL_STAFF_OPTIMIZATION.is_enabled()

org = request.GET.get('org', '') if optimization_enabled else None
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request, org)
user = request.user
libraries = []
if not split_library_view_on_dashboard() and LIBRARIES_ENABLED:
libraries = _accessible_libraries_iter(request.user)

def format_in_process_course_view(uca):
"""
Return a dict of the data which the view requires for each unsucceeded course
"""
return {
'display_name': uca.display_name,
'course_key': str(uca.course_key),
'org': uca.course_key.org,
'number': uca.course_key.course,
'run': uca.course_key.run,
'is_failed': uca.state == CourseRerunUIStateManager.State.FAILED,
'is_in_progress': uca.state == CourseRerunUIStateManager.State.IN_PROGRESS,
'dismiss_link': reverse_course_url(
'course_notifications_handler',
uca.course_key,
kwargs={
'action_state_id': uca.id,
},
) if uca.state == CourseRerunUIStateManager.State.FAILED else ''
}

split_archived = settings.FEATURES.get('ENABLE_SEPARATE_ARCHIVED_COURSES', False)
active_courses, archived_courses = _process_courses_list(courses_iter, in_process_course_actions, split_archived)
in_process_course_actions = [format_in_process_course_view(uca) for uca in in_process_course_actions]

home_context = {
'courses': active_courses,
'split_studio_home': split_library_view_on_dashboard(),
'archived_courses': archived_courses,
'in_process_course_actions': in_process_course_actions,
'libraries_enabled': LIBRARIES_ENABLED,
'redirect_to_library_authoring_mfe': should_redirect_to_library_authoring_mfe(),
'library_authoring_mfe_url': LIBRARY_AUTHORING_MICROFRONTEND_URL,
'libraries': [_format_library_for_view(lib, request) for lib in libraries],
'show_new_library_button': user_can_create_library(user) and not should_redirect_to_library_authoring_mfe(),
'user': user,
'request_course_creator_url': reverse('request_course_creator'),
'course_creator_status': _get_course_creator_status(user),
'rerun_creator_status': GlobalStaff().has_user(user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False),
'allow_course_reruns': settings.FEATURES.get('ALLOW_COURSE_RERUNS', True),
'optimization_enabled': optimization_enabled,
'active_tab': 'courses',
'allowed_organizations': get_allowed_organizations(user),
'allowed_organizations_for_libraries': get_allowed_organizations_for_libraries(user),
'can_create_organizations': user_can_create_organizations(user),
}

return home_context


def get_course_rerun_context(course_key, course_block, user):
"""
Utils is used to get context of course rerun.
It is used for both DRF and django views.
"""

from cms.djangoapps.contentstore.views.course import _get_course_creator_status

course_rerun_context = {
'source_course_key': course_key,
'display_name': course_block.display_name,
'user': user,
'course_creator_status': _get_course_creator_status(user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False)
}

return course_rerun_context
76 changes: 7 additions & 69 deletions cms/djangoapps/contentstore/views/course.py
Original file line number Diff line number Diff line change
@@ -91,8 +91,10 @@
from ..utils import (
add_instructor,
get_course_settings,
get_home_context,
get_lms_link_for_item,
get_proctored_exam_settings_url,
get_course_rerun_context,
initialize_permissions,
remove_all_instructors,
reverse_course_url,
@@ -104,12 +106,7 @@
from .component import ADVANCED_COMPONENT_TYPES
from .helpers import is_content_creator
from .block import create_xblock_info
from .library import (
LIBRARIES_ENABLED,
LIBRARY_AUTHORING_MICROFRONTEND_URL,
user_can_create_library,
should_redirect_to_library_authoring_mfe
)
from .library import LIBRARIES_ENABLED

log = logging.getLogger(__name__)
User = get_user_model()
@@ -317,13 +314,8 @@ def course_rerun_handler(request, course_key_string):
with modulestore().bulk_operations(course_key):
course_block = get_course_and_check_access(course_key, request.user, depth=3)
if request.method == 'GET':
return render_to_response('course-create-rerun.html', {
'source_course_key': course_key,
'display_name': course_block.display_name,
'user': request.user,
'course_creator_status': _get_course_creator_status(request.user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False)
})
course_rerun_context = get_course_rerun_context(course_key, course_block, request.user)
return render_to_response('course-create-rerun.html', course_rerun_context)


@login_required
@@ -532,62 +524,8 @@ def course_listing(request):
List all courses and libraries available to the logged in user
"""

optimization_enabled = GlobalStaff().has_user(request.user) and ENABLE_GLOBAL_STAFF_OPTIMIZATION.is_enabled()

org = request.GET.get('org', '') if optimization_enabled else None
courses_iter, in_process_course_actions = get_courses_accessible_to_user(request, org)
user = request.user
libraries = []
if not split_library_view_on_dashboard() and LIBRARIES_ENABLED:
libraries = _accessible_libraries_iter(request.user)

def format_in_process_course_view(uca):
"""
Return a dict of the data which the view requires for each unsucceeded course
"""
return {
'display_name': uca.display_name,
'course_key': str(uca.course_key),
'org': uca.course_key.org,
'number': uca.course_key.course,
'run': uca.course_key.run,
'is_failed': uca.state == CourseRerunUIStateManager.State.FAILED,
'is_in_progress': uca.state == CourseRerunUIStateManager.State.IN_PROGRESS,
'dismiss_link': reverse_course_url(
'course_notifications_handler',
uca.course_key,
kwargs={
'action_state_id': uca.id,
},
) if uca.state == CourseRerunUIStateManager.State.FAILED else ''
}

split_archived = settings.FEATURES.get('ENABLE_SEPARATE_ARCHIVED_COURSES', False)
active_courses, archived_courses = _process_courses_list(courses_iter, in_process_course_actions, split_archived)
in_process_course_actions = [format_in_process_course_view(uca) for uca in in_process_course_actions]

return render_to_response('index.html', {
'courses': active_courses,
'split_studio_home': split_library_view_on_dashboard(),
'archived_courses': archived_courses,
'in_process_course_actions': in_process_course_actions,
'libraries_enabled': LIBRARIES_ENABLED,
'redirect_to_library_authoring_mfe': should_redirect_to_library_authoring_mfe(),
'library_authoring_mfe_url': LIBRARY_AUTHORING_MICROFRONTEND_URL,
'libraries': [_format_library_for_view(lib, request) for lib in libraries],
'show_new_library_button': user_can_create_library(user) and not should_redirect_to_library_authoring_mfe(),
'user': user,
'request_course_creator_url': reverse('request_course_creator'),
'course_creator_status': _get_course_creator_status(user),
'rerun_creator_status': GlobalStaff().has_user(user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False),
'allow_course_reruns': settings.FEATURES.get('ALLOW_COURSE_RERUNS', True),
'optimization_enabled': optimization_enabled,
'active_tab': 'courses',
'allowed_organizations': get_allowed_organizations(user),
'allowed_organizations_for_libraries': get_allowed_organizations_for_libraries(user),
'can_create_organizations': user_can_create_organizations(user),
})
home_context = get_home_context(request)
return render_to_response('index.html', home_context)


@login_required

0 comments on commit b22a2b8

Please sign in to comment.