diff --git a/course_discovery/apps/api/serializers.py b/course_discovery/apps/api/serializers.py index bbef4995c4..caeed00a81 100644 --- a/course_discovery/apps/api/serializers.py +++ b/course_discovery/apps/api/serializers.py @@ -1103,10 +1103,10 @@ class Meta(MinimalCourseRunSerializer.Meta): 'first_enrollable_paid_seat_price', 'has_ofac_restrictions', 'ofac_comment', 'enrollment_count', 'recent_enrollment_count', 'expected_program_type', 'expected_program_name', 'course_uuid', 'estimated_hours', 'content_language_search_facet_name', 'enterprise_subscription_inclusion', - 'transcript_languages_search_facet_names', 'translation_languages' + 'transcript_languages_search_facet_names', 'ai_languages' ) read_only_fields = ('enrollment_count', 'recent_enrollment_count', 'content_language_search_facet_name', - 'enterprise_subscription_inclusion', 'translation_languages') + 'enterprise_subscription_inclusion', 'ai_languages') def get_instructors(self, obj): # pylint: disable=unused-argument # This field is deprecated. Use the staff field. diff --git a/course_discovery/apps/api/tests/test_serializers.py b/course_discovery/apps/api/tests/test_serializers.py index f013b3dfa5..277eed8fb6 100644 --- a/course_discovery/apps/api/tests/test_serializers.py +++ b/course_discovery/apps/api/tests/test_serializers.py @@ -782,7 +782,7 @@ def get_expected_data(cls, course_run, request): 'transcript_languages_search_facet_names': [ lang.get_search_facet_display() for lang in course_run.transcript_languages.all() ], - 'translation_languages': course_run.translation_languages, + 'ai_languages': course_run.ai_languages, }) return expected diff --git a/course_discovery/apps/course_metadata/admin.py b/course_discovery/apps/course_metadata/admin.py index ef1827cdd7..cd3f30a0bb 100644 --- a/course_discovery/apps/course_metadata/admin.py +++ b/course_discovery/apps/course_metadata/admin.py @@ -313,7 +313,7 @@ class CourseRunAdmin(SimpleHistoryAdmin): raw_id_fields = ('course', 'draft_version',) readonly_fields = [ 'enrollment_count', 'recent_enrollment_count', 'hidden', 'key', 'enterprise_subscription_inclusion', - 'variant_id', 'fixed_price_usd', 'translation_languages' + 'variant_id', 'fixed_price_usd', 'ai_languages' ] search_fields = ('uuid', 'key', 'title_override', 'course__title', 'slug', 'external_key', 'variant_id') save_error = False diff --git a/course_discovery/apps/course_metadata/algolia_models.py b/course_discovery/apps/course_metadata/algolia_models.py index 200b7659a9..951e4183e8 100644 --- a/course_discovery/apps/course_metadata/algolia_models.py +++ b/course_discovery/apps/course_metadata/algolia_models.py @@ -83,7 +83,7 @@ def delegate_attributes(cls): 'secondary_description', 'tertiary_description'] facet_fields = ['availability_level', 'subject_names', 'levels', 'active_languages', 'staff_slugs', 'product_allowed_in', 'product_blocked_in', 'learning_type', 'learning_type_exp', - 'product_translation_languages'] + 'product_ai_languages'] ranking_fields = ['availability_rank', 'product_recent_enrollment_count', 'promoted_in_spanish_index', 'product_value_per_click_usa', 'product_value_per_click_international', 'product_value_per_lead_usa', 'product_value_per_lead_international'] @@ -355,10 +355,16 @@ def product_max_effort(self): return getattr(self.advertised_course_run, 'max_effort', None) @property - def product_translation_languages(self): - if self.advertised_course_run and self.advertised_course_run.translation_languages: - return self.advertised_course_run.translation_languages - return [] + def product_ai_languages(self): + if ai_langs:=(self.advertised_course_run and self.advertised_course_run.ai_languages): + return { + 'translation_languages': [lang['label'] for lang in ai_langs['translation_languages']], + 'transcription_languages': [lang['label'] for lang in ai_langs['transcription_languages']] + } + return { + 'translation_languages': [], + 'transcription_languages': [] + } @property def owners(self): @@ -544,8 +550,11 @@ def product_max_effort(self): return self.max_hours_effort_per_week @property - def product_translation_languages(self): - return [] + def product_ai_languages(self): + return { + 'translation_languages': [], + 'transcription_languages': [] + } @property def subject_names(self): diff --git a/course_discovery/apps/course_metadata/index.py b/course_discovery/apps/course_metadata/index.py index 7617601665..ce7dfc609c 100644 --- a/course_discovery/apps/course_metadata/index.py +++ b/course_discovery/apps/course_metadata/index.py @@ -81,7 +81,7 @@ class EnglishProductIndex(BaseProductIndex): ('staff_slugs', 'staff'), ('product_allowed_in', 'allowed_in'), ('product_blocked_in', 'blocked_in'), 'subscription_eligible', 'subscription_prices', 'learning_type', 'learning_type_exp', - ('product_translation_languages', 'translation_languages')) + ('product_ai_languages', 'ai_languages')) ranking_fields = ('availability_rank', ('product_recent_enrollment_count', 'recent_enrollment_count'), ('product_value_per_click_usa', 'value_per_click_usa'), ('product_value_per_click_international', 'value_per_click_international'), @@ -117,7 +117,7 @@ class EnglishProductIndex(BaseProductIndex): 'partner', 'availability', 'subject', 'level', 'language', 'product', 'program_type', 'filterOnly(staff)', 'filterOnly(allowed_in)', 'filterOnly(blocked_in)', 'skills.skill', 'skills.category', 'skills.subcategory', 'tags', 'subscription_eligible', 'subscription_prices', - 'learning_type', 'learning_type_exp', 'translation_languages.code', 'translation_languages.label', + 'learning_type', 'learning_type_exp', 'ai_languages.translation_languages', 'ai_languages.transcription_languages', ], 'customRanking': ['asc(availability_rank)', 'desc(recent_enrollment_count)'] } @@ -135,7 +135,7 @@ class SpanishProductIndex(BaseProductIndex): ('staff_slugs', 'staff'), ('product_allowed_in', 'allowed_in'), ('product_blocked_in', 'blocked_in'), 'subscription_eligible', 'subscription_prices', 'learning_type', 'learning_type_exp', - ('product_translation_languages', 'translation_languages')) + ('product_ai_languages', 'ai_languages')) ranking_fields = ('availability_rank', ('product_recent_enrollment_count', 'recent_enrollment_count'), ('product_value_per_click_usa', 'value_per_click_usa'), ('product_value_per_click_international', 'value_per_click_international'), @@ -173,8 +173,8 @@ class SpanishProductIndex(BaseProductIndex): 'partner', 'availability', 'subject', 'level', 'language', 'product', 'program_type', 'filterOnly(staff)', 'filterOnly(allowed_in)', 'filterOnly(blocked_in)', 'skills.skill', 'skills.category', 'skills.subcategory', 'tags', 'subscription_eligible', - 'subscription_prices', 'learning_type', 'learning_type_exp', 'translation_languages.code', - 'translation_languages.label', + 'subscription_prices', 'learning_type', 'learning_type_exp', 'ai_languages.translation_languages', + 'ai_languages.transcription_languages', ], 'customRanking': ['desc(promoted_in_spanish_index)', 'asc(availability_rank)', 'desc(recent_enrollment_count)'] } diff --git a/course_discovery/apps/course_metadata/tests/factories.py b/course_discovery/apps/course_metadata/tests/factories.py index 824e9e8928..f1c3ed02e4 100644 --- a/course_discovery/apps/course_metadata/tests/factories.py +++ b/course_discovery/apps/course_metadata/tests/factories.py @@ -482,7 +482,10 @@ class CourseRunFactory(SalesforceRecordFactory): type = factory.SubFactory(CourseRunTypeFactory) variant_id = factory.LazyFunction(uuid4) fixed_price_usd = FuzzyDecimal(0.0, 650.0) - translation_languages = [{'code': 'fr', 'label': 'French'}] + ai_languages = { + 'translation_languages': [{'code': 'fr', 'label': 'French'}], + 'transcription_languages': [{'code': 'en', 'label': 'English'}, {'code': 'bs', 'label': 'Bosnian'}] + } @factory.post_generation def staff(self, create, extracted, **kwargs): diff --git a/course_discovery/apps/course_metadata/tests/test_algolia_models.py b/course_discovery/apps/course_metadata/tests/test_algolia_models.py index 1789087ba9..c07a22d505 100644 --- a/course_discovery/apps/course_metadata/tests/test_algolia_models.py +++ b/course_discovery/apps/course_metadata/tests/test_algolia_models.py @@ -579,13 +579,19 @@ def test_learning_type_exp_non_open_course(self, course_type_slug, expected_resu course.type = CourseTypeFactory(slug=course_type_slug) assert course.learning_type_exp == [expected_result] - def test_course_translation_languages(self): + def test_course_ai_languages(self): course = self.create_current_upgradeable_course() - assert course.product_translation_languages == [{'code': 'fr', 'label': 'French'}] + assert course.product_ai_languages == { + 'translation_languages': ['French'], + 'transcription_languages': ['English', 'Bosnian'] + } - def test_course_translation_languages__no_advertised_run(self): + def test_course_ai_languages__no_advertised_run(self): course = self.create_blocked_course(status=CourseRunStatus.Unpublished) - assert course.product_translation_languages == [] + assert course.product_ai_languages == { + 'translation_languages': [], + 'transcription_languages': [] + } @ddt.ddt @@ -927,6 +933,9 @@ def test_learning_type_exp(self, program_type_slug, learning_type): program = AlgoliaProxyProgramFactory(partner=self.__class__.edxPartner, type=program_type) assert program.learning_type_exp == [learning_type] - def test_program_translation_languages(self): + def test_program_ai_languages(self): program = AlgoliaProxyProgramFactory(partner=self.__class__.edxPartner) - assert program.product_translation_languages == [] + assert program.product_ai_languages == { + 'translation_languages': [], + 'transcription_languages': [] + } diff --git a/course_discovery/apps/course_metadata/tests/test_models.py b/course_discovery/apps/course_metadata/tests/test_models.py index 53de73d2a6..73e74d8bb9 100644 --- a/course_discovery/apps/course_metadata/tests/test_models.py +++ b/course_discovery/apps/course_metadata/tests/test_models.py @@ -990,16 +990,19 @@ def test_course_run_fixed_usd_price(self): ) assert course_run.fixed_price_usd is None - def test_course_run_translation_languages(self): + def test_course_run_ai_languages(self): """ - Sanity checks for the translation_languages field + Sanity checks for the ai_languages field """ - DEFAULT_TRANSLATION_LANGUAGES = [{'code': 'fr', 'label': 'French'}] course_run = factories.CourseRunFactory() - assert course_run.translation_languages == DEFAULT_TRANSLATION_LANGUAGES - - course_run = factories.CourseRunFactory(translation_languages=None) - assert course_run.translation_languages is None + DEFAULT_AI_LANGUAGES = { + 'translation_languages': [{'code': 'fr', 'label': 'French'}], + 'transcription_languages': [{'code': 'en', 'label': 'English'}, {'code': 'bs', 'label': 'Bosnian'}] + } + assert course_run.ai_languages == DEFAULT_AI_LANGUAGES + + course_run = factories.CourseRunFactory(ai_languages=None) + assert course_run.ai_languages is None @ddt.data('full_description_override', 'outcome_override', 'short_description_override') def test_html_fields_are_validated(self, field_name):