From 6cd8981d32c8f166bb3fa28bf14a4219db1cdf61 Mon Sep 17 00:00:00 2001 From: wajeeha-khalid Date: Wed, 19 Jun 2019 23:39:19 +0500 Subject: [PATCH 1/3] Revert " [MCKIN-7759] Remove usage of CourseAggregatedMetaData since it is no longer in use. (#222)" This reverts commit 56a232dc6df8e73f4383a767ff466736e3cd9cb7. --- edx_solutions_api_integration/courses/tests.py | 8 ++++++++ edx_solutions_api_integration/courses/views.py | 8 ++++++++ edx_solutions_api_integration/test_utils.py | 9 +++++++++ edx_solutions_api_integration/urls.py | 1 - edx_solutions_api_integration/users/views.py | 4 ++++ setup.py | 2 +- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/edx_solutions_api_integration/courses/tests.py b/edx_solutions_api_integration/courses/tests.py index 5859771e..9ac5aaf3 100644 --- a/edx_solutions_api_integration/courses/tests.py +++ b/edx_solutions_api_integration/courses/tests.py @@ -53,6 +53,8 @@ ) from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory +from course_metadata.models import CourseAggregatedMetaData + from edx_solutions_api_integration.courseware_access import get_course_descriptor, get_course_key from edx_solutions_api_integration.test_utils import ( APIClientMixin, CourseGradingMixin, SignalDisconnectTestMixin, @@ -1592,6 +1594,9 @@ def test_courses_users_list_get_attributes(self, store): user_completions, course_total_assesments = 50, 100 CourseEnrollmentFactory.create(user=user, course_id=course.id) + CourseAggregatedMetaData.objects.update_or_create( + id=course.id, defaults={'total_assessments': course_total_assesments} + ) section_breakdown = [ { "category": "Homework", @@ -2433,6 +2438,9 @@ def test_courses_data_metrics(self): self.login() users_to_add, user_grade, user_completions, total_assessments = 5, 0.6, 10, 20 course = CourseFactory() + CourseAggregatedMetaData.objects.update_or_create( + id=course.id, defaults={'total_assessments': total_assessments} + ) for idx in xrange(0, users_to_add): user = UserFactory() created_user_id = user.id diff --git a/edx_solutions_api_integration/courses/views.py b/edx_solutions_api_integration/courses/views.py index 22d98e64..ff047124 100644 --- a/edx_solutions_api_integration/courses/views.py +++ b/edx_solutions_api_integration/courses/views.py @@ -25,6 +25,7 @@ from completion.models import BlockCompletion from completion_aggregator.models import Aggregator +from course_metadata.models import CourseAggregatedMetaData from courseware.courses import ( get_course_about_section, get_course_info_section, @@ -1206,6 +1207,7 @@ class CoursesUsersList(MobileListAPIView): """ serializer_class = UserSerializer course_key = None + course_meta_data = None user_organizations = [] def post(self, request, course_id): @@ -1254,6 +1256,11 @@ def get(self, request, course_id): # pylint: disable=W0221 if not course_exists(course_id): return Response({}, status=status.HTTP_404_NOT_FOUND) self.course_key = get_course_key(course_id) + try: + self.course_meta_data = CourseAggregatedMetaData.objects.get(id=self.course_key) + except CourseAggregatedMetaData.DoesNotExist: + self.course_meta_data = None + return super(CoursesUsersList, self).list(request) def get_serializer_context(self): @@ -1286,6 +1293,7 @@ def get_serializer_context(self): serializer_context.update({ 'course_id': self.course_key, 'default_fields': default_fields, + 'course_meta_data': self.course_meta_data, 'active_attributes': active_attributes, }) return serializer_context diff --git a/edx_solutions_api_integration/test_utils.py b/edx_solutions_api_integration/test_utils.py index 550f0344..655b0bd1 100644 --- a/edx_solutions_api_integration/test_utils.py +++ b/edx_solutions_api_integration/test_utils.py @@ -20,6 +20,9 @@ from xmodule.modulestore.django import SignalHandler from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory +from course_metadata.signals import ( + course_publish_handler_in_course_metadata as listener_in_course_metadata +) from gradebook.signals import on_course_grade_changed @@ -272,6 +275,9 @@ def connect_signals(): """ connects signals defined in solutions apps """ + SignalHandler.course_published.connect( + listener_in_course_metadata, dispatch_uid='course_metadata' + ) PROBLEM_WEIGHTED_SCORE_CHANGED.connect(on_course_grade_changed) @staticmethod @@ -279,6 +285,9 @@ def disconnect_signals(): """ Disconnects signals defined in solutions apps """ + SignalHandler.course_published.disconnect( + listener_in_course_metadata, dispatch_uid='course_metadata' + ) PROBLEM_WEIGHTED_SCORE_CHANGED.disconnect(on_course_grade_changed) diff --git a/edx_solutions_api_integration/urls.py b/edx_solutions_api_integration/urls.py index c0942f9d..16137ae4 100644 --- a/edx_solutions_api_integration/urls.py +++ b/edx_solutions_api_integration/urls.py @@ -31,7 +31,6 @@ url(r'^mobile/v1/', include('edx_solutions_api_integration.mobile_api.urls')), url(r'^imports/*', include('edx_solutions_api_integration.imports.urls')), url(r'^courses_metadata/', include('course_metadata.urls')), - # we have to explicitly define url for workgroup users detail view # to wrap it around non_atomic_requests decorator url( diff --git a/edx_solutions_api_integration/users/views.py b/edx_solutions_api_integration/users/views.py index 175513a9..6ef4ea36 100644 --- a/edx_solutions_api_integration/users/views.py +++ b/edx_solutions_api_integration/users/views.py @@ -45,6 +45,7 @@ from openedx.core.djangoapps.user_api.preferences.api import set_user_preference from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_names, get_profile_image_storage from edx_notifications.lib.consumer import mark_notification_read +from course_metadata.models import CourseAggregatedMetaData, CourseSetting from completion_aggregator.models import Aggregator from student.models import CourseEnrollment, CourseEnrollmentException, PasswordHistory, UserProfile, LoginFailures from student.roles import ( @@ -1783,6 +1784,8 @@ def get(self, request, *args, **kwargs): # pylint: disable=unused-argument aggregation_name='course' ).values('course_key', 'earned', 'possible', 'percent') } + course_meta_data = CourseAggregatedMetaData.objects.filter(id__in=course_keys)\ + .values('id', 'total_assessments') course_overview = CourseOverview.objects.filter(id__in=course_keys) if str2bool(mobile_only): course_overview = course_overview.filter(mobile_available=True) @@ -1801,6 +1804,7 @@ def get(self, request, *args, **kwargs): # pylint: disable=unused-argument serializer = CourseProgressSerializer(enrollments, many=True, context={ 'student_progress': student_progress, 'course_overview': course_overview, + 'course_metadata': course_meta_data, 'user_grades': user_grades, }) diff --git a/setup.py b/setup.py index f8522cd7..a25204d9 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='api-integration', - version='3.1.3', + version='3.0.0', description='RESTful api integration for edX platform', long_description=open('README.rst').read(), author='edX', From fea5dd8deee1c544de519ddafe0d77d9b7056ab3 Mon Sep 17 00:00:00 2001 From: wajeeha-khalid Date: Wed, 19 Jun 2019 23:39:58 +0500 Subject: [PATCH 2/3] update version to 3.1.4 after reverting mckin-7759 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a25204d9..e0237e9d 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='api-integration', - version='3.0.0', + version='3.1.4', description='RESTful api integration for edX platform', long_description=open('README.rst').read(), author='edX', From 92420a6f15a10b1122fd29355d1ea8387eb4810f Mon Sep 17 00:00:00 2001 From: Nasir Hussain Date: Fri, 21 Jun 2019 22:56:46 +0500 Subject: [PATCH 3/3] Revert "update courses and user courses api to return image urls (#224)" This reverts commit 86226fa640d5eaec6850f6a51fc7747e4255e09b. --- edx_solutions_api_integration/courses/tests.py | 6 ++---- edx_solutions_api_integration/courses/views.py | 7 ++++--- edx_solutions_api_integration/users/views.py | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/edx_solutions_api_integration/courses/tests.py b/edx_solutions_api_integration/courses/tests.py index 9ac5aaf3..34e8d9e4 100644 --- a/edx_solutions_api_integration/courses/tests.py +++ b/edx_solutions_api_integration/courses/tests.py @@ -37,7 +37,6 @@ from django_comment_common.models import FORUM_ROLE_MODERATOR, Role from freezegun import freeze_time from instructor.access import allow_access -from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from requests.exceptions import ConnectionError from rest_framework import status @@ -342,7 +341,6 @@ def setUpClass(cls): end=cls.course_end_date, language=cls.language, ) - cls.course_overview = CourseOverview.get_from_id(cls.course.id) cls.test_data = '{}'.format(str(uuid.uuid4())) cls.chapter = ItemFactory.create( @@ -1025,14 +1023,14 @@ def test_courses_overview_get_unparsed(self): self.assertGreater(len(response.data), 0) asset_id = self.test_course_id.split(":")[1] self.assertEqual(response.data['overview_html'], self.overview.data.format(asset_id, asset_id)[1:]) - self.assertEqual(self.course_overview.image_urls, response.data['course_image_urls']) + self.assertIn(self.course.course_image, response.data['course_image_url']) def test_courses_overview_get_parsed(self): test_uri = self.base_courses_uri + '/' + self.test_course_id + '/overview?parse=true' response = self.do_get(test_uri) self.assertEqual(response.status_code, 200) self.assertGreater(len(response.data), 0) - self.assertEqual(self.course_overview.image_urls, response.data['course_image_urls']) + self.assertIn(self.course.course_image, response.data['course_image_url']) sections = response.data['sections'] self.assertEqual(len(sections), 4) self.assertIsNotNone(self._find_item_by_class(sections, 'about')) diff --git a/edx_solutions_api_integration/courses/views.py b/edx_solutions_api_integration/courses/views.py index ff047124..579a8db4 100644 --- a/edx_solutions_api_integration/courses/views.py +++ b/edx_solutions_api_integration/courses/views.py @@ -996,9 +996,10 @@ def get(self, request, course_id): response_data['sections'] = _parse_overview_html(existing_content) else: response_data['overview_html'] = existing_content - - course_overview = CourseOverview.get_from_id(course_key) - response_data['course_image_urls'] = course_overview.image_urls + image_url = '' + if hasattr(course_descriptor, 'course_image') and course_descriptor.course_image: + image_url = course_image_url(course_descriptor) + response_data['course_image_url'] = image_url response_data['course_video'] = get_course_about_section(request, course_descriptor, 'video') return Response(response_data, status=status.HTTP_200_OK) diff --git a/edx_solutions_api_integration/users/views.py b/edx_solutions_api_integration/users/views.py index 6ef4ea36..6949684a 100644 --- a/edx_solutions_api_integration/users/views.py +++ b/edx_solutions_api_integration/users/views.py @@ -1094,7 +1094,7 @@ def get(self, request, user_id): "start": enrollment.course_overview.start, "end": enrollment.course_overview.end, "effort": enrollment.course_overview.effort, - "course_image_urls": enrollment.course_overview.image_urls, + "course_image_url": enrollment.course_overview.course_image_url, } response_data.append(course_data)