Esempio n. 1
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
Esempio n. 2
0
    def post(self):
        user_data = user_models.UserData.current()

        key = self.request.get("entity_key")
        text = self.request.get("question_text") or self.request.get(
            "answer_text")

        if key and text:
            feedback = db.get(key)
            if feedback:
                if feedback.authored_by(
                        user_data) or user_util.is_current_user_moderator():

                    feedback.content = text
                    feedback.put()

                    # Redirect to appropriate list of entities depending on type of
                    # feedback entity being edited.
                    if feedback.is_type(
                            discussion_models.FeedbackType.Question):

                        page = self.request.get("page")
                        video = feedback.video()
                        self.redirect(
                            "/discussion/pagequestions?video_key=%s&page=%s&qa_expand_key=%s"
                            % (video.key(), page, feedback.key()))

                    elif feedback.is_type(
                            discussion_models.FeedbackType.Answer):

                        question = feedback.question()
                        self.redirect("/discussion/answers?question_key=%s" %
                                      question.key())
Esempio n. 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
Esempio n. 4
0
File: qa.py Progetto: hebkhan/server
    def post(self):
        user_data = models.UserData.current()
        if not user_data:
            return

        key = self.request.get("entity_key")
        topic_key = self.request.get("topic_key")
        text = self.request.get("question_text") or self.request.get("answer_text")

        if key and text:
            feedback = db.get(key)
            if feedback:
                if feedback.authored_by(user_data) or user_util.is_current_user_moderator():

                    feedback.content = text
                    feedback.put()

                    # Redirect to appropriate list of entities depending on type of
                    # feedback entity being edited.
                    if feedback.is_type(models_discussion.FeedbackType.Question):

                        page = self.request.get("page")
                        video = feedback.video()
                        self.redirect(
                            "/discussion/pagequestions?video_key=%s&topic_key=%s&page=%s&qa_expand_key=%s"
                            % (video.key(), topic_key, page, feedback.key())
                        )

                    elif feedback.is_type(models_discussion.FeedbackType.Answer):

                        question = feedback.question()
                        self.redirect("/discussion/answers?question_key=%s" % question.key())
Esempio n. 5
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
Esempio n. 6
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
Esempio n. 7
0
    def post(self):
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        if key:
            entity = db.get(key)
            if entity:
                entity.clear_flags()
                entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 8
0
File: qa.py Progetto: hebkhan/server
    def post(self):
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        if key:
            entity = db.get(key)
            if entity:
                entity.clear_flags()
                entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 9
0
    def post(self):
        # Must be a moderator to change types of anything
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        target_type = self.request.get("target_type")

        if key:
            entity = db.get(key)
            if entity:
                clear_flags = self.request_bool("clear_flags", default=False)
                entity.change_type(target_type, clear_flags)

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 10
0
    def post(self):
        # Must be a moderator to change types of anything
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        target_type = self.request.get("target_type")

        if key:
            entity = db.get(key)
            if entity:
                clear_flags = self.request_bool("clear_flags", default=False)
                entity.change_type(target_type, clear_flags)

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 11
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,
    }
Esempio n. 12
0
File: qa.py Progetto: hebkhan/server
    def post(self):
        # Must be a moderator to change types of anything
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        target_type = self.request.get("target_type")
        if key and models_discussion.FeedbackType.is_valid(target_type):
            entity = db.get(key)
            if entity:
                entity.types = [target_type]

                if self.request_bool("clear_flags", default=False):
                    entity.clear_flags()

                entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 13
0
    def post(self):
        # Must be a moderator to change types of anything
        if not user_util.is_current_user_moderator():
            return

        key = self.request.get("entity_key")
        target_type = self.request.get("target_type")
        if key and models_discussion.FeedbackType.is_valid(target_type):
            entity = db.get(key)
            if entity:
                entity.types = [target_type]

                if self.request_bool("clear_flags", default=False):
                    entity.clear_flags()

                entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 14
0
File: qa.py Progetto: hebkhan/server
    def post(self):
        user_data = models.UserData.current()
        if not user_data:
            return

        key = self.request.get("entity_key")
        if key:
            entity = db.get(key)
            if entity:
                # Must be a moderator or author of entity to delete
                if entity.authored_by(user_data):
                    # Entity authors can completely delete their posts.
                    # Posts that are flagged as deleted by moderators won't show up
                    # as deleted to authors, so we just completely delete in this special case.
                    entity.delete()
                elif user_util.is_current_user_moderator():
                    entity.deleted = True
                    entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 15
0
    def post(self):
        user_data = user_models.UserData.current()
        if not user_data:
            return

        key = self.request.get("entity_key")
        if key:
            entity = db.get(key)
            if entity:
                # Must be a moderator or author of entity to delete
                if entity.authored_by(user_data):
                    # Entity authors can completely delete their posts.
                    # Posts that are flagged as deleted by moderators won't show up
                    # as deleted to authors, so we just completely delete in this special case.
                    entity.delete()
                elif user_util.is_current_user_moderator():
                    entity.deleted = True
                    entity.put()

        self.redirect("/discussion/flaggedfeedback")
Esempio n. 16
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,
           }
Esempio n. 17
0
def hide_feedback(feedback_key):
    """Hide the specified feedback entity from the general public.

    If initiated by the entity author, the entity is deleted from the
    datastore.
    If initiated by a moderator, the entity is marked as deleted and thus
    hidden from the general public but not from the author.
    """
    if not feedback_key:
        return

    feedback = db.get(feedback_key)

    if not feedback:
        return

    user_data = user_models.UserData.current()
    client_feedback = None

    stats = discussion_models.UserDiscussionStats.get_or_build_for(
        feedback.get_author())
    stats.forget(feedback)

    if feedback.authored_by(user_data):
        stats.put()
        # Entity authors can completely delete their posts. Posts that are
        # flagged as deleted by moderators won't show up as deleted to
        # authors, so we just completely delete in this special case.
        feedback.delete()
    elif user_util.is_current_user_moderator():
        feedback.deleted = True
        stats.record(feedback)
        stats.put()
        feedback.put()  # Feedback put does extra stuff so don't multi-put
        client_feedback = util_discussion.ClientFeedback.from_feedback(
            feedback)

    return client_feedback
Esempio n. 18
0
def hide_feedback(feedback_key):
    """Hide the specified feedback entity from the general public.

    If initiated by the entity author, the entity is deleted from the
    datastore.
    If initiated by a moderator, the entity is marked as deleted and thus
    hidden from the general public but not from the author.
    """
    if not feedback_key:
        return

    feedback = db.get(feedback_key)

    if not feedback:
        return

    user_data = user_models.UserData.current()
    client_feedback = None

    stats = discussion_models.UserDiscussionStats.get_or_build_for(
        feedback.get_author())
    stats.forget(feedback)

    if feedback.authored_by(user_data):
        stats.put()
        # Entity authors can completely delete their posts. Posts that are
        # flagged as deleted by moderators won't show up as deleted to
        # authors, so we just completely delete in this special case.
        feedback.delete()
    elif user_util.is_current_user_moderator():
        feedback.deleted = True
        stats.record(feedback)
        stats.put()
        feedback.put()  # Feedback put does extra stuff so don't multi-put
        client_feedback = util_discussion.ClientFeedback.from_feedback(
            feedback)

    return client_feedback
Esempio n. 19
0
File: qa.py Progetto: 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,
    }
Esempio n. 20
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,
    }