Example #1
0
    def get(self):
        user_data = user_models.UserData.current()
        question_key = self.request.get("question_key")
        question = db.get(question_key)

        if question:
            video = question.video()
            dict_votes = discussion_models.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)

            answers = discussion_models.Feedback.gql(
                "WHERE types = :1 AND targets = :2",
                discussion_models.FeedbackType.Answer,
                question.key()).fetch(1000)
            answers = filter(lambda answer: answer.is_visible_to(user_data),
                             answers)
            answers = voting.VotingSortOrder.sort(answers)

            for answer in answers:
                voting.add_vote_expando_properties(answer, dict_votes)

            template_values = {
                "answers": answers,
                "is_mod": user_util.is_current_user_moderator()
            }

            html = self.render_jinja2_template_to_string(
                'discussion/question_answers_only.html', template_values)
            self.render_json({"html": html})

        return
Example #2
0
    def get(self):
        user_data = models.UserData.current()
        question_key = self.request.get("question_key")
        question = db.get(question_key)

        if question:
            video = question.video()
            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)

            answers = models_discussion.Feedback.gql(
                "WHERE types = :1 AND targets = :2 AND deleted = :3 AND is_hidden_by_flags = :4",
                models_discussion.FeedbackType.Answer, question.key(), False,
                False).fetch(1000)
            answers = voting.VotingSortOrder.sort(answers)

            for answer in answers:
                voting.add_vote_expando_properties(answer, dict_votes)

            template_values = {
                "answers": answers,
                "is_mod": util_discussion.is_current_user_moderator()
            }

            html = self.render_jinja2_template_to_string(
                'discussion/question_answers_only.html', template_values)
            self.render_json({"html": html})

        return
Example #3
0
    def get(self):
        user_data = user_models.UserData.current()
        question_key = self.request.get("question_key")
        question = db.get(question_key)

        if question:
            video = question.video()
            dict_votes = discussion_models.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)

            answers = discussion_models.Feedback.gql("WHERE types = :1 AND targets = :2", discussion_models.FeedbackType.Answer, question.key()).fetch(1000)
            answers = filter(lambda answer: answer.is_visible_to(user_data), answers)
            answers = voting.VotingSortOrder.sort(answers)

            for answer in answers:
                voting.add_vote_expando_properties(answer, dict_votes)

            template_values = {
                "answers": answers,
                "is_mod": user_util.is_current_user_moderator()
            }

            html = self.render_jinja2_template_to_string('discussion/question_answers_only.html', template_values)
            self.render_json({"html": html})

        return
Example #4
0
def update_feedback(feedback_key, text, feedback_type,
    parent_key_or_id=None):
    """Update the text of a question or answer.

    Returns a util_discussion.ClientFeedback entity for the added feedback, if
    successful, or None.

    Arguments:
        feedback_key: the key of feedback that is to be updated
        text: the desired feedback text property
        feedback_type: either FeedbackType.Question or FeedbackType.Answer
        parent_key_or_id: readable_id if adding a question, question_key if
                          adding an answer
    """
    user_data = user_models.UserData.current()

    # parent will only be initialized if parent_key_or_id was initialized
    if parent_key_or_id:
        parent = video_models.Video.get_for_readable_id(parent_key_or_id)

    feedback = db.get(feedback_key)

    is_answer = feedback_type == discussion_models.FeedbackType.Answer

    # TODO(drew): Do we really need to use video here?
    if feedback and text and (is_answer or parent):
        if (feedback.authored_by(user_data) or
            user_util.is_current_user_moderator()):
            feedback.content = text

            # If a moderator rewrote the content, then it's not spam.
            # Otherwise, reset the var to false (it could have turned into
            # spam)
            feedback.definitely_not_spam = (user_util.
                is_current_user_moderator())

            # Recalculate the low quality metric as the content changed
            feedback.low_quality_score = (discussion_models.
                Heuristics.get_low_quality_score(text, feedback_type))

            feedback.put()

        if is_answer:
            dict_votes = discussion_models.FeedbackVote.get_dict_for_feedback(
                feedback, user_data)

        else:
            dict_votes = (discussion_models.
                FeedbackVote.get_dict_for_user_data_and_video(
                user_data, parent))

        voting.add_vote_expando_properties(feedback, dict_votes)
        return util_discussion.ClientFeedback.from_feedback(feedback,
            with_extra_vote_properties=True)

    return None
Example #5
0
def update_feedback(feedback_key, text, feedback_type, parent_key_or_id=None):
    """Update the text of a question or answer.

    Returns a util_discussion.ClientFeedback entity for the added feedback, if
    successful, or None.

    Arguments:
        feedback_key: the key of feedback that is to be updated
        text: the desired feedback text property
        feedback_type: either FeedbackType.Question or FeedbackType.Answer
        parent_key_or_id: readable_id if adding a question, question_key if
                          adding an answer
    """
    user_data = user_models.UserData.current()

    # parent will only be initialized if parent_key_or_id was initialized
    if parent_key_or_id:
        parent = video_models.Video.get_for_readable_id(parent_key_or_id)

    feedback = db.get(feedback_key)

    is_answer = feedback_type == discussion_models.FeedbackType.Answer

    # TODO(drew): Do we really need to use video here?
    if feedback and text and (is_answer or parent):
        if (feedback.authored_by(user_data)
                or user_util.is_current_user_moderator()):
            feedback.content = text

            # If a moderator rewrote the content, then it's not spam.
            # Otherwise, reset the var to false (it could have turned into
            # spam)
            feedback.definitely_not_spam = (
                user_util.is_current_user_moderator())

            # Recalculate the low quality metric as the content changed
            feedback.low_quality_score = (
                discussion_models.Heuristics.get_low_quality_score(
                    text, feedback_type))

            feedback.put()

        if is_answer:
            dict_votes = discussion_models.FeedbackVote.get_dict_for_feedback(
                feedback, user_data)

        else:
            dict_votes = (discussion_models.FeedbackVote.
                          get_dict_for_user_data_and_video(user_data, parent))

        voting.add_vote_expando_properties(feedback, dict_votes)
        return util_discussion.ClientFeedback.from_feedback(
            feedback, with_extra_vote_properties=True)

    return None
Example #6
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        # Whenever looking at this page, make sure the feedback count is recalculated
        # in case the user was notified about deleted or flagged posts.
        user_data.count_feedback_notification = -1
        user_data.put()

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            if video == None or type(video).__name__ != "Video":
                continue

            video_key = video.key()
            dict_videos[video_key] = video

            if dict_answers.has_key(video_key):
                dict_answers[video_key].append(answer)
            else:
                dict_answers[video_key] = [answer]

        videos = sorted(
            dict_videos.values(),
            key=lambda video: video.first_topic().title + video.title)

        context = {
            "email": user_data.email,
            "videos": videos,
            "dict_answers": dict_answers
        }

        self.render_jinja2_template(
            'discussion/video_feedback_notification_list.html', context)
Example #7
0
def video_comments_context(
        video,
        topic,
        page=0,
        comments_hidden=True,
        sort_order=voting.VotingSortOrder.HighestPointsFirst):

    user_data = models.UserData.current()

    if page > 0:
        comments_hidden = False  # Never hide questions if specifying specific page
    else:
        page = 1

    limit_per_page = 10
    limit_initially_visible = 2 if comments_hidden else limit_per_page

    comments = util_discussion.get_feedback_by_type_for_video(
        video, models_discussion.FeedbackType.Comment, user_data)
    comments = voting.VotingSortOrder.sort(comments, sort_order=sort_order)

    count_total = len(comments)
    comments = comments[((page - 1) * limit_per_page):(page * limit_per_page)]

    dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
        user_data, video)
    for comment in comments:
        voting.add_vote_expando_properties(comment, dict_votes)

    count_page = len(comments)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
        "is_mod": user_util.is_current_user_moderator(),
        "video": video,
        "topic": topic,
        "comments": comments,
        "count_total": count_total,
        "comments_hidden": count_page > limit_initially_visible,
        "limit_initially_visible": limit_initially_visible,
        "pages": range(1, pages_total + 1),
        "pages_total": pages_total,
        "prev_page_1_based": page - 1,
        "current_page_1_based": page,
        "next_page_1_based": page + 1,
        "show_page_controls": pages_total > 1,
    }
Example #8
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        # Whenever looking at this page, make sure the feedback count is recalculated
        # in case the user was notified about deleted or flagged posts.
        user_data.count_feedback_notification = -1
        user_data.put()

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            if video == None or type(video).__name__ != "Video":
                continue

            video_key = video.key()
            dict_videos[video_key] = video
            
            if dict_answers.has_key(video_key):
                dict_answers[video_key].append(answer)
            else:
                dict_answers[video_key] = [answer]
        
        videos = sorted(dict_videos.values(), key=lambda video: video.first_topic().title + video.title)

        context = {
                    "email": user_data.email,
                    "videos": videos,
                    "dict_answers": dict_answers
                  }

        self.render_jinja2_template('discussion/video_feedback_notification_list.html', context)
Example #9
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            if video == None or type(video).__name__ != "Video":
                continue

            video_key = video.key()
            dict_videos[video_key] = video

            if dict_answers.has_key(video_key):
                dict_answers[video_key].append(answer)
            else:
                dict_answers[video_key] = [answer]

        videos = sorted(dict_videos.values(),
                        key=lambda video: video.playlists[0] + video.title)

        context = {
            "email": user_data.email,
            "videos": videos,
            "dict_answers": dict_answers
        }

        self.render_jinja2_template(
            'discussion/video_feedback_notification_list.html', context)
Example #10
0
def add_feedback(text, feedback_type, parent_key_or_id):
    """Add a question to a video, or an answer to a question.

    Returns a util_discussion.ClientFeedback entity for the added feedback, if
    successful, or None.

    Arguments:
        text: the desired feedback text property
        feedback_type: either FeedbackType.Question or FeedbackType.Answer
        parent_key_or_id: readable_id if adding a question, question_key if
                          adding an answer
    """
    user_data = user_models.UserData.current()
    if not util_discussion.is_post_allowed(user_data, None):
        return None

    if feedback_type == discussion_models.FeedbackType.Question:
        parent = video_models.Video.get_for_readable_id(parent_key_or_id)
    else:
        parent = db.get(parent_key_or_id)

    if parent and text:
        # TODO(drew): see if answers need to be truncated
        # Truncate feedback to a maximum length of 500 characters
        text = text[:500]

        # Grab stats before putting the feedback in case of building stats now
        # and double-counting
        stats = discussion_models.UserDiscussionStats.get_or_build_for(
            user_data)

        feedback = discussion_models.Feedback.insert_feedback(text,
            feedback_type, parent, user_data)

        stats.record(feedback)
        stats.put()

        voting.add_vote_expando_properties(feedback, {})
        return util_discussion.ClientFeedback.from_feedback(feedback,
            with_extra_vote_properties=True)

    return None
Example #11
0
def add_feedback(text, feedback_type, parent_key_or_id):
    """Add a question to a video, or an answer to a question.

    Returns a util_discussion.ClientFeedback entity for the added feedback, if
    successful, or None.

    Arguments:
        text: the desired feedback text property
        feedback_type: either FeedbackType.Question or FeedbackType.Answer
        parent_key_or_id: readable_id if adding a question, question_key if
                          adding an answer
    """
    user_data = user_models.UserData.current()
    if not util_discussion.is_post_allowed(user_data, None):
        return None

    if feedback_type == discussion_models.FeedbackType.Question:
        parent = video_models.Video.get_for_readable_id(parent_key_or_id)
    else:
        parent = db.get(parent_key_or_id)

    if parent and text:
        # TODO(drew): see if answers need to be truncated
        # Truncate feedback to a maximum length of 500 characters
        text = text[:500]

        # Grab stats before putting the feedback in case of building stats now
        # and double-counting
        stats = discussion_models.UserDiscussionStats.get_or_build_for(
            user_data)

        feedback = discussion_models.Feedback.insert_feedback(
            text, feedback_type, parent, user_data)

        stats.record(feedback)
        stats.put()

        voting.add_vote_expando_properties(feedback, {})
        return util_discussion.ClientFeedback.from_feedback(
            feedback, with_extra_vote_properties=True)

    return None
Example #12
0
def video_comments_context(
    video, playlist, page=0, comments_hidden=True, sort_order=voting.VotingSortOrder.HighestPointsFirst
):

    user_data = models.UserData.current()

    if page > 0:
        comments_hidden = False  # Never hide questions if specifying specific page
    else:
        page = 1

    limit_per_page = 10
    limit_initially_visible = 2 if comments_hidden else limit_per_page

    comments = util_discussion.get_feedback_by_type_for_video(video, models_discussion.FeedbackType.Comment, user_data)
    comments = voting.VotingSortOrder.sort(comments, sort_order=sort_order)

    count_total = len(comments)
    comments = comments[((page - 1) * limit_per_page) : (page * limit_per_page)]

    dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)
    for comment in comments:
        voting.add_vote_expando_properties(comment, dict_votes)

    count_page = len(comments)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
        "is_mod": util_discussion.is_current_user_moderator(),
        "video": video,
        "playlist": playlist,
        "comments": comments,
        "count_total": count_total,
        "comments_hidden": count_page > limit_initially_visible,
        "limit_initially_visible": limit_initially_visible,
        "pages": range(1, pages_total + 1),
        "pages_total": pages_total,
        "prev_page_1_based": page - 1,
        "current_page_1_based": page,
        "next_page_1_based": page + 1,
        "show_page_controls": pages_total > 1,
    }
Example #13
0
    def get(self):
        user_data = models.UserData.current()
        question_key = self.request.get("question_key")
        question = db.get(question_key)

        if question:
            video = question.video()
            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)

            answers = models_discussion.Feedback.gql("WHERE types = :1 AND targets = :2 AND deleted = :3 AND is_hidden_by_flags = :4", models_discussion.FeedbackType.Answer, question.key(), False, False).fetch(1000)
            answers = voting.VotingSortOrder.sort(answers)

            for answer in answers:
                voting.add_vote_expando_properties(answer, dict_votes)

            template_values = {
                "answers": answers,
                "is_mod": util_discussion.is_current_user_moderator()
            }

            html = self.render_jinja2_template_to_string('discussion/question_answers_only.html', template_values)
            self.render_json({"html": html})

        return
Example #14
0
File: qa.py Project: hebkhan/server
def video_qa_context(user_data, video, topic=None, page=0, qa_expand_key=None, sort_override=-1):
    limit_per_page = 5

    if page <= 0:
        page = 1

    sort_order = voting.VotingSortOrder.HighestPointsFirst
    if user_data:
        sort_order = user_data.question_sort_order
    if sort_override >= 0:
        sort_order = sort_override

    questions = util_discussion.get_feedback_by_type_for_video(
        video, models_discussion.FeedbackType.Question, user_data
    )
    questions = voting.VotingSortOrder.sort(questions, sort_order=sort_order)

    if qa_expand_key:
        # If we're showing an initially expanded question,
        # make sure we're on the correct page
        question = models_discussion.Feedback.get(qa_expand_key)
        if question:
            count_preceding = 0
            for question_test in questions:
                if question_test.key() == question.key():
                    break
                count_preceding += 1
            page = 1 + (count_preceding / limit_per_page)

    answers = util_discussion.get_feedback_by_type_for_video(video, models_discussion.FeedbackType.Answer, user_data)
    answers.reverse()  # Answers are initially in date descending -- we want ascending before the points sort
    answers = voting.VotingSortOrder.sort(answers)

    dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)

    count_total = len(questions)
    questions = questions[((page - 1) * limit_per_page) : (page * limit_per_page)]

    dict_questions = {}
    # Store each question in this page in a dict for answer population
    for question in questions:
        voting.add_vote_expando_properties(question, dict_votes)
        dict_questions[question.key()] = question

    # Just grab all answers for this video and cache in page's questions
    for answer in answers:
        # Grab the key only for each answer, don't run a full gql query on the ReferenceProperty
        question_key = answer.question_key()
        if dict_questions.has_key(question_key):
            question = dict_questions[question_key]
            voting.add_vote_expando_properties(answer, dict_votes)
            question.children_cache.append(answer)

    count_page = len(questions)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
        "is_mod": user_util.is_current_user_moderator(),
        "video": video,
        "topic": topic,
        "questions": questions,
        "count_total": count_total,
        "pages": range(1, pages_total + 1),
        "pages_total": pages_total,
        "prev_page_1_based": page - 1,
        "current_page_1_based": page,
        "next_page_1_based": page + 1,
        "show_page_controls": pages_total > 1,
        "qa_expand_key": qa_expand_key,
        "sort_order": sort_order,
    }
Example #15
0
def video_qa_context(user_data,
                     video,
                     page=0,
                     qa_expand_key=None,
                     sort_override=-1):
    limit_per_page = 5

    if page <= 0:
        page = 1

    sort_order = voting.VotingSortOrder.HighestPointsFirst
    if user_data:
        sort_order = user_data.question_sort_order
    if sort_override >= 0:
        sort_order = sort_override

    questions = util_discussion.get_feedback_by_type_for_video(
        video, discussion_models.FeedbackType.Question, user_data)
    questions = voting.VotingSortOrder.sort(questions, sort_order=sort_order)

    if qa_expand_key:
        # If we're showing an initially expanded question,
        # make sure we're on the correct page
        question = discussion_models.Feedback.get(qa_expand_key)
        if question:
            count_preceding = 0
            for question_test in questions:
                if question_test.key() == question.key():
                    break
                count_preceding += 1
            page = 1 + (count_preceding / limit_per_page)

    answers = util_discussion.get_feedback_by_type_for_video(
        video, discussion_models.FeedbackType.Answer, user_data)
    answers.reverse(
    )  # Answers are initially in date descending -- we want ascending before the points sort
    answers = voting.VotingSortOrder.sort(answers)

    dict_votes = discussion_models.FeedbackVote.get_dict_for_user_data_and_video(
        user_data, video)

    count_total = len(questions)
    questions = questions[((page - 1) * limit_per_page):(page *
                                                         limit_per_page)]

    dict_questions = {}
    # Store each question in this page in a dict for answer population
    for question in questions:
        voting.add_vote_expando_properties(question, dict_votes)
        dict_questions[question.key()] = question

    # Just grab all answers for this video and cache in page's questions
    for answer in answers:
        # Grab the key only for each answer, don't run a full gql query on the ReferenceProperty
        question_key = answer.question_key()
        if (dict_questions.has_key(question_key)):
            question = dict_questions[question_key]
            voting.add_vote_expando_properties(answer, dict_votes)
            question.children_cache.append(answer)

    count_page = len(questions)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
        "is_mod": user_util.is_current_user_moderator(),
        "video": video,
        "questions": questions,
        "count_total": count_total,
        "pages": range(1, pages_total + 1),
        "pages_total": pages_total,
        "prev_page_1_based": page - 1,
        "current_page_1_based": page,
        "next_page_1_based": page + 1,
        "show_page_controls": pages_total > 1,
        "qa_expand_key": qa_expand_key,
        "sort_order": sort_order,
    }