Пример #1
0
def validate_comment(request, parent_comment=None, replied_comment=None, reply_content=None, category=None):
    """ Return {"success": True} if valid. """
    validate_and_clean_comment(
        request.user,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        reply_content=reply_content,
        category=category,
    )
Пример #2
0
def validate_comment(request, reply_text='', parent_comment=None, replied_comment=None,
                     reply_content=None, category=None, external_content=None):
    """ Return {"success": True} if valid. """
    validate_and_clean_comment(
        request.user,
        reply_text=reply_text,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        reply_content=reply_content,
        category=category,
        external_content=external_content,
    )
Пример #3
0
def post_quest_comment(request, quest_id, content_id, fact_metadata={},
                       facebook_share=False, facebook_access_token=None):
    # Rate-limit?
    if not request.user.is_staff:
        prefix = 'user:{}:post_limit:'.format(request.user.id)
        if not RateLimit(prefix+'h', 60, 60*60).allowed() or not RateLimit(prefix+'d', 100, 8*60*60).allowed():
            raise ServiceError("Attempting to post drawings too quickly.")

    _, parent_comment, content, _, _, _ = validate_and_clean_comment(
        request.user,
        parent_comment=quest_id,
        reply_content=content_id,
    )

    if facebook_share:
        if not facebook_access_token:
            raise ServiceError("Can't share to your timeline if you haven't signed into Facebook yet.")

        associate_facebook_account(request.user, facebook_access_token)

    comment = QuestComment.create_and_post(request, request.user, content, parent_comment,
                                           fact_metadata=fact_metadata)

    if facebook_share:
        complete_quest(request.user, comment, facebook_access_token, request=request)

    return {
        'comment': comment.details(),
        'balance': economy.balance(request.user),
    }
Пример #4
0
def create_quest(request, title, content_id=None, invite_followees=False,
                 facebook_share=False, facebook_access_token=None,
                 twitter_share=False, twitter_access_token=None, twitter_access_token_secret=None,
                 email_share=False, email_recipients=[],
                 resolve_share_ids=[]):
    if not request.user.is_staff and not settings.STAGING:
        prefix = 'user:{}:create_quest_limit:'.format(request.user.id)
        if not RateLimit(prefix+'h', 60, 60*60).allowed() or not RateLimit(prefix+'d', 100, 8*60*60).allowed():
            raise ServiceError("Attempting to create quests too quickly.")

    _, _, content, _, title = validate_and_clean_comment(
        request.user,
        parent_comment=None,
        reply_content=content_id,
        title=title,
    )

    if facebook_share:
        facebook_share = sns_publishing.facebook_share_pre_post(request, facebook_access_token)

    if twitter_share:
        twitter_share = sns_publishing.twitter_share_pre_post(request, twitter_access_token, twitter_access_token_secret)

    quest = Quest.create_and_post(request, request.user, title, content=content, ugq=True)

    models.autocurate_for_flag_words(quest)

    if invite_followees:
        quest.invited_users.invite(request.user, request.user.followers(), ignore_errors=True)

    if facebook_share:
        sns_publishing.facebook_share_post_post(request, facebook_access_token, quest)

    if twitter_share:
        sns_publishing.twitter_share_post_post(request, twitter_access_token, twitter_access_token_secret, quest)

    for share_id in resolve_share_ids:
        share = ShareTrackingUrl.objects.get(id=share_id)

        if share.redirect_url:
            pass #TODO log some error here without failing this request
        
        share.redirect_url = quest.get_share_page_url()
        share.save()

    if email_share:
        @bgwork.defer
        def defer_email_share():
            sns_publishing.share_quest_by_email(quest, request.user, email_recipients)

    @bgwork.defer
    def alert_followers():
        for follower_id in request.user.redis.new_followers.zrange(0, -1):
            RealtimeChannel('user:{}:rt_tab_badges'.format(follower_id), 1).publish({'tab_badge_update': 'draw'})

    return {
        'quest': quest.details(),
    }
Пример #5
0
def post_quest_comment(request, quest_id, content_id, fact_metadata={},
                       facebook_share=False, facebook_access_token=None,
                       twitter_share=False, twitter_access_token=None, twitter_access_token_secret=None,
                       email_share=False, email_recipients=[],
                       resolve_share_ids=[],
                       uuid=None):
    if not request.user.is_staff and not settings.STAGING:
        prefix = 'user:{}:post_limit:'.format(request.user.id)
        if not RateLimit(prefix+'h', 60, 60*60).allowed() or not RateLimit(prefix+'d', 100, 8*60*60).allowed():
            raise ServiceError("Attempting to post drawings too quickly.")

    _, parent_comment, content, _, _ = validate_and_clean_comment(
        request.user,
        parent_comment=quest_id,
        reply_content=content_id,
    )

    if facebook_share:
        facebook_share = sns_publishing.facebook_share_pre_post(request, facebook_access_token)

    if twitter_share:
        twitter_share = sns_publishing.twitter_share_pre_post(request, twitter_access_token, twitter_access_token_secret)

    comment = QuestComment.create_and_post(request, request.user, content, parent_comment,
                                           uuid=uuid, fact_metadata=fact_metadata, debug_content_id=content_id)

    if facebook_share:
        sns_publishing.facebook_share_post_post(request, facebook_access_token, comment)

    if twitter_share:
        sns_publishing.twitter_share_post_post(request, twitter_access_token, twitter_access_token_secret, comment)

    for share_id in resolve_share_ids:
        share = ShareTrackingUrl.objects.get(id=share_id)

        if share.redirect_url:
            pass #TODO log some error here without failing this request

        share.redirect_url = comment.get_share_page_url()
        share.save()

    if email_share:
        @bgwork.defer
        def defer_email_share():
            sns_publishing.share_comment_by_email(comment, request.user, email_recipients)

    return {
        'comment': comment.details(),
        'balance': economy.balance(request.user),
    }
Пример #6
0
def post_comment(request, user, post_data, persist_url=True):
    reply_text = post_data.get('reply_text', '')

    try:
        replied_comment, parent_comment, reply_content, external_content, category, title = (
            validate_and_clean_comment(
                user,
                reply_text=reply_text,
                parent_comment=post_data.get('parent_comment'),
                replied_comment=post_data.get('replied_comment'),
                reply_content=post_data.get('reply_content'),
                category=post_data.get('category'),
                external_content=post_data.get('external_content'),
                title=post_data.get('title'),
            ))

        post_anon = True
        if category and category == MONSTER_GROUP:
            post_anon = False

        comment = Comment.create_and_post(
            request,
            user,
            post_anon,  # Anonymous.
            category,
            reply_content,
            parent_comment=parent_comment,
            reply_text=reply_text,
            replied_comment=replied_comment,
            external_content=external_content,
            title=title,
        )

        post_pending_url = comment.details().url

        if persist_url:
            if category and category.name == MONSTER_GROUP:
                post_pending_url = '/monster/{0}'.format(
                    base36encode(comment.thread.op.id))
            user.kv.post_pending_signup_url.set(post_pending_url)

        return comment

    except ServiceError, e:
        # Silently drop the post if an error occurs.
        # We tried validating it prior to posting, but something went wrong between then and now
        # and it no longer validates. Should be rare.
        Metrics.logged_out_reply_dropped.record(request,
                                                extra_info=extra_info,
                                                service_error=e)
Пример #7
0
def post_quest_comment(request,
                       quest_id,
                       content_id,
                       fact_metadata={},
                       facebook_share=False,
                       facebook_access_token=None):
    # Rate-limit?
    if not request.user.is_staff:
        prefix = 'user:{}:post_limit:'.format(request.user.id)
        if not RateLimit(prefix + 'h', 60, 60 * 60).allowed() or not RateLimit(
                prefix + 'd', 100, 8 * 60 * 60).allowed():
            raise ServiceError("Attempting to post drawings too quickly.")

    _, parent_comment, content, _, _, _ = validate_and_clean_comment(
        request.user,
        parent_comment=quest_id,
        reply_content=content_id,
    )

    if facebook_share:
        if not facebook_access_token:
            raise ServiceError(
                "Can't share to your timeline if you haven't signed into Facebook yet."
            )

        associate_facebook_account(request.user, facebook_access_token)

    comment = QuestComment.create_and_post(request,
                                           request.user,
                                           content,
                                           parent_comment,
                                           fact_metadata=fact_metadata)

    if facebook_share:
        complete_quest(request.user,
                       comment,
                       facebook_access_token,
                       request=request)

    return {
        'comment': comment.details(),
        'balance': economy.balance(request.user),
    }
Пример #8
0
def post_comment(request, user, post_data, persist_url=True):
    try:
        replied_comment, parent_comment, reply_content, category, title = (
            validate_and_clean_comment(
                user,
                parent_comment=post_data.get('parent_comment'),
                replied_comment=post_data.get('replied_comment'),
                reply_content=post_data.get('reply_content'),
                category=post_data.get('category'),
                title=post_data.get('title'),
            )
        )

        post_anon = True
        if category and category == MONSTER_GROUP:
            post_anon = False

        comment = Comment.create_and_post(
            request,
            user,
            post_anon, # Anonymous.
            category,
            reply_content,
            parent_comment=parent_comment,
            replied_comment=replied_comment,
            title=title,
        )

        post_pending_url = comment.details().url

        if persist_url:
            if category and category.name == MONSTER_GROUP:
                post_pending_url = '/monster/{0}'.format(base36encode(comment.thread.op.id))
            user.kv.post_pending_signup_url.set(post_pending_url)

        return comment

    except ServiceError, e:
        # Silently drop the post if an error occurs.
        # We tried validating it prior to posting, but something went wrong between then and now
        # and it no longer validates. Should be rare.
        Metrics.logged_out_reply_dropped.record(request, extra_info=extra_info, service_error=e)
Пример #9
0
def post_quest_idea(request, title, content, name, email):
    user = User.objects.get(username=settings.QUEST_IDEAS_USERNAME)

    text = "Name: {}\n\nEmail: {}".format(name, email)

    replied_comment, parent_comment, reply_content, category, title = validate_and_clean_comment(
        user,
        reply_content=content,
        title=title,
    )

    comment = Comment.create_and_post(
        request,
        user,
        False,
        category,
        reply_content,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        fact_metadata={},
        title=title,
    )

    return {'comment': comment.details()}
Пример #10
0
def post_quest_idea(request, title, content, name, email):
    user = User.objects.get(username=settings.QUEST_IDEAS_USERNAME)

    text = "Name: {}\n\nEmail: {}".format(name, email)

    replied_comment, parent_comment, reply_content, category, title = validate_and_clean_comment(
        user,
        reply_content=content,
        title=title,
    )

    comment = Comment.create_and_post(
        request,
        user,
        False,
        category,
        reply_content,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        fact_metadata={},
        title=title,
    )

    return {'comment': comment.details()}
Пример #11
0
def post_comment(
    request,
    anonymous=False,
    parent_comment=None,
    replied_comment=None,
    reply_content=None,
    category=None,
    fact_metadata={},
    title=None,
    tags=[],
):
    anonymous = bool(anonymous)

    # Remember the user's preference for anonymous posting.
    request.user.userinfo.post_anonymously = anonymous
    request.user.userinfo.save()

    replied_comment, parent_comment, reply_content, category, title = validate_and_clean_comment(
        request.user,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        reply_content=reply_content,
        category=category,
        title=title,
    )

    comment = models.Comment.create_and_post(
        request,
        request.user,
        anonymous,
        category,
        reply_content,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        fact_metadata=fact_metadata,
        title=title,
        tags=tags,
    )

    if parent_comment is None:
        key = "posted_unvisited_threads"
        val = request.session.get(key, set())
        val.add(comment.id)
        request.session[key] = val

    @bgwork.defer
    def create_footer():
        if comment.footer.should_exist():
            comment.footer.call_update_in_new_process()

    @bgwork.defer
    def credit_original_author():
        if (
            not comment.reply_content
            or not comment.reply_content.is_remix()
            or not comment.reply_content.remix_of.first_caption
        ):
            return
        original_author = comment.reply_content.remix_of.first_caption.author
        if original_author != comment.author:
            economy.credit_received_remix(original_author)

    @bgwork.defer
    def do_notify():
        Actions.replied(request.user, comment)

    return {"comment": comment.details()}
Пример #12
0
def create_quest(request,
                 title,
                 content_id=None,
                 invite_followees=False,
                 facebook_share=False,
                 facebook_access_token=None,
                 twitter_share=False,
                 twitter_access_token=None,
                 twitter_access_token_secret=None,
                 email_share=False,
                 email_recipients=[],
                 resolve_share_ids=[]):
    if not request.user.is_staff and not settings.STAGING:
        prefix = 'user:{}:create_quest_limit:'.format(request.user.id)
        if not RateLimit(prefix + 'h', 60, 60 * 60).allowed() or not RateLimit(
                prefix + 'd', 100, 8 * 60 * 60).allowed():
            raise ServiceError("Attempting to create quests too quickly.")

    _, _, content, _, title = validate_and_clean_comment(
        request.user,
        parent_comment=None,
        reply_content=content_id,
        title=title,
    )

    if facebook_share:
        facebook_share = sns_publishing.facebook_share_pre_post(
            request, facebook_access_token)

    if twitter_share:
        twitter_share = sns_publishing.twitter_share_pre_post(
            request, twitter_access_token, twitter_access_token_secret)

    quest = Quest.create_and_post(request,
                                  request.user,
                                  title,
                                  content=content,
                                  ugq=True)

    models.autocurate_for_flag_words(quest)

    if invite_followees:
        quest.invited_users.invite(request.user,
                                   request.user.followers(),
                                   ignore_errors=True)

    if facebook_share:
        sns_publishing.facebook_share_post_post(request, facebook_access_token,
                                                quest)

    if twitter_share:
        sns_publishing.twitter_share_post_post(request, twitter_access_token,
                                               twitter_access_token_secret,
                                               quest)

    for share_id in resolve_share_ids:
        share = ShareTrackingUrl.objects.get(id=share_id)

        if share.redirect_url:
            pass  #TODO log some error here without failing this request

        share.redirect_url = quest.get_share_page_url()
        share.save()

    if email_share:

        @bgwork.defer
        def defer_email_share():
            sns_publishing.share_quest_by_email(quest, request.user,
                                                email_recipients)

    @bgwork.defer
    def alert_followers():
        for follower_id in request.user.redis.new_followers.zrange(0, -1):
            RealtimeChannel('user:{}:rt_tab_badges'.format(follower_id),
                            1).publish({'tab_badge_update': 'draw'})

    return {
        'quest': quest.details(),
    }
Пример #13
0
def post_comment(request, anonymous=False, reply_text='', parent_comment=None, replied_comment=None,
                 reply_content=None, category=None, external_content=None, fact_metadata={},
                 title=None, tags=[]):
    anonymous = bool(anonymous)

    # Remember the user's preference for anonymous posting.
    request.user.userinfo.post_anonymously = anonymous
    request.user.userinfo.save()

    replied_comment, parent_comment, reply_content, external_content, category, title = validate_and_clean_comment(
        request.user,
        reply_text=reply_text,
        parent_comment=parent_comment,
        replied_comment=replied_comment,
        reply_content=reply_content,
        category=category,
        external_content=external_content,
        title=title,
    )

    comment = models.Comment.create_and_post(
        request,
        request.user,
        anonymous,
        category,
        reply_content,
        parent_comment=parent_comment,
        reply_text=reply_text,
        replied_comment=replied_comment,
        external_content=external_content,
        fact_metadata=fact_metadata,
        title=title,
        tags=tags,
    )

    if parent_comment is None:
        key = 'posted_unvisited_threads'
        val = request.session.get(key, set())
        val.add(comment.id)
        request.session[key] = val

    @bgwork.defer
    def create_footer():
        if comment.footer.should_exist():
            comment.footer.call_update_in_new_process()

    @bgwork.defer
    def credit_original_author():
        if not comment.reply_content or not comment.reply_content.is_remix() or not comment.reply_content.remix_of.first_caption:
            return
        original_author = comment.reply_content.remix_of.first_caption.author
        if original_author != comment.author:
            economy.credit_received_remix(original_author)

    @bgwork.defer
    def do_notify():
        Actions.replied(request.user, comment)

    @bgwork.defer
    def monster_achievement():
        if comment.is_monster_top():
            request.user.kv.achievements.achieve('monster_top')
        elif comment.is_monster_bottom():
            request.user.kv.achievements.achieve('monster_bottom')

    return {'comment': comment.details()}