Skip to content

Commit abcb87e

Browse files
ChrisChVanfbermudezme
authored andcommitted
feat: get migrations info REST-API added [FC-0112] (openedx#37558)
- Adds the get migrations info REST-API. - Add missing title to CourseDetails population.
1 parent fea8b42 commit abcb87e

3 files changed

Lines changed: 104 additions & 2 deletions

File tree

cms/djangoapps/modulestore_migrator/rest_api/v1/urls.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@
1717
basename='library-migrations',
1818
)
1919

20-
21-
urlpatterns = ROUTER.urls
20+
urlpatterns = [
21+
path('', include(ROUTER.urls)),
22+
path('migration_info/', MigrationInfoViewSet.as_view(), name='migration-info'),
23+
]

cms/djangoapps/modulestore_migrator/rest_api/v1/views.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
from rest_framework.response import Response
1313
from user_tasks.models import UserTaskStatus
1414
from user_tasks.views import StatusViewSet
15+
from opaque_keys.edx.keys import CourseKey
1516

1617
from cms.djangoapps.modulestore_migrator import api as migrator_api
1718
from common.djangoapps.student import auth
1819
from openedx.core.djangoapps.content_libraries import api as lib_api
1920
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
21+
from common.djangoapps.student.auth import has_studio_write_access
2022

2123
from ...data import (
2224
CompositionLevel, RepeatHandlingStrategy,
@@ -373,6 +375,103 @@ def cancel(self, request, *args, **kwargs):
373375
raise NotImplementedError
374376

375377

378+
class MigrationInfoViewSet(APIView):
379+
"""
380+
Retrieve migration information for a list of source courses or libraries.
381+
382+
It returns the target library information associated with each successfully migrated source.
383+
384+
API Endpoints
385+
-------------
386+
GET /api/modulestore_migrator/v1/migration-info/
387+
Retrieve migration details for one or more sources.
388+
389+
Query parameters:
390+
source_keys (list[str]): List of course or library keys to check.
391+
Example: ?source_keys=course-v1:edX+DemoX+2024_T1&source_keys=library-v1:orgX+lib_2
392+
393+
Example request:
394+
GET /api/modulestore_migrator/v1/migration-info/?source_keys=course-v1:edX+DemoX+2024_T1
395+
396+
Example response:
397+
{
398+
"course-v1:edX+DemoX+2024_T1": [
399+
{
400+
"target_key": "library-v1:orgX+lib_2",
401+
"target_title": "Demo Library",
402+
"target_collection_key": "col-v2:1234abcd",
403+
"target_collection_title": "Default Collection",
404+
"source_key": "course-v1:edX+DemoX+2024_T1"
405+
}
406+
],
407+
"library-v1:orgX+lib_2": [
408+
{
409+
"target_key": "library-v1:orgX+lib_2",
410+
"target_title": "Demo Library",
411+
"target_collection_key": "col-v2:1234abcd",
412+
"target_collection_title": "Default Collection",
413+
"source_key": "course-v1:edX+DemoX+2024_T1"
414+
},
415+
{
416+
"target_key": "library-v1:orgX+lib_2",
417+
"target_title": "Demo Library",
418+
"target_collection_key": "col-v2:1234abcd",
419+
"target_collection_title": "Default Collection",
420+
"source_key": "course-v1:edX+DemoX+2024_T1"
421+
}
422+
]
423+
}
424+
"""
425+
426+
permission_classes = (IsAuthenticated,)
427+
authentication_classes = (
428+
BearerAuthenticationAllowInactiveUser,
429+
JwtAuthentication,
430+
SessionAuthenticationAllowInactiveUser,
431+
)
432+
433+
@apidocs.schema(
434+
parameters=[
435+
apidocs.string_parameter(
436+
"source_keys",
437+
apidocs.ParameterLocation.QUERY,
438+
description="List of source keys to consult",
439+
),
440+
],
441+
responses={
442+
200: MigrationInfoResponseSerializer,
443+
400: "Missing required parameter: source_keys",
444+
401: "The requester is not authenticated.",
445+
},
446+
)
447+
def get(self, request):
448+
"""
449+
Handle the migration info `GET` request
450+
"""
451+
source_keys = request.query_params.getlist("source_keys")
452+
453+
if not source_keys:
454+
return Response(
455+
{"detail": "Missing required parameter: source_keys"},
456+
status=status.HTTP_400_BAD_REQUEST
457+
)
458+
459+
# Check permissions for each source_key:
460+
# Skip the source if the key is invalid or if the user doesn't have permissions
461+
source_keys_validated = []
462+
for source_key in source_keys:
463+
try:
464+
key = CourseKey.from_string(source_key)
465+
if has_studio_write_access(request.user, key):
466+
source_keys_validated.append(key)
467+
except InvalidKeyError:
468+
continue
469+
470+
data = get_all_migrations_info(source_keys_validated)
471+
serializer = MigrationInfoResponseSerializer(data)
472+
return Response(serializer.data)
473+
474+
376475
@apidocs.schema_for(
377476
"list",
378477
"List all course migrations to a library.",

openedx/core/djangoapps/models/course_details.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def populate(cls, block):
129129
course_details.self_paced = block.self_paced
130130
course_details.learning_info = block.learning_info
131131
course_details.instructor_info = block.instructor_info
132+
course_details.title = block.display_name
132133

133134
# Default course license is "All Rights Reserved"
134135
course_details.license = getattr(block, "license", "all-rights-reserved")

0 commit comments

Comments
 (0)