示例#1
0
def get_group_id_for_comments_service(request, course_key, commentable_id=None):
    """
    Given a user requesting content within a `commentable_id`, determine the
    group_id which should be passed to the comments service.

    Returns:
        int: the group_id to pass to the comments service or None if nothing
        should be passed

    Raises:
        ValueError if the requested group_id is invalid
    """
    if commentable_id is None or is_commentable_cohorted(course_key, commentable_id):
        if request.method == "GET":
            requested_group_id = request.GET.get('group_id')
        elif request.method == "POST":
            requested_group_id = request.POST.get('group_id')
        if cached_has_permission(request.user, "see_all_cohorts", course_key):
            if not requested_group_id:
                return None
            try:
                group_id = int(requested_group_id)
                get_cohort_by_id(course_key, group_id)
            except CourseUserGroup.DoesNotExist:
                raise ValueError
        else:
            # regular users always query with their own id.
            group_id = get_cohort_id(request.user, course_key)
        return group_id
    else:
        # Never pass a group_id to the comments service for a non-cohorted
        # commentable
        return None
示例#2
0
def get_group_id_for_comments_service(request, course_key, commentable_id=None):
    """
    Given a user requesting content within a `commentable_id`, determine the
    group_id which should be passed to the comments service.

    Returns:
        int: the group_id to pass to the comments service or None if nothing
        should be passed

    Raises:
        ValueError if the requested group_id is invalid
    """
    if commentable_id is None or is_commentable_cohorted(course_key, commentable_id):
        if request.method == "GET":
            requested_group_id = request.GET.get('group_id')
        elif request.method == "POST":
            requested_group_id = request.POST.get('group_id')
        if cached_has_permission(request.user, "see_all_cohorts", course_key):
            if not requested_group_id:
                return None
            try:
                group_id = int(requested_group_id)
                get_cohort_by_id(course_key, group_id)
            except CourseUserGroup.DoesNotExist:
                raise ValueError
        else:
            # regular users always query with their own id.
            group_id = get_cohort_id(request.user, course_key)
        return group_id
    else:
        # Never pass a group_id to the comments service for a non-cohorted
        # commentable
        return None
def inline_discussion(request, course_id, discussion_id,tags_type):
    """
    Renders JSON for DiscussionModules
    """
    course = get_course_with_access(request.user, course_id, 'load_forum')

    try:
        threads, query_params = get_threads_tags(request, course_id, tags_type, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()
    except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError):
        # TODO (vshnayder): since none of this code seems to be aware of the fact that
        # sometimes things go wrong, I suspect that the js client is also not
        # checking for errors on request.  Check and fix as needed.
        log.error("Error loading inline discussion threads.")
        raise Http404

    annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    allow_anonymous = course.allow_anonymous
    allow_anonymous_to_peers = course.allow_anonymous_to_peers

    #since inline is all one commentable, only show or allow the choice of cohorts
    #if the commentable is cohorted, otherwise everything is not cohorted
    #and no one has the option of choosing a cohort
    is_cohorted = is_course_cohorted(course_id) and is_commentable_cohorted(course_id, discussion_id)
    is_moderator = cached_has_permission(request.user, "see_all_cohorts", course_id)

    cohorts_list = list()

    if is_cohorted:
        cohorts_list.append({'name': 'All Groups', 'id': None})

        #if you're a mod, send all cohorts and let you pick

        if is_moderator:
            cohorts = get_course_cohorts(course_id)
            for cohort in cohorts:
                cohorts_list.append({'name': cohort.name, 'id': cohort.id})

        else:
            #students don't get to choose
            cohorts_list = None

    return utils.JsonResponse({
        'discussion_data': map(utils.safe_content, threads),
        'user_info': user_info,
        'annotated_content_info': annotated_content_info,
        'page': query_params['page'],
        'num_pages': query_params['num_pages'],
        'roles': utils.get_role_ids(course_id),
        'allow_anonymous_to_peers': allow_anonymous_to_peers,
        'allow_anonymous': allow_anonymous,
        'cohorts': cohorts_list,
        'is_moderator': is_moderator,
        'is_cohorted': is_cohorted
    })
示例#4
0
def inline_discussion(request, course_id, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, course_id, 'load_forum')

    try:
        threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()
    except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError):
        log.error("Error loading inline discussion threads.")
        raise

    with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    allow_anonymous = course.allow_anonymous
    allow_anonymous_to_peers = course.allow_anonymous_to_peers

    #since inline is all one commentable, only show or allow the choice of cohorts
    #if the commentable is cohorted, otherwise everything is not cohorted
    #and no one has the option of choosing a cohort
    is_cohorted = is_course_cohorted(course_id) and is_commentable_cohorted(course_id, discussion_id)
    is_moderator = cached_has_permission(request.user, "see_all_cohorts", course_id)

    cohorts_list = list()

    if is_cohorted:
        cohorts_list.append({'name': 'All Groups', 'id': None})

        #if you're a mod, send all cohorts and let you pick

        if is_moderator:
            cohorts = get_course_cohorts(course_id)
            for cohort in cohorts:
                cohorts_list.append({'name': cohort.name, 'id': cohort.id})

        else:
            #students don't get to choose
            cohorts_list = None

    return utils.JsonResponse({
        'discussion_data': map(utils.safe_content, threads),
        'user_info': user_info,
        'annotated_content_info': annotated_content_info,
        'page': query_params['page'],
        'num_pages': query_params['num_pages'],
        'roles': utils.get_role_ids(course_id),
        'allow_anonymous_to_peers': allow_anonymous_to_peers,
        'allow_anonymous': allow_anonymous,
        'cohorts': cohorts_list,
        'is_moderator': is_moderator,
        'is_cohorted': is_cohorted
    })
示例#5
0
def inline_discussion(request, course_id, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    course = get_course_with_access(request.user, course_id, 'load_forum')

    try:
        threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()
    except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError):
        # TODO (vshnayder): since none of this code seems to be aware of the fact that
        # sometimes things go wrong, I suspect that the js client is also not
        # checking for errors on request.  Check and fix as needed.
        log.error("Error loading inline discussion threads.")
        raise Http404

    annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    allow_anonymous = course.allow_anonymous
    allow_anonymous_to_peers = course.allow_anonymous_to_peers

    #since inline is all one commentable, only show or allow the choice of cohorts
    #if the commentable is cohorted, otherwise everything is not cohorted
    #and no one has the option of choosing a cohort
    is_cohorted = is_course_cohorted(course_id) and is_commentable_cohorted(course_id, discussion_id)
    is_moderator = cached_has_permission(request.user, "see_all_cohorts", course_id)

    cohorts_list = list()

    if is_cohorted:
        cohorts_list.append({'name': 'All Groups', 'id': None})

        #if you're a mod, send all cohorts and let you pick

        if is_moderator:
            cohorts = get_course_cohorts(course_id)
            for cohort in cohorts:
                cohorts_list.append({'name': cohort.name, 'id': cohort.id})

        else:
            #students don't get to choose
            cohorts_list = None

    return utils.JsonResponse({
        'discussion_data': map(utils.safe_content, threads),
        'user_info': user_info,
        'annotated_content_info': annotated_content_info,
        'page': query_params['page'],
        'num_pages': query_params['num_pages'],
        'roles': utils.get_role_ids(course_id),
        'allow_anonymous_to_peers': allow_anonymous_to_peers,
        'allow_anonymous': allow_anonymous,
        'cohorts': cohorts_list,
        'is_moderator': is_moderator,
        'is_cohorted': is_cohorted
    })
示例#6
0
def inline_discussion(request, course_id, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    nr_transaction = newrelic.agent.current_transaction()
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)

    course = get_course_with_access(request.user, 'load_forum', course_id)

    threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    allow_anonymous = course.allow_anonymous
    allow_anonymous_to_peers = course.allow_anonymous_to_peers

    #since inline is all one commentable, only show or allow the choice of cohorts
    #if the commentable is cohorted, otherwise everything is not cohorted
    #and no one has the option of choosing a cohort
    is_cohorted = is_course_cohorted(course_id) and is_commentable_cohorted(course_id, discussion_id)
    is_moderator = cached_has_permission(request.user, "see_all_cohorts", course_id)

    cohorts_list = list()

    if is_cohorted:
        cohorts_list.append({'name': _('All Groups'), 'id': None})

        #if you're a mod, send all cohorts and let you pick

        if is_moderator:
            cohorts = get_course_cohorts(course_id)
            for cohort in cohorts:
                cohorts_list.append({'name': cohort.name, 'id': cohort.id})

        else:
            #students don't get to choose
            cohorts_list = None

    return utils.JsonResponse({
        'discussion_data': map(utils.safe_content, threads),
        'user_info': user_info,
        'annotated_content_info': annotated_content_info,
        'page': query_params['page'],
        'num_pages': query_params['num_pages'],
        'roles': utils.get_role_ids(course_id),
        'allow_anonymous_to_peers': allow_anonymous_to_peers,
        'allow_anonymous': allow_anonymous,
        'cohorts': cohorts_list,
        'is_moderator': is_moderator,
        'is_cohorted': is_cohorted
    })
示例#7
0
    def test_is_commentable_cohorted(self):
        course = modulestore().get_course(self.toy_course_key)
        self.assertFalse(course.is_cohorted)

        def to_id(name):
            return topic_name_to_id(course, name)

        # no topics
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course doesn't even have a 'General' topic"
        )

        # not cohorted
        config_course_cohorts(course, ["General", "Feedback"], cohorted=False)

        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course isn't cohorted"
        )

        # cohorted, but top level topics aren't
        config_course_cohorts(course, ["General", "Feedback"], cohorted=True)

        self.assertTrue(course.is_cohorted)
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course is cohorted, but 'General' isn't."
        )
        self.assertTrue(
            cohorts.is_commentable_cohorted(course.id, to_id("random")),
            "Non-top-level discussion is always cohorted in cohorted courses."
        )

        # cohorted, including "Feedback" top-level topics aren't
        config_course_cohorts(
            course, ["General", "Feedback"],
            cohorted=True,
            cohorted_discussions=["Feedback"]
        )

        self.assertTrue(course.is_cohorted)
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course is cohorted, but 'General' isn't."
        )
        self.assertTrue(
            cohorts.is_commentable_cohorted(course.id, to_id("Feedback")),
            "Feedback was listed as cohorted.  Should be."
        )
示例#8
0
    def test_is_commentable_cohorted(self):
        course = modulestore().get_course(self.toy_course_key)
        self.assertFalse(course.is_cohorted)

        def to_id(name):
            return self.topic_name_to_id(course, name)

        # no topics
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course doesn't even have a 'General' topic")

        # not cohorted
        self.config_course_cohorts(course, ["General", "Feedback"],
                                   cohorted=False)

        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course isn't cohorted")

        # cohorted, but top level topics aren't
        self.config_course_cohorts(course, ["General", "Feedback"],
                                   cohorted=True)

        self.assertTrue(course.is_cohorted)
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course is cohorted, but 'General' isn't.")

        self.assertTrue(
            cohorts.is_commentable_cohorted(course.id, to_id("random")),
            "Non-top-level discussion is always cohorted in cohorted courses.")

        # cohorted, including "Feedback" top-level topics aren't
        self.config_course_cohorts(course, ["General", "Feedback"],
                                   cohorted=True,
                                   cohorted_discussions=["Feedback"])

        self.assertTrue(course.is_cohorted)
        self.assertFalse(
            cohorts.is_commentable_cohorted(course.id, to_id("General")),
            "Course is cohorted, but 'General' isn't.")

        self.assertTrue(
            cohorts.is_commentable_cohorted(course.id, to_id("Feedback")),
            "Feedback was listed as cohorted.  Should be.")
示例#9
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course = get_course_with_access(request.user, course_id, 'load')
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers',
                                      'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    if 'title' not in post or not post['title'].strip():
        return JsonError(_("Title can't be empty"))
    if 'body' not in post or not post['body'].strip():
        return JsonError(_("Body can't be empty"))

    thread = cc.Thread(**extract(post, ['body', 'title']))
    thread.update_attributes(
        **{
            'anonymous': anonymous,
            'anonymous_to_peers': anonymous_to_peers,
            'commentable_id': commentable_id,
            'course_id': course_id,
            'user_id': request.user.id,
        })

    user = cc.User.from_django_user(request.user)

    #kevinchugh because the new requirement is that all groups will be determined
    #by the group id in the request this all goes away
    #not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    #patch for backward compatibility to comments service
    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(thread)
    data = thread.to_dict()
    add_courseware_context([data], course)
    if request.is_ajax():
        return ajax_content_response(request, course_id, data)
    else:
        return JsonResponse(utils.safe_content(data))
示例#10
0
def single_thread(request, course_id, discussion_id, thread_id):
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_key)
    course_settings = make_course_settings(course, include_category_map=True)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()
    is_moderator = cached_has_permission(request.user, "see_all_cohorts",
                                         course_key)

    # Currently, the front end always loads responses via AJAX, even for this
    # page; it would be a nice optimization to avoid that extra round trip to
    # the comments service.
    try:
        thread = cc.Thread.find(thread_id).retrieve(
            recursive=request.is_ajax(),
            user_id=request.user.id,
            response_skip=request.GET.get("resp_skip"),
            response_limit=request.GET.get("resp_limit"))
    except cc.utils.CommentClientRequestError as e:
        if e.status_code == 404:
            raise Http404
        raise

    # verify that the thread belongs to the requesting student's cohort
    if is_commentable_cohorted(course_key, discussion_id) and not is_moderator:
        user_group_id = get_cohort_id(request.user, course_key)
        if getattr(thread, "group_id",
                   None) is not None and user_group_id != thread.group_id:
            raise Http404

    is_staff = cached_has_permission(request.user, 'openclose_thread',
                                     course.id)
    if request.is_ajax():
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(
                course_key, thread, request.user, user_info=user_info)
        content = utils.prepare_content(thread.to_dict(), course_key, is_staff)
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context([content], course)
        return utils.JsonResponse({
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })

    else:
        try:
            threads, query_params = get_threads(request, course_key)
        except ValueError:
            return HttpResponseBadRequest("Invalid group_id")
        threads.append(thread.to_dict())

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context(threads, course)

        for thread in threads:
            #patch for backward compatibility with comments service
            if not "pinned" in thread:
                thread["pinned"] = False

        threads = [
            utils.prepare_content(thread, course_key, is_staff)
            for thread in threads
        ]

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_key, threads, request.user, user_info)

        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            user_cohort = get_cohort_id(request.user, course_key)

        context = {
            'discussion_id':
            discussion_id,
            'csrf':
            csrf(request)['csrf_token'],
            'init':
            '',  # TODO: What is this?
            'user_info':
            _attr_safe_json(user_info),
            'annotated_content_info':
            _attr_safe_json(annotated_content_info),
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            'course_id':
            course.id.to_deprecated_string(
            ),  # TODO: Why pass both course and course.id to template?
            'thread_id':
            thread_id,
            'threads':
            _attr_safe_json(threads),
            'roles':
            _attr_safe_json(utils.get_role_ids(course_key)),
            'is_moderator':
            is_moderator,
            'thread_pages':
            query_params['num_pages'],
            'is_course_cohorted':
            is_course_cohorted(course_key),
            'flag_moderator':
            cached_has_permission(request.user, 'openclose_thread', course.id)
            or has_access(request.user, 'staff', course),
            'cohorts':
            course_settings["cohorts"],
            'user_cohort':
            user_cohort,
            'sort_preference':
            cc_user.default_sort_key,
            'category_map':
            course_settings["category_map"],
            'course_settings':
            _attr_safe_json(course_settings)
        }
        return render_to_response('discussion/index.html', context)
示例#11
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course = get_course_with_access(request.user, course_id, 'load')
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get(
            'anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    thread = cc.Thread(**extract(post, ['body', 'title', 'tags']))
    thread.update_attributes(**{
        'anonymous': anonymous,
        'anonymous_to_peers': anonymous_to_peers,
        'commentable_id': commentable_id,
        'course_id': course_id,
        'user_id': request.user.id,
    })

    user = cc.User.from_django_user(request.user)

    # kevinchugh because the new requirement is that all groups will be determined
    # by the group id in the request this all goes away
    # not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    # patch for backward compatibility to comments service
    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(thread)
    courseware_context = get_courseware_context(thread, course)
    data = thread.to_dict()
    if courseware_context:
        data.update(courseware_context)
    if request.is_ajax():
        return ajax_content_response(request, course_id, data, 'discussion/ajax_create_thread.html')
    else:
        return JsonResponse(utils.safe_content(data))
示例#12
0
def single_thread(request, course_id, discussion_id, thread_id):
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_key)
    course_settings = make_course_settings(course, include_category_map=True)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()
    is_moderator = cached_has_permission(request.user, "see_all_cohorts", course_key)

    # Currently, the front end always loads responses via AJAX, even for this
    # page; it would be a nice optimization to avoid that extra round trip to
    # the comments service.
    try:
        thread = cc.Thread.find(thread_id).retrieve(
            recursive=request.is_ajax(),
            user_id=request.user.id,
            response_skip=request.GET.get("resp_skip"),
            response_limit=request.GET.get("resp_limit")
        )
    except cc.utils.CommentClientRequestError as e:
        if e.status_code == 404:
            raise Http404
        raise

    # verify that the thread belongs to the requesting student's cohort
    if is_commentable_cohorted(course_key, discussion_id) and not is_moderator:
        user_group_id = get_cohort_id(request.user, course_key)
        if getattr(thread, "group_id", None) is not None and user_group_id != thread.group_id:
            raise Http404

    is_staff = cached_has_permission(request.user, 'openclose_thread', course.id)
    if request.is_ajax():
        with newrelic.agent.FunctionTrace(nr_transaction, "get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(course_key, thread, request.user, user_info=user_info)
        content = utils.prepare_content(thread.to_dict(), course_key, is_staff)
        with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
            add_courseware_context([content], course)
        return utils.JsonResponse({
            'content': content,
            'annotated_content_info': annotated_content_info,
        })

    else:
        try:
            threads, query_params = get_threads(request, course_key)
        except ValueError:
            return HttpResponseBadRequest("Invalid group_id")
        threads.append(thread.to_dict())

        with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
            add_courseware_context(threads, course)

        for thread in threads:
            #patch for backward compatibility with comments service
            if not "pinned" in thread:
                thread["pinned"] = False

        threads = [utils.prepare_content(thread, course_key, is_staff) for thread in threads]

        with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(course_key, threads, request.user, user_info)

        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            user_cohort = get_cohort_id(request.user, course_key)

        context = {
            'discussion_id': discussion_id,
            'csrf': csrf(request)['csrf_token'],
            'init': '',   # TODO: What is this?
            'user_info': _attr_safe_json(user_info),
            'annotated_content_info': _attr_safe_json(annotated_content_info),
            'course': course,
            #'recent_active_threads': recent_active_threads,
            'course_id': course.id.to_deprecated_string(),   # TODO: Why pass both course and course.id to template?
            'thread_id': thread_id,
            'threads': _attr_safe_json(threads),
            'roles': _attr_safe_json(utils.get_role_ids(course_key)),
            'is_moderator': is_moderator,
            'thread_pages': query_params['num_pages'],
            'is_course_cohorted': is_course_cohorted(course_key),
            'flag_moderator': cached_has_permission(request.user, 'openclose_thread', course.id) or has_access(request.user, 'staff', course),
            'cohorts': course_settings["cohorts"],
            'user_cohort': user_cohort,
            'sort_preference': cc_user.default_sort_key,
            'category_map': course_settings["category_map"],
            'course_settings': _attr_safe_json(course_settings)
        }
        return render_to_response('discussion/index.html', context)
示例#13
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get("anonymous", "false").lower() == "true"
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get("anonymous_to_peers", "false").lower() == "true"
    else:
        anonymous_to_peers = False

    if "title" not in post or not post["title"].strip():
        return JsonError(_("Title can't be empty"))
    if "body" not in post or not post["body"].strip():
        return JsonError(_("Body can't be empty"))

    thread = cc.Thread(
        anonymous=anonymous,
        anonymous_to_peers=anonymous_to_peers,
        commentable_id=commentable_id,
        course_id=course_key.to_deprecated_string(),
        user_id=request.user.id,
        thread_type=post["thread_type"],
        body=post["body"],
        title=post["title"],
    )

    user = cc.User.from_django_user(request.user)

    # kevinchugh because the new requirement is that all groups will be determined
    # by the group id in the request this all goes away
    # not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_key, commentable_id):
        user_group_id = get_cohort_id(user, course_key)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_key):
            # admins can optionally choose what group to post as
            try:
                group_id = int(post.get("group_id", user_group_id))
                get_cohort_by_id(course_key, group_id)
            except (ValueError, CourseUserGroup.DoesNotExist):
                return HttpResponseBadRequest("Invalid cohort id")
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.group_id = group_id

    thread.save()

    # patch for backward compatibility to comments service
    if not "pinned" in thread.attributes:
        thread["pinned"] = False

    if post.get("auto_subscribe", "false").lower() == "true":
        user = cc.User.from_django_user(request.user)
        user.follow(thread)
    data = thread.to_dict()
    add_thread_group_name(data, course_key)
    add_courseware_context([data], course)
    if request.is_ajax():
        return ajax_content_response(request, course_key, data)
    else:
        return JsonResponse(safe_content(data, course_key))
示例#14
0
def mobi_create_thread(request, course_id, topic_id):
    """
    Given a course and commentable_id from mobile. create the thread
    """
    course_id = course_id.replace('.', '/')
    log.debug("Creating new thread in %r, id %r", course_id, topic_id)
    course = get_course_with_access(request.user, course_id, 'load')
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    if 'title' not in post or not post['title'].strip():
        return JsonResponse({'success': False, 'errmsg': "Title can't be empty"})
    if 'body' not in post or not post['body'].strip():
        return JsonResponse({'success': False, 'errmsg': "Body can't be empty"})

    thread = cc.Thread(**extract(post, ['body', 'title']))

    user = cc.User.from_django_user(request.user)

    thread.update_attributes(**{
        'anonymous': anonymous,
        'anonymous_to_peers': anonymous_to_peers,
        'commentable_id': topic_id,
        'course_id': course_id,
        'user_id': request.user.id,
    })

    if is_commentable_cohorted(course_id, topic_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    # if post.get('auto_subscribe', 'false').lower() == 'true':
    user = cc.User.from_django_user(request.user)
    user.follow(thread)

    return JsonResponse({"success": True})
示例#15
0
def mobi_create_thread(request, course_id, topic_id):
    """
    Given a course and commentable_id from mobile. create the thread
    """
    course_id = course_id.replace('.', '/')
    log.debug("Creating new thread in %r, id %r", course_id, topic_id)
    course = get_course_with_access(request.user, course_id, 'load')
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers',
                                      'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    if 'title' not in post or not post['title'].strip():
        return JsonResponse({
            'success': False,
            'errmsg': "Title can't be empty"
        })
    if 'body' not in post or not post['body'].strip():
        return JsonResponse({
            'success': False,
            'errmsg': "Body can't be empty"
        })

    thread = cc.Thread(**extract(post, ['body', 'title']))

    user = cc.User.from_django_user(request.user)

    thread.update_attributes(
        **{
            'anonymous': anonymous,
            'anonymous_to_peers': anonymous_to_peers,
            'commentable_id': topic_id,
            'course_id': course_id,
            'user_id': request.user.id,
        })

    if is_commentable_cohorted(course_id, topic_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    # if post.get('auto_subscribe', 'false').lower() == 'true':
    user = cc.User.from_django_user(request.user)
    user.follow(thread)

    return JsonResponse({"success": True})
示例#16
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course = get_course_with_access(request.user, course_id, "load")
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get("anonymous", "false").lower() == "true"
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get("anonymous_to_peers", "false").lower() == "true"
    else:
        anonymous_to_peers = False

    if "title" not in post or not post["title"].strip():
        return JsonError(_("Title can't be empty"))
    if "body" not in post or not post["body"].strip():
        return JsonError(_("Body can't be empty"))

    thread = cc.Thread(**extract(post, ["body", "title"]))
    thread.update_attributes(
        **{
            "anonymous": anonymous,
            "anonymous_to_peers": anonymous_to_peers,
            "commentable_id": commentable_id,
            "course_id": course_id,
            "user_id": request.user.id,
        }
    )

    user = cc.User.from_django_user(request.user)

    # kevinchugh because the new requirement is that all groups will be determined
    # by the group id in the request this all goes away
    # not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get("group_id", user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    # patch for backward compatibility to comments service
    if not "pinned" in thread.attributes:
        thread["pinned"] = False

    if post.get("auto_subscribe", "false").lower() == "true":
        user = cc.User.from_django_user(request.user)
        user.follow(thread)
    data = thread.to_dict()
    add_courseware_context([data], course)
    if request.is_ajax():
        return ajax_content_response(request, course_id, data)
    else:
        return JsonResponse(utils.safe_content(data))
示例#17
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_with_access(request.user, 'load', course_id)
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    if 'title' not in post or not post['title'].strip():
        return JsonError(_("Title can't be empty"))
    if 'body' not in post or not post['body'].strip():
        return JsonError(_("Body can't be empty"))

    thread = cc.Thread(
        anonymous=anonymous,
        anonymous_to_peers=anonymous_to_peers,
        commentable_id=commentable_id,
        course_id=course_id.to_deprecated_string(),
        user_id=request.user.id,
        body=post["body"],
        title=post["title"]
    )

    user = cc.User.from_django_user(request.user)

    #kevinchugh because the new requirement is that all groups will be determined
    #by the group id in the request this all goes away
    #not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.group_id = group_id

    thread.save()

    #patch for backward compatibility to comments service
    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(thread)
    data = thread.to_dict()
    add_courseware_context([data], course)
    if request.is_ajax():
        return ajax_content_response(request, course_id, data)
    else:
        return JsonResponse(safe_content(data))
def create_thread(request, course_id, commentable_id, thread_data, portfolio_user, id_map):
    """
    Given a course and commentble ID, create the thread
    """
    course = get_course_with_access(portfolio_user, course_id, 'load')
   
    if course.allow_anonymous:
        anonymous = thread_data.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = thread_data.get('anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False
    thread = cc.Thread(**extract(thread_data, ['body', 'title', 'tags']))
    thread.update_attributes(**{
        'anonymous': anonymous,
        'anonymous_to_peers': anonymous_to_peers,
        'commentable_id': commentable_id,
        'course_id': course_id,
        'user_id': portfolio_user.id,
    })
    
    user = cc.User.from_django_user(portfolio_user)

    #kevinchugh because the new requirement is that all groups will be determined
    #by the group id in the request this all goes away
    #not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(portfolio_user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = thread_data.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()
    #patch for backward compatibility to comments service
    if not 'pinned' in thread.attributes:
        thread['pinned'] = False

    if thread_data.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(portfolio_user)
        user.follow(thread)
    #courseware_context = get_courseware_context(thread, course)
    data = thread.to_dict()
    '''
    id = data['commentable_id']
    content_info = None
    if id in id_map:
        location = id_map[id]["location"].url()
        title = id_map[id]["title"]

        url = reverse('jump_to', kwargs={"course_id": course.location.course_id,
                  "location": location})

        data.update({"courseware_url": url, "courseware_title": title})
    '''
    #if courseware_context:
    #    data.update(courseware_context)  
    return ajax_content_response(request, course_id, data, 'discussion/ajax_create_thread.html')
    '''