def test_enroll_date(self): """ Test that we don't show any courses that have no published enrollment date, or an enrollment date in the future """ # demo_course_1 should be found cos it has a date that is valid DemoCourse.get_and_index(self.searcher, {"enrollment_start": datetime(2014, 1, 1)}) # demo_course_2 should not be found because it has enrollment_start date set explicitly to None DemoCourse.get_and_index(self.searcher, {"enrollment_start": None}) # demo_course_3 should not be found because it has enrollment_start date in the future DemoCourse.get_and_index(self.searcher, {"enrollment_start": datetime(2114, 1, 1)}) # demo_course_4 should not be found because it has no enrollment_start specification DemoCourse.get_and_index(self.searcher, {}, ["enrollment_start"]) results = course_discovery_search() self.assertEqual(results["total"], 1) additional_course = DemoCourse.get() DemoCourse.index(self.searcher, [additional_course]) results = course_discovery_search() self.assertEqual(results["total"], 2) # Mark the course as having ended enrollment additional_course["enrollment_end"] = datetime(2015, 1, 1) DemoCourse.index(self.searcher, [additional_course]) results = course_discovery_search() self.assertEqual(results["total"], 1)
def test_course_matching(self, term, result_count): """ Make sure that matches within content can be located and processed """ DemoCourse.get_and_index(self.searcher, { "content": { "short_description": "This is a defensive move", "overview": "Defensive teams often win" } }) DemoCourse.get_and_index(self.searcher, { "content": { "short_description": "This is an offensive move", "overview": "Offensive teams often win" } }) DemoCourse.get_and_index(self.searcher, { "content": { "short_description": "This is a hyphenated move", "overview": "Highly-offensive teams often win" } }) results = course_discovery_search() self.assertEqual(results["total"], 3) results = course_discovery_search(term) self.assertEqual(results["total"], result_count)
def test_course_list(self): """ No arguments to course_discovery_search should show all available courses""" results = course_discovery_search() self.assertEqual(results["total"], 0) DemoCourse.get_and_index(self.searcher) results = course_discovery_search() self.assertEqual(results["total"], 1)
def test_course_matching(self): """ Make sure that matches within content can be located and processed """ results = course_discovery_search("defensive") self.assertEqual(results["total"], 0) DemoCourse.get_and_index(self.searcher, {"content": {"short_description": "This is a defensive move"}}) DemoCourse.get_and_index(self.searcher, {"content": {"overview": "Defensive teams often win"}}) DemoCourse.get_and_index(self.searcher) results = course_discovery_search() self.assertEqual(results["total"], 3) results = course_discovery_search("defensive") self.assertEqual(results["total"], 2)
def test_discovery_field_matching(self): """ Test that field specifications only show those results with the desired field values """ DemoCourse.get_and_index(self.searcher, {"org": "OrgA"}) DemoCourse.get_and_index(self.searcher, {"org": "OrgB"}) results = course_discovery_search() self.assertEqual(results["total"], 2) results = course_discovery_search(field_dictionary={"org": "OrgA"}) self.assertEqual(results["total"], 1) self.assertEqual(results["results"][0]["data"]["org"], "OrgA") results = course_discovery_search(field_dictionary={"org": "OrgB"}) self.assertEqual(results["total"], 1) self.assertEqual(results["results"][0]["data"]["org"], "OrgB")
def test_faceting_override(self): """ Test that facet under consideration can be specified with custom setting """ DemoCourse.get_and_index(self.searcher, {"subject": "Mathematics", "lang": ["en", "fr"]}) DemoCourse.get_and_index(self.searcher, {"subject": "Mathematics", "lang": ["en"]}) DemoCourse.get_and_index(self.searcher, {"subject": "History", "lang": ["en"]}) DemoCourse.get_and_index(self.searcher, {"subject": "History", "lang": ["fr"]}) DemoCourse.get_and_index(self.searcher, {"lang": ["de"]}) results = course_discovery_search() self.assertEqual(results["total"], 5) self.assertIn("facets", results) self.assertNotIn("org", results["facets"]) self.assertNotIn("modes", results["facets"]) self.assertIn("subject", results["facets"]) self.assertEqual(results["facets"]["subject"]["total"], 4) self.assertEqual(results["facets"]["subject"]["terms"]["Mathematics"], 2) self.assertEqual(results["facets"]["subject"]["terms"]["History"], 2) self.assertIn("lang", results["facets"]) self.assertEqual(results["facets"]["lang"]["total"], 6) self.assertEqual(results["facets"]["lang"]["terms"]["en"], 3) self.assertEqual(results["facets"]["lang"]["terms"]["fr"], 2) self.assertEqual(results["facets"]["lang"]["terms"]["de"], 1)
def test_multivalue_field_matching(self): """ Test that field specifications only show those results with the desired field values - even when there is an array of possible values """ DemoCourse.get_and_index(self.searcher, {"modes": ["honor", "verified"]}) DemoCourse.get_and_index(self.searcher, {"modes": ["honor"]}) results = course_discovery_search() self.assertEqual(results["total"], 2) results = course_discovery_search(field_dictionary={"modes": "honor"}) self.assertEqual(results["total"], 2) results = course_discovery_search(field_dictionary={"modes": "verified"}) self.assertEqual(results["total"], 1)
def post(self, request, course_id=None): status_code = 500 search_term = request.POST.get("search_string", None) try: size, from_, page = _process_pagination_values(request) field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_term, size=size, from_=from_, field_dictionary=field_dictionary, ) status_code = 200 except ValueError as invalid_err: results = {"error": unicode(invalid_err)} log.debug(unicode(invalid_err)) # Allow for broad exceptions here - this is an entry point from external reference except Exception as err: # pylint: disable=broad-except results = { "error": ('An error occurred when searching for "{search_string}"' ).format(search_string=search_term) } log.exception( 'Search view exception when searching for %s for user %s: %r', search_term, request.user.id, err) status_code = 200 return Response(status=status.HTTP_200_OK, data=results)
def test_faceting(self): """ Test that facet results are incorporated (org and modes are default facets) """ DemoCourse.get_and_index(self.searcher, { "org": "OrgA", "modes": ["honor", "verified"] }) DemoCourse.get_and_index(self.searcher, { "org": "OrgA", "modes": ["honor"] }) DemoCourse.get_and_index(self.searcher, { "org": "OrgB", "modes": ["honor"] }) DemoCourse.get_and_index(self.searcher, { "org": "OrgB", "modes": ["verified"] }) DemoCourse.get_and_index(self.searcher, {"modes": ["other"]}) results = course_discovery_search() self.assertEqual(results["total"], 5) self.assertIn("facets", results) self.assertIn("org", results["facets"]) self.assertEqual(results["facets"]["org"]["total"], 4) self.assertEqual(results["facets"]["org"]["terms"]["OrgA"], 2) self.assertEqual(results["facets"]["org"]["terms"]["OrgB"], 2) self.assertIn("modes", results["facets"]) self.assertEqual(results["facets"]["modes"]["total"], 6) self.assertEqual(results["facets"]["modes"]["terms"]["honor"], 3) self.assertEqual(results["facets"]["modes"]["terms"]["verified"], 2) self.assertEqual(results["facets"]["modes"]["terms"]["other"], 1)
def test_enroll_date_skipped(self): """ Test feature flag to skip enrollment start date filtering for course search """ DemoCourse.get_and_index(self.searcher, {"enrollment_start": datetime(2014, 1, 1)}) DemoCourse.get_and_index(self.searcher, {"enrollment_start": None}) DemoCourse.get_and_index(self.searcher, {"enrollment_start": datetime(2114, 1, 1)}) DemoCourse.get_and_index(self.searcher, {}, ["enrollment_start"]) results = course_discovery_search() self.assertEqual(results["total"], 4)
def get(self, request, **kwargs): category_list = [] category_dict = {} search_key = request.GET.get('search_key') user_id = request.GET.get('user_id') size = 200 search_url = request.build_absolute_uri(reverse('subjects')) def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=200, from_=0, field_dictionary=field_dictionary, ) associations_list = results['facets']['org']['terms'] topics_list = results['facets']['subjects']['terms'] association_list = [] if associations_list: for name, count in associations_list.items(): association_dict = {} association_dict['name'] = name association_dict['count'] = count association_list.append(association_dict) else: association_list = [] topic_list = [] if topics_list: for name, count in topics_list.items(): topic_dict = {} topic_dict['name'] = name topic_dict['count'] = count topic_list.append(topic_dict) else: topic_list = [] association_topic_list = [] association_topic_dict = {} association_topic_dict['name'] = "Association" association_topic_dict['value'] = association_list association_topic_list.append(association_topic_dict) association_topic_dict = {} association_topic_dict['name'] = "Topics" association_topic_dict['value'] = topic_list association_topic_list.append(association_topic_dict) return JsonResponse(association_topic_list, status=200, safe=False)
def test_aggregating_filters(self): """ Test that aggregation under consideration can be specified by virtue of filters being overriden """ DemoCourse.get_and_index(self.searcher, { "test_name": "Test Name 1", "modes": ["honor", "verified"] }) DemoCourse.get_and_index(self.searcher, { "test_name": "Test Name 1", "modes": ["honor"] }) DemoCourse.get_and_index(self.searcher, { "test_name": "Test Name 2", "modes": ["honor"] }) DemoCourse.get_and_index(self.searcher, { "test_name": "Test Name 2", "modes": ["verified"] }) DemoCourse.get_and_index(self.searcher, {"modes": ["other"]}) results = course_discovery_search() self.assertEqual(results["total"], 5) self.assertIn("aggs", results) self.assertNotIn("org", results["aggs"]) self.assertIn("modes", results["aggs"]) self.assertEqual(results["aggs"]["modes"]["total"], 6) self.assertEqual(results["aggs"]["modes"]["terms"]["honor"], 3) self.assertEqual(results["aggs"]["modes"]["terms"]["verified"], 2) self.assertEqual(results["aggs"]["modes"]["terms"]["other"], 1) self.assertIn("test_name", results["aggs"]) self.assertEqual(results["aggs"]["test_name"]["total"], 4) self.assertEqual(results["aggs"]["test_name"]["terms"]["Test Name 1"], 2) self.assertEqual(results["aggs"]["test_name"]["terms"]["Test Name 2"], 2)
def test_faceting(self): """ Test that facet results are incorporated (org and modes are default facets) """ DemoCourse.get_and_index(self.searcher, {"org": "OrgA", "modes": ["honor", "verified"]}) DemoCourse.get_and_index(self.searcher, {"org": "OrgA", "modes": ["honor"]}) DemoCourse.get_and_index(self.searcher, {"org": "OrgB", "modes": ["honor"]}) DemoCourse.get_and_index(self.searcher, {"org": "OrgB", "modes": ["verified"]}) DemoCourse.get_and_index(self.searcher, {"modes": ["other"]}) results = course_discovery_search() self.assertEqual(results["total"], 5) self.assertIn("facets", results) self.assertIn("org", results["facets"]) self.assertEqual(results["facets"]["org"]["total"], 4) self.assertEqual(results["facets"]["org"]["terms"]["OrgA"], 2) self.assertEqual(results["facets"]["org"]["terms"]["OrgB"], 2) self.assertIn("modes", results["facets"]) self.assertEqual(results["facets"]["modes"]["total"], 6) self.assertEqual(results["facets"]["modes"]["terms"]["honor"], 3) self.assertEqual(results["facets"]["modes"]["terms"]["verified"], 2) self.assertEqual(results["facets"]["modes"]["terms"]["other"], 1)
def test_faceting_filters(self): """ Test that facet under consideration can be specified by virtue of filters being overriden """ DemoCourse.get_and_index(self.searcher, {"test_name": "Test Name 1", "modes": ["honor", "verified"]}) DemoCourse.get_and_index(self.searcher, {"test_name": "Test Name 1", "modes": ["honor"]}) DemoCourse.get_and_index(self.searcher, {"test_name": "Test Name 2", "modes": ["honor"]}) DemoCourse.get_and_index(self.searcher, {"test_name": "Test Name 2", "modes": ["verified"]}) DemoCourse.get_and_index(self.searcher, {"modes": ["other"]}) results = course_discovery_search() self.assertEqual(results["total"], 5) self.assertIn("facets", results) self.assertNotIn("org", results["facets"]) self.assertIn("modes", results["facets"]) self.assertEqual(results["facets"]["modes"]["total"], 6) self.assertEqual(results["facets"]["modes"]["terms"]["honor"], 3) self.assertEqual(results["facets"]["modes"]["terms"]["verified"], 2) self.assertEqual(results["facets"]["modes"]["terms"]["other"], 1) self.assertIn("test_name", results["facets"]) self.assertEqual(results["facets"]["test_name"]["total"], 4) self.assertEqual(results["facets"]["test_name"]["terms"]["Test Name 1"], 2) self.assertEqual(results["facets"]["test_name"]["terms"]["Test Name 2"], 2)
def get(self, request, **kwargs): category_list = [] category_dict = {} search_key = request.GET.get("search_key") user_id = request.GET.get("user_id") size = 200 search_url = request.build_absolute_uri(reverse("course_discovery")) if "org" in request.GET: if not request.GET.get("org"): request.GET = request.GET.copy() request.GET.pop("org") if "subjects" in request.GET: if not request.GET.get("subjects"): request.GET = request.GET.copy() request.GET.pop("subjects") if "coursetype" in request.GET: if not request.GET.get("coursetype"): request.GET = request.GET.copy() request.GET.pop("coursetype") def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) # logging.info(field_dictionary) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) # logging.info(results) associations_list = results["facets"]["org"]["terms"] topics_list = results["facets"]["subjects"]["terms"] association_list = [] if associations_list: for name, count in associations_list.items(): association_dict = {} association_dict["name"] = name association_dict["count"] = count association_list.append(association_dict) else: association_list = [] topic_list = [] if topics_list: for name, count in topics_list.items(): topic_dict = {} topic_dict["name"] = name topic_dict["count"] = count topic_list.append(topic_dict) else: topic_list = [] association_topic_list = [] association_topic_dict = {} association_topic_dict["name"] = "Association" association_topic_dict["value"] = association_list association_topic_list.append(association_topic_dict) association_topic_dict = {} association_topic_dict["name"] = "Topics" association_topic_dict["value"] = topic_list association_topic_list.append(association_topic_dict) return JsonResponse(association_topic_list, status=200, safe=False)
def test_course_matching_empty_index(self): """ Check for empty result count before indexing """ results = course_discovery_search("defensive") self.assertEqual(results["total"], 0)
def test_perform_search(self): """ search opertaion should yeild an exception with no search engine """ with self.assertRaises(NoSearchEngineError): course_discovery_search("abc test")
def get(self, request, **kwargs): """ Implements the GET method as described in the class docstring. """ # logging.info(request.GET) search_key = request.GET.get("search_key") user_id = request.GET.get("user_id") # logging.info(user_id) size = 20000 search_url = request.build_absolute_uri(reverse("course_discovery")) if "page" in request.GET: page = int(request.GET.get("page")) - 1 else: page = 0 if "org" in request.GET: if not request.GET.get("org"): request.GET = request.GET.copy() request.GET.pop("org") if "subjects" in request.GET: if not request.GET.get("subjects"): request.GET = request.GET.copy() request.GET.pop("subjects") if "coursetype" in request.GET: if not request.GET.get("coursetype"): request.GET = request.GET.copy() request.GET.pop("coursetype") def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) if results.get("total"): # logging.info("for search api have results") result = [] course_ids = [] for course in results.get("results"): course_id = course.get("_id") course_key = CourseKey.from_string(course_id) course_ids.append(course_key) course_overviews = CourseOverview.objects.filter( id__in=course_ids ).order_by("-start") starting = (page) * 20 ending = (page + 1) * (20) # logging.info("course start index [%s]", course_ids) course_overviews = course_overviews[starting:ending] # logging.info("courses list [%s]", course_overviews) for course_overview in course_overviews: search_course = {} course_id = str(course_overview.id) # logging.info("finding response for [%s]", course_id) course_key = CourseKey.from_string(course_id) course_extra_info = course_extrainfo.objects.get(course_id=course_key) # logging.info("user [%s]", user_id) course_enroll = CourseEnrollment.objects.filter( course_id=course_key, user_id=user_id ) # logging.info(course_enroll) if course_enroll.exists(): # logging.info("course enrollment exist") search_course["is_enrolled"] = "true" if course_extra_info.course_type == "2": video_blocks_in_course = modulestore().get_items( course_key, qualifiers={"category": "video"} ) block_id = modulestore().get_items( course_key, qualifiers={"category": "video"} ) if block_id: data = block_id[0].__dict__ if "scope_ids" in data: search_course["seq_block_id"] = data.get( "scope_ids" ).def_id.to_deprecated_string() else: search_course["seq_block_id"] = "" else: search_course["seq_block_id"] = "" if video_blocks_in_course: # logging.info(video_blocks_in_course) # logging.info("video_block_in_course successfully printes") # logging.info(video_blocks_in_course[0]) # logging.info("video_block_in_course[0] successfully printes") if video_blocks_in_course[0].html5_sources: search_course["video_url"] = ( video_blocks_in_course[0].html5_sources[0] if video_blocks_in_course[0].html5_sources else video_blocks_in_course[0].html5_sources ) else: video_id = ( video_blocks_in_course[0].youtube_id_1_25 or video_blocks_in_course[0].youtube_id_0_75 or video_blocks_in_course[0].youtube_id_1_0 or video_blocks_in_course[0].youtube_id_1_25 or video_blocks_in_course[0].youtube_id_1_5 ) if video_id: search_course["video_url"] = ( "https://www.youtube.com/watch?v=" + video_id ) else: search_course["video_url"] = "" else: search_course["video_url"] = "" else: search_course["video_url"] = "" else: search_course["video_url"] = "" search_course["seq_block_id"] = "" search_course["is_enrolled"] = "false" if course_extra_info.course_type == "2": search_course["is_lecture"] = "true" else: search_course["is_lecture"] = "false" search_course["id"] = course_id search_course["media"] = { "course_image": {"uri": course_overview.course_image_url}, "course_video": {"uri": course_overview.course_video_url}, } search_course["name"] = course_overview.display_name search_course["number"] = course_overview.number search_course["org"] = course_overview.org search_course["start_display"] = course_overview.start_display search_course["start_type"] = course_overview.start_type search_course["short_description"] = course_overview.short_description search_course["pacing"] = course_overview.pacing search_course["mobile_available"] = course_overview.mobile_available search_course["invitation_only"] = course_overview.invitation_only search_course["start"] = ( course_overview.start.strftime("%Y-%m-%dT%H:%M:%S.%fZ") if course_overview.start else course_overview.start ) search_course["end"] = ( course_overview.end.strftime("%Y-%m-%dT%H:%M:%S.%fZ") if course_overview.end else course_overview.end ) catalog_visibility = course_overview.catalog_visibility if catalog_visibility in ["about", "none"]: hidden = True else: hidden = False search_course["hidden"] = hidden base_url = "?".join( [ reverse("blocks_in_course"), urllib.urlencode({"course_id": course_id}), ] ) block_url = self.request.build_absolute_uri(base_url) search_course["blocks_url"] = block_url search_course["course_id"] = course_id # logging.info("succesfully find response for [%s]", course_id) result.append(search_course) results["results"] = result page = page + 1 if page > 1: pages = page - 1 previous = ( settings.LMS_ROOT_URL + "/api/v1/course/search/discovery/?search_key={search_key}&user_id={user_id}&page={page}".format( search_key=search_key, user_id=user_id, page=pages ) ) else: previous = "" if results.get("total") > page * 20: results["pagination"] = { "count": results.get("total"), "previous": previous, "num_pages": math.ceil(results.get("total") / float(size)), "next": settings.LMS_ROOT_URL + "/api/v1/course/search/discovery/?search_key={search_key}&user_id={user_id}&page={page}".format( search_key=search_key, user_id=user_id, page=page ), } else: results["pagination"] = { "count": results.get("total"), "previous": previous, "num_pages": math.ceil(results.get("total") / float(size)), "next": "", } response = JsonResponse(results, status=200) return response else: res = {} res["pagination"] = {"count": 0, "previous": "", "num_pages": 0, "next": ""} res["facets"] = {} res["results"] = [] res["total"] = 0 res["max_score"] = 0 response = JsonResponse(res, status=200) return response
def test_malformed_query_handling(self): """Make sure that mismatched quotes produce a specific exception. """ with self.assertRaises(QueryParseError): course_discovery_search('"missing quote')
def get(self, request, **kwargs): """ Implements the GET method as described in the class docstring. """ search_key = request.GET.get('search_key') user_id = request.GET.get('user_id') size = 20 search_url = request.build_absolute_uri(reverse('course_discovery')) if 'page' in request.GET: page = int(request.GET.get('page')) else: page = 0 course_category = request.GET.get('subjects') org = request.GET.get('org') if course_category or org: logging.info("Discovery category search request") def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) else: logging.info("Discovery course search request") def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.POST[field_key] for field_key in request.POST if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) if results.get('total'): logging.info("for search api have results") result = [] for course in results.get('results'): search_course = {} course_id = course.get('_id') logging.info("finding response for [%s]", course_id) course_key = CourseKey.from_string(course_id) course_overview = CourseOverview.objects.get(id=course_key) search_course['id'] = course_id search_course["media"] = { "course_image": { "uri": course_overview.course_image_url }, "course_video": { "uri": course_overview.course_video_url } } search_course['name'] = course_overview.display_name search_course['number'] = course_overview.number search_course['org'] = course_overview.org search_course['start_display'] = course_overview.start_display search_course['start_type'] = course_overview.start_type search_course[ 'short_description'] = course_overview.short_description search_course['pacing'] = course_overview.pacing search_course[ 'mobile_available'] = course_overview.mobile_available search_course[ 'invitation_only'] = course_overview.invitation_only search_course['start'] = course_overview.start.strftime( "%Y-%m-%dT%H:%M:%S.%fZ" ) if course_overview.start else course_overview.start search_course['end'] = course_overview.end.strftime( "%Y-%m-%dT%H:%M:%S.%fZ" ) if course_overview.end else course_overview.end catalog_visibility = course_overview.catalog_visibility if catalog_visibility in ['about', 'none']: hidden = True else: hidden = False search_course['hidden'] = hidden base_url = '?'.join([ reverse('blocks_in_course'), urllib.urlencode({'course_id': course_id}), ]) block_url = self.request.build_absolute_uri(base_url) search_course['blocks_url'] = block_url search_course['course_id'] = course_id del course['data'] logging.info("succesfully find response for [%s]", course_id) result.append(search_course) results['results'] = result page = page + 1 if page > 1: pages = page - 2 previous = settings.LMS_ROOT_URL + "/api/v1/course/search/discovery/?search_key={search_key}&user_id={user_id}&page={page}".format( search_key=search_key, user_id=user_id, page=pages) else: previous = "" if results.get('total') > page * size: results['pagination'] = { "count": results.get('total'), "previous": previous, "num_pages": math.ceil(results.get('total') / float(size)), "next": settings.LMS_ROOT_URL + "/api/v1/course/search/discovery/?search_key={search_key}&user_id={user_id}&page={page}" .format(search_key=search_key, user_id=user_id, page=page) } else: results['pagination'] = { "count": results.get('total'), "previous": previous, "num_pages": math.ceil(results.get('total') / float(size)), "next": "" } response = JsonResponse(results, status=200) return response else: res = {} res['pagination'] = { "count": 0, "previous": "", "num_pages": 0, "next": "" } res['facets'] = {} res['results'] = [] res['total'] = 0 res['max_score'] = 0 response = JsonResponse(res, status=200) return response
def get(self, request, **kwargs): """ Implements the GET method as described in the class docstring. """ from rest_framework.reverse import reverse params = request.GET search_key = request.GET.get('search_key') course_category = request.GET.get('subjects') org = request.GET.get('org') user_id = request.GET.get('user_id') size = 2000 search_url = request.build_absolute_uri(reverse('course_discovery')) if course_category or org: def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) else: def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.POST[field_key] for field_key in request.POST if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) if results.get('total'): result = [] course_search_enroll = [] for course in results.get('results'): search_course = {} course_id = course.get('_id') course_key = CourseKey.from_string(course_id) course_enroll = CourseEnrollment.objects.filter( course_id=course_key, user_id=user_id, is_active=True) course_overview = CourseOverview.objects.get(id=course_key) if course_enroll.exists(): course_enroll = course_enroll[0] try: user = User.objects.get(id=user_id) except: message = { "error": _('Does not match user for "{user_id}"').format( user_id=user_id) } response = JsonResponse( { 'status': 'false', 'message': message }, status=400) return response search_course['mode'] = course_enroll.mode search_course['is_active'] = course_enroll.is_active created = course_enroll.created created = created.strftime("%Y-%m-%dT%H:%M:%S.%fZ") search_course['created'] = created certificate_info = certificate_downloadable_status( user, course_key) if certificate_info['is_downloadable']: certificates = { 'url': request.build_absolute_uri( certificate_info['download_url']), } else: certificates = {} search_course['certificate'] = certificates start_date = course_overview.start start = start_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ") end_date = course_overview.end if end_date: end_date = end_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ") search_course['course'] = { 'id': course_id, 'number': course_overview.display_number_with_default, 'name': course_overview.display_name, 'org': course_overview.display_org_with_default, # dates 'start': start, 'start_display': course_overview.start_display, 'start_type': course_overview.start_type, 'end': end_date, # notification info 'subscription_id': course_overview.clean_id(padding_char='_'), # access info 'courseware_access': has_access(user, 'load_mobile', course_overview).to_json(), # various URLs # course_image is sent in both new and old formats # (within media to be compatible with the new Course API) 'media': { 'course_image': { 'uri': course_overview.course_image_url, 'name': 'Course Image', } }, 'course_image': course_overview.course_image_url, 'course_about': get_link_for_about_page(course_overview), 'course_sharing_utm_parameters': get_encoded_course_sharing_utm_params(), 'course_updates': reverse( 'course-updates-list', kwargs={'course_id': course_id}, request=request, ), 'course_handouts': reverse( 'course-handouts-list', kwargs={'course_id': course_id}, request=request, ), 'discussion_url': reverse( 'discussion_course', kwargs={'course_id': course_id}, request=request, ) if course_overview.is_discussion_tab_enabled() else None, 'video_outline': reverse( 'video-summary-list', kwargs={'course_id': course_id}, request=request, ) } course_search_enroll.append(search_course) if not course_search_enroll: course_search_enroll = [] return JsonResponse(course_search_enroll, status=200, safe=False) return JsonResponse(course_search_enroll, status=200, safe=False) else: course_search_enroll = [] return JsonResponse(course_search_enroll, status=200, safe=False)
def get(self, request, **kwargs): """ Implements the GET method as described in the class docstring. """ from rest_framework.reverse import reverse params = request.GET search_key = request.GET.get("search_key") course_category = request.GET.get("subjects") org = request.GET.get("org") user_id = request.GET.get("user_id") size = 2000 if "org" in request.GET: if not request.GET.get("org"): request.GET = request.GET.copy() request.GET.pop("org") if "subjects" in request.GET: if not request.GET.get("subjects"): request.GET = request.GET.copy() request.GET.pop("subjects") search_url = request.build_absolute_uri(reverse("course_discovery")) if course_category or org: def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.GET[field_key] for field_key in request.GET if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) else: def _process_field_values(request): """ Create separate dictionary of supported filter values provided """ return { field_key: request.POST[field_key] for field_key in request.POST if field_key in course_discovery_filter_fields() } field_dictionary = _process_field_values(request) if search_key: results = course_discovery_search( search_term=search_key, size=size, from_=0, field_dictionary=field_dictionary, ) else: results = course_discovery_search( size=size, from_=0, field_dictionary=field_dictionary, ) if results.get("total"): # logging.info("for search api have results") result = [] course_ids = [] for course in results.get("results"): course_id = course.get("_id") course_key = CourseKey.from_string(course_id) course_ids.append(course_key) course_overviews = CourseOverview.objects.filter( id__in=course_ids ).order_by("-start") # logging.info("courses list [%s]", course_overviews) course_search_enroll = [] for course_overview in course_overviews: search_course = {} course_id = str(course_overview.id) course_key = CourseKey.from_string(course_id) course_enroll = CourseEnrollment.objects.filter( course_id=course_key, user_id=user_id, is_active=True ) if course_enroll.exists(): course_enroll = course_enroll[0] try: user = User.objects.get(id=user_id) except: message = { "error": _('Does not match user for "{user_id}"').format( user_id=user_id ) } response = JsonResponse( {"status": "false", "message": message}, status=400 ) return response search_course["mode"] = course_enroll.mode search_course["is_active"] = course_enroll.is_active created = course_enroll.created created = created.strftime("%Y-%m-%dT%H:%M:%S.%fZ") search_course["created"] = created certificate_info = certificate_downloadable_status(user, course_key) if certificate_info["is_downloadable"]: certificates = { "url": request.build_absolute_uri( certificate_info["download_url"] ), } else: certificates = {} search_course["certificate"] = certificates block_id = modulestore().get_items( course_key, qualifiers={"category": "video"} ) if block_id: data = block_id[0].__dict__ if "scope_ids" in data: seq_block_id = data.get( "scope_ids" ).def_id.to_deprecated_string() else: seq_block_id = "" else: seq_block_id = "" course_extra_info = course_extrainfo.objects.get( course_id=course_key ) if course_extra_info.course_type == "2": video_blocks_in_course = modulestore().get_items( course_key, qualifiers={"category": "video"} ) if video_blocks_in_course: if video_blocks_in_course[0].html5_sources: video_url = ( video_blocks_in_course[0].html5_sources[0] if video_blocks_in_course[0].html5_sources else video_blocks_in_course[0].html5_sources ) else: video_id = ( video_blocks_in_course[0].youtube_id_1_25 or video_blocks_in_course[0].youtube_id_0_75 or video_blocks_in_course[0].youtube_id_1_0 ) if video_id: video_url = ( "https://www.youtube.com/watch?v=" + video_id ) else: video_url = "" else: video_url = "" is_lecture = "true" else: video_url = "" is_lecture = "false" start_date = course_overview.start start = start_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ") end_date = course_overview.end if end_date: end_date = end_date.strftime("%Y-%m-%dT%H:%M:%S.%fZ") search_course["course"] = { "id": course_id, "is_lecture": is_lecture, "video_url": video_url, "seq_block_id": seq_block_id, "number": course_overview.display_number_with_default, "name": course_overview.display_name, "org": course_overview.display_org_with_default, # dates "start": start, "start_display": course_overview.start_display, "start_type": course_overview.start_type, "end": end_date, # notification info "subscription_id": course_overview.clean_id(padding_char="_"), # access info "courseware_access": has_access( user, "load_mobile", course_overview ).to_json(), # various URLs # course_image is sent in both new and old formats # (within media to be compatible with the new Course API) "media": { "course_image": { "uri": course_overview.course_image_url, "name": "Course Image", } }, "course_image": course_overview.course_image_url, "course_about": get_link_for_about_page(course_overview), "course_sharing_utm_parameters": get_encoded_course_sharing_utm_params(), "course_updates": reverse( "course-updates-list", kwargs={"course_id": course_id}, request=request, ), "course_handouts": reverse( "course-handouts-list", kwargs={"course_id": course_id}, request=request, ), "discussion_url": reverse( "discussion_course", kwargs={"course_id": course_id}, request=request, ) if course_overview.is_discussion_tab_enabled() else None, "video_outline": reverse( "video-summary-list", kwargs={"course_id": course_id}, request=request, ), } course_search_enroll.append(search_course) if not course_search_enroll: course_search_enroll = [] return JsonResponse(course_search_enroll, status=200, safe=False) return JsonResponse(course_search_enroll, status=200, safe=False) else: course_search_enroll = [] return JsonResponse(course_search_enroll, status=200, safe=False)