def get_thread_list(request, course_key, page, page_size, topic_id_list=None, text_search=None, following=False): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following Note that topic_id_list, text_search, and following are mutually exclusive. Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. Raises: ValueError: if more than one of the mutually exclusive parameters is provided Http404: if the requesting user does not have access to the requested course or a page beyond the last is requested """ exclusive_param_count = sum(1 for param in [topic_id_list, text_search, following] if param) if exclusive_param_count > 1: # pragma: no cover raise ValueError("More than one mutually exclusive param passed to get_thread_list") course = _get_course_or_404(course_key, request.user) context = get_context(course, request) query_params = { "group_id": (None if context["is_requester_privileged"] else get_cohort_id(request.user, course.id)), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, "text": text_search, } text_search_rewrite = None if following: threads, result_page, num_pages = context["cc_requester"].subscribed_threads(query_params) else: query_params["course_id"] = unicode(course.id) query_params["commentable_ids"] = ",".join(topic_id_list) if topic_id_list else None query_params["text"] = text_search threads, result_page, num_pages, text_search_rewrite = Thread.search(query_params) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [ThreadSerializer(thread, context=context).data for thread in threads] ret = get_paginated_data(request, results, page, num_pages) ret["text_search_rewrite"] = text_search_rewrite return ret
def get_thread_list(request, course, page, page_size): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course: The course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. """ user_is_privileged = Role.objects.filter( course_id=course.id, name__in=[FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA], users=request.user ).exists() cc_user = User.from_django_user(request.user).retrieve() threads, result_page, num_pages, _ = Thread.search({ "course_id": unicode(course.id), "group_id": None if user_is_privileged else get_cohort_id(request.user, course.id), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, }) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 # TODO: cache staff_user_ids and ta_user_ids if we need to improve perf staff_user_ids = { user.id for role in Role.objects.filter( name__in=[FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR], course_id=course.id ) for user in role.users.all() } ta_user_ids = { user.id for role in Role.objects.filter(name=FORUM_ROLE_COMMUNITY_TA, course_id=course.id) for user in role.users.all() } # For now, the only groups are cohorts group_ids_to_names = get_cohort_names(course) results = [ _cc_thread_to_api_thread(thread, cc_user, staff_user_ids, ta_user_ids, group_ids_to_names) for thread in threads ] return get_paginated_data(request, results, page, num_pages)
def get_thread_list(request, course_key, page, page_size): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. """ user_is_privileged = Role.objects.filter(course_id=course_key, name__in=[ FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA ], users=request.user).exists() threads, result_page, num_pages, _ = Thread.search({ "course_id": unicode(course_key), "group_id": None if user_is_privileged else get_cohort_id(request.user, course_key), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, }) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [_cc_thread_to_api_thread(thread) for thread in threads] return get_paginated_data(request, results, page, num_pages)
def get_thread_list(request, course_key, page, page_size): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. """ course = _get_course_or_404(course_key, request.user) context = get_context(course, request) threads, result_page, num_pages, _ = Thread.search({ "course_id": unicode(course.id), "group_id": (None if context["is_requester_privileged"] else get_cohort_id( request.user, course.id)), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, }) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [ ThreadSerializer(thread, context=context).data for thread in threads ] return get_paginated_data(request, results, page, num_pages)
def get_section_list(request,course_id,student_id): section_id_dict = {} commentable_id_list = [] try: course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) except Exception as e: return Resposne( data={ "Error": e.message }) course = get_course_by_id(course_key) with modulestore().bulk_operations(course.id): course_module = get_module_for_descriptor( request.user, request, course, None, course.id, course=course ) if course_module is None: return Response( data={ "Error":"User is not allowed to do the operation" }) student = User.objects.get(id=student_id) query_params = { "course_id":course_id, "user_id": student.id, } threads = Thread.search(query_params).collection for chapter in course_module.get_children(): for section in chapter.get_children(): for unit in section.get_children(): for vertical in unit.get_children(): if vertical.category == 'discussion': participated = False for thread in threads: if thread['commentable_id'] == vertical.discussion_id: participated = thread['username'] == student.username section_id_dict.update({chapter.url_name: participated}) return section_id_dict
def get_thread_list(request, course_key, page, page_size, topic_id_list=None): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. """ course = _get_course_or_404(course_key, request.user) context = get_context(course, request) topic_ids_csv = ",".join(topic_id_list) if topic_id_list else None threads, result_page, num_pages, _ = Thread.search({ "course_id": unicode(course.id), "group_id": ( None if context["is_requester_privileged"] else get_cohort_id(request.user, course.id) ), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, "commentable_ids": topic_ids_csv, }) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [ThreadSerializer(thread, context=context).data for thread in threads] return get_paginated_data(request, results, page, num_pages)
def get_thread_list(request, course_key, page, page_size): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. """ user_is_privileged = Role.objects.filter( course_id=course_key, name__in=[FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA], users=request.user ).exists() threads, result_page, num_pages, _ = Thread.search({ "course_id": unicode(course_key), "group_id": None if user_is_privileged else get_cohort_id(request.user, course_key), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, }) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [_cc_thread_to_api_thread(thread) for thread in threads] return get_paginated_data(request, results, page, num_pages)
def get_thread_list( request, course_key, page, page_size, topic_id_list=None, text_search=None, following=False, view=None, order_by="last_activity_at", order_direction="desc", ): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following view: filters for either "unread" or "unanswered" threads order_by: The key in which to sort the threads by. The only values are "last_activity_at", "comment_count", and "vote_count". The default is "last_activity_at". order_direction: The direction in which to sort the threads by. The only values are "asc" or "desc". The default is "desc". Note that topic_id_list, text_search, and following are mutually exclusive. Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. Raises: ValidationError: if an invalid value is passed for a field. ValueError: if more than one of the mutually exclusive parameters is provided Http404: if the requesting user does not have access to the requested course or a page beyond the last is requested """ exclusive_param_count = sum(1 for param in [topic_id_list, text_search, following] if param) if exclusive_param_count > 1: # pragma: no cover raise ValueError("More than one mutually exclusive param passed to get_thread_list") cc_map = {"last_activity_at": "date", "comment_count": "comments", "vote_count": "votes"} if order_by not in cc_map: raise ValidationError({ "order_by": ["Invalid value. '{}' must be 'last_activity_at', 'comment_count', or 'vote_count'".format(order_by)] }) if order_direction not in ["asc", "desc"]: raise ValidationError({ "order_direction": ["Invalid value. '{}' must be 'asc' or 'desc'".format(order_direction)] }) course = _get_course_or_404(course_key, request.user) context = get_context(course, request) query_params = { "user_id": unicode(request.user.id), "group_id": ( None if context["is_requester_privileged"] else get_cohort_id(request.user, course.id) ), "page": page, "per_page": page_size, "text": text_search, "sort_key": cc_map.get(order_by), "sort_order": order_direction, } text_search_rewrite = None if view: if view in ["unread", "unanswered"]: query_params[view] = "true" else: ValidationError({ "view": ["Invalid value. '{}' must be 'unread' or 'unanswered'".format(view)] }) if following: threads, result_page, num_pages = context["cc_requester"].subscribed_threads(query_params) else: query_params["course_id"] = unicode(course.id) query_params["commentable_ids"] = ",".join(topic_id_list) if topic_id_list else None query_params["text"] = text_search threads, result_page, num_pages, text_search_rewrite = Thread.search(query_params) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [ThreadSerializer(thread, context=context).data for thread in threads] ret = get_paginated_data(request, results, page, num_pages) ret["text_search_rewrite"] = text_search_rewrite return ret
def get_thread_list( request, course_key, page, page_size, topic_id_list=None, text_search=None, following=False, view=None, order_by="last_activity_at", order_direction="desc", requested_fields=None, ): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following view: filters for either "unread" or "unanswered" threads order_by: The key in which to sort the threads by. The only values are "last_activity_at", "comment_count", and "vote_count". The default is "last_activity_at". order_direction: The direction in which to sort the threads by. The default and only value is "desc". This will be removed in a future major version. requested_fields: Indicates which additional fields to return for each thread. (i.e. ['profile_image']) Note that topic_id_list, text_search, and following are mutually exclusive. Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. Raises: ValidationError: if an invalid value is passed for a field. ValueError: if more than one of the mutually exclusive parameters is provided CourseNotFoundError: if the requesting user does not have access to the requested course PageNotFoundError: if page requested is beyond the last """ exclusive_param_count = sum( 1 for param in [topic_id_list, text_search, following] if param) if exclusive_param_count > 1: # pragma: no cover raise ValueError( "More than one mutually exclusive param passed to get_thread_list") cc_map = { "last_activity_at": "activity", "comment_count": "comments", "vote_count": "votes" } if order_by not in cc_map: raise ValidationError({ "order_by": [ "Invalid value. '{}' must be 'last_activity_at', 'comment_count', or 'vote_count'" .format(order_by) ] }) if order_direction != "desc": raise ValidationError({ "order_direction": ["Invalid value. '{}' must be 'desc'".format(order_direction)] }) course = _get_course(course_key, request.user) context = get_context(course, request) query_params = { "user_id": unicode(request.user.id), "group_id": (None if context["is_requester_privileged"] else get_cohort_id( request.user, course.id)), "page": page, "per_page": page_size, "text": text_search, "sort_key": cc_map.get(order_by), } if view: if view in ["unread", "unanswered"]: query_params[view] = "true" else: ValidationError({ "view": [ "Invalid value. '{}' must be 'unread' or 'unanswered'". format(view) ] }) if following: paginated_results = context["cc_requester"].subscribed_threads( query_params) else: query_params["course_id"] = unicode(course.id) query_params["commentable_ids"] = ",".join( topic_id_list) if topic_id_list else None query_params["text"] = text_search paginated_results = Thread.search(query_params) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a PageNotFoundError in that case if paginated_results.page != page: raise PageNotFoundError("Page not found (No results on this page).") results = _serialize_discussion_entities(request, context, paginated_results.collection, requested_fields, DiscussionEntity.thread) paginator = DiscussionAPIPagination(request, paginated_results.page, paginated_results.num_pages, paginated_results.thread_count) return paginator.get_paginated_response({ "results": results, "text_search_rewrite": paginated_results.corrected_text, })
def get_thread_list( request, course_key, page, page_size, topic_id_list=None, text_search=None, following=False, view=None, order_by="last_activity_at", order_direction="desc", requested_fields=None, ): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following view: filters for either "unread" or "unanswered" threads order_by: The key in which to sort the threads by. The only values are "last_activity_at", "comment_count", and "vote_count". The default is "last_activity_at". order_direction: The direction in which to sort the threads by. The default and only value is "desc". This will be removed in a future major version. requested_fields: Indicates which additional fields to return for each thread. (i.e. ['profile_image']) Note that topic_id_list, text_search, and following are mutually exclusive. Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. Raises: ValidationError: if an invalid value is passed for a field. ValueError: if more than one of the mutually exclusive parameters is provided CourseNotFoundError: if the requesting user does not have access to the requested course PageNotFoundError: if page requested is beyond the last """ exclusive_param_count = sum(1 for param in [topic_id_list, text_search, following] if param) if exclusive_param_count > 1: # pragma: no cover raise ValueError("More than one mutually exclusive param passed to get_thread_list") cc_map = {"last_activity_at": "activity", "comment_count": "comments", "vote_count": "votes"} if order_by not in cc_map: raise ValidationError({ "order_by": ["Invalid value. '{}' must be 'last_activity_at', 'comment_count', or 'vote_count'".format(order_by)] }) if order_direction != "desc": raise ValidationError({ "order_direction": ["Invalid value. '{}' must be 'desc'".format(order_direction)] }) course = _get_course(course_key, request.user) context = get_context(course, request) query_params = { "user_id": unicode(request.user.id), "group_id": ( None if context["is_requester_privileged"] else get_cohort_id(request.user, course.id) ), "page": page, "per_page": page_size, "text": text_search, "sort_key": cc_map.get(order_by), } if view: if view in ["unread", "unanswered"]: query_params[view] = "true" else: ValidationError({ "view": ["Invalid value. '{}' must be 'unread' or 'unanswered'".format(view)] }) if following: paginated_results = context["cc_requester"].subscribed_threads(query_params) else: query_params["course_id"] = unicode(course.id) query_params["commentable_ids"] = ",".join(topic_id_list) if topic_id_list else None query_params["text"] = text_search paginated_results = Thread.search(query_params) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a PageNotFoundError in that case if paginated_results.page != page: raise PageNotFoundError("Page not found (No results on this page).") results = _serialize_discussion_entities( request, context, paginated_results.collection, requested_fields, DiscussionEntity.thread ) paginator = DiscussionAPIPagination( request, paginated_results.page, paginated_results.num_pages, paginated_results.thread_count ) return paginator.get_paginated_response({ "results": results, "text_search_rewrite": paginated_results.corrected_text, })
def get_thread_list(request, course_key, page, page_size, topic_id_list=None, text_search=None, following=False): """ Return the list of all discussion threads pertaining to the given course Parameters: request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following Note that topic_id_list, text_search, and following are mutually exclusive. Returns: A paginated result containing a list of threads; see discussion_api.views.ThreadViewSet for more detail. Raises: ValueError: if more than one of the mutually exclusive parameters is provided Http404: if the requesting user does not have access to the requested course or a page beyond the last is requested """ exclusive_param_count = sum( 1 for param in [topic_id_list, text_search, following] if param) if exclusive_param_count > 1: # pragma: no cover raise ValueError( "More than one mutually exclusive param passed to get_thread_list") course = _get_course_or_404(course_key, request.user) context = get_context(course, request) query_params = { "group_id": (None if context["is_requester_privileged"] else get_cohort_id( request.user, course.id)), "sort_key": "date", "sort_order": "desc", "page": page, "per_page": page_size, "text": text_search, } text_search_rewrite = None if following: threads, result_page, num_pages = context[ "cc_requester"].subscribed_threads(query_params) else: query_params["course_id"] = unicode(course.id) query_params["commentable_ids"] = ",".join( topic_id_list) if topic_id_list else None query_params["text"] = text_search threads, result_page, num_pages, text_search_rewrite = Thread.search( query_params) # The comments service returns the last page of results if the requested # page is beyond the last page, but we want be consistent with DRF's general # behavior and return a 404 in that case if result_page != page: raise Http404 results = [ ThreadSerializer(thread, context=context).data for thread in threads ] ret = get_paginated_data(request, results, page, num_pages) ret["text_search_rewrite"] = text_search_rewrite return ret
def get(self, request, course_id, section_id): try: course_key = SlashSeparatedCourseKey.from_deprecated_string( course_id) except Exception as e: return Resposne(data={"Error": e.message}) course = get_course_by_id(course_key) with modulestore().bulk_operations(course.id): course_module = get_module_for_descriptor(request.user, request, course, None, course.id, course=course) if course_module is None: return Response( data={"Error": "User is not allowed to do the operation"}) commentable_id_list = [] for chapter in course_module.get_children(): for section in chapter.get_children(): if section_id == section.url_name: for unit in section.get_children(): for vertical in unit.get_children(): if vertical.category == 'discussion': commentable_id_list.append( vertical.discussion_id) break count = 0 for cid in commentable_id_list: query_params = { "course_id": course_id, "user_id": request.user.id, "commentable_id": cid } threads = Thread.search(query_params).collection for thread in threads: if thread['thread_type'] == "discussion": request.GET = {'thread_id': thread['id']} elif thread['thread_type'] == "question": request.GET = { 'thread_id': thread['id'], 'endorsed': False } else: pass if thread['username'] == request.user.username: count = count + 1 list_comments = CommentViewSet() comments = list_comments.list(request).data for comment in comments['results']: if comment['author'] == request.user.username: count = count + 1 if comment['child_count'] > 0: child_comments = list_comments.retrieve( request, comment_id=comment['id']).data for child_comment in child_comments['results']: if child_comment[ 'author'] == request.user.username: count = count + 1 return Response( data={ "Course_id": course_id, "Section_id": section_id, "User": request.user.username, "Comment Count": count, }) else: return Response( data={"Error": "No active discussion for given section_id"})