Esempio n. 1
0
def get_replies(request, comment_id=0, replies_after_timestamp=0.):
    from apps.features import feature_flags as features

    op_id = int(comment_id)
    # Fudge the timestamp a bit to err on the side of too many replies which we'll dedupe, instead of clicking the
    # button and having nothing happening.
    fudge = 5
    replies_after_timestamp = float(replies_after_timestamp) - fudge

    op = get_object_or_404(models.Comment, id=op_id)
    replies = [
        r.details()
        for r in op.replies.filter(models.Visibility.q_visible).filter(
            timestamp__gt=replies_after_timestamp).order_by('timestamp')
    ]

    Metrics.get_new_replies.record(
        request, op=op_id, replies_after_timestamp=replies_after_timestamp)

    if features.thread_new(request):
        from apps.threads.jinja_tags import thread_new_comment
        html = u''.join(
            thread_new_comment(
                {'request': request}, reply, ignore_lazy_load=True)
            for reply in replies)
        return {'replies': replies, 'html': html}

    return {'replies': replies}
Esempio n. 2
0
def get_replies(request, comment_id=0, replies_after_timestamp=0.0):
    from apps.features import feature_flags as features

    op_id = int(comment_id)
    # Fudge the timestamp a bit to err on the side of too many replies which we'll dedupe, instead of clicking the
    # button and having nothing happening.
    fudge = 5
    replies_after_timestamp = float(replies_after_timestamp) - fudge

    op = get_object_or_404(models.Comment, id=op_id)
    replies = [
        r.details()
        for r in op.replies.filter(models.Visibility.q_visible)
        .filter(timestamp__gt=replies_after_timestamp)
        .order_by("timestamp")
    ]

    Metrics.get_new_replies.record(request, op=op_id, replies_after_timestamp=replies_after_timestamp)

    if features.thread_new(request):
        from apps.threads.jinja_tags import thread_new_comment

        html = u"".join(thread_new_comment({"request": request}, reply, ignore_lazy_load=True) for reply in replies)
        return {"replies": replies, "html": html}

    return {"replies": replies}
Esempio n. 3
0
def thread(request, short_id, page=None, gotoreply=None, sort_by_top=False,
           template_name='comment/new_base_thread.django.html'):
    from apps.monster.models import MONSTER_GROUP

    if not request.user.is_authenticated() and template_name == 'comment/new_base_thread.django.html' and not features.thread_new(request):
        return logged_out_thread_view(request, short_id, page=page, gotoreply=gotoreply)

    view_data = CommentViewData(request, short_id, page=page, gotoreply=gotoreply)

    if '/p/' + short_id == request.user.kv.post_pending_signup_url.get():
        request.user.kv.post_pending_signup_url.delete()

    ctx = view_data.thread_context()

    ctx['request'] = request

    # monstermash posts redirect to monstermash app
    if ctx['op_comment'].category == MONSTER_GROUP and not ctx['viewer_is_staff']:
        return HttpResponseRedirect('/monster/{0}'.format(ctx['op_comment'].short_id()))

    # all hidden group posts are invisible to normal users
    if ctx['op_comment'].category in settings.HIDDEN_GROUPS and not ctx['viewer_is_staff']:
        return Http404()

    # If we hit the size threshold, record metric that the user is viewing a large thread
    if ctx['large_thread_view']:
        Metrics.large_thread_view.record(request)

    ctx['remix_invite_share_view'] = 'rmi' in request.GET
    if ctx['remix_invite_share_view']:
        ctx['fb_metadata']['title'] = "Come Remix With Me!"
        if ctx['op_comment'].title:
            ctx['fb_metadata']['description'] = """I just started a thread on Canvas, "{0}". Click the link to add your remix to the thread!""".format(op_comment.title)
        else:
            ctx['fb_metadata']['description'] = "I just started a thread on Canvas. Click the link to add your remix to the thread!"

    # Inviting experiment
    ctx['is_in_invite_remixers_v2'] = False

    ctx.update({
        'request': request,
        'sort_by_top': sort_by_top,
    })

    if request.is_mobile:
        return r2r_jinja("mobile/thread.html", ctx)

    if features.thread_new(request):
        ctx['has_top_remixes'] = bool(len(ctx['top_remixes']))
        if sort_by_top:
            ctx['replies'] = ctx['top_remixes']
            ctx['has_top_remixes'] = True

        return r2r_jinja('threads_new/thread.html', ctx, request)

    return r2r(template_name, ctx)
    def thread_context(self):
        top_reply_ids = self.top_reply_ids(force_show=features.thread_new(self.request))

        ctx = {
            'short_id': self.short_id,
            'page': self.page,
            'gotoreply': self.gotoreply,

            'viewer_is_staff': self.request.user.is_authenticated() and self.request.user.is_staff,
            'viewer_is_thread_author': self.is_author,
            'root': '/p/',

            'op_content': self.op_content,
            'op_category': self.op_category,
            'page': self.page,
            'per_page': self.per_page,
            'num_replies': self.num_replies,
            'reply_ids': self.reply_ids,
            'pages': self.pages,
            'page_reply_ids': self.page_reply_ids,
            'page_current': self.page_current,
            'page_next': self.page_next,
            'page_last': self.page_last,
            'page_penultimate': self.page_penultimate,
            'explicit_page_view': self.explicit_page_view,

            # Recent replies.
            'recent_reply_ids': self.recent_reply_ids,

            'top_reply_ids': top_reply_ids,
        }

        # Get all the replies in one query, then create the appropriate lists.
        _all_replies = Comment.visible.in_bulk(self.page_reply_ids + self.recent_reply_ids + top_reply_ids)
        _recent_replies = [_all_replies[cid] for cid in self.recent_reply_ids]
        _top_replies = filter(bool, [_all_replies.get(cid) for cid in top_reply_ids])
        _replies = [_all_replies[cid] for cid in self.page_reply_ids]

        replyable = [self._op_comment] + _replies + _recent_replies + _top_replies

        # Get all comment ids (ids so 0 queries) that any of these comments are replies to, that aren't in this
        # page, so we can render them on hover.
        replied_ids = ([reply.replied_comment_id for reply in replyable
                        if (reply.replied_comment_id
                            and reply.replied_comment_id not in [r.id for r in replyable])])

        ctx.update({
            'replied_ids': replied_ids,
            'replyable': replyable,
        })

        recent_replies = [reply.details for reply in _recent_replies]
        replies = [Comment.details_by_id(reply.id) for reply in _replies]
        replied = [Comment.details_by_id(cid) for cid in replied_ids]
        top_replies = [reply.details for reply in _top_replies]

        if self.request.user.is_authenticated():
            ctx['user_infos'] = {'pinned': self.request.user.id in self._op_comment.pins()}
            if self.request.user.is_staff:
                ctx['admin_infos'] = {self._op_comment.id: self._op_comment.admin_info}
                # For replies we only use the username, so grab those all in one query and put them in admin_infos.
                ctx['usernames'] = Comment.visible.filter(id__in=_all_replies.keys()).values('id', 'author__username')
                for reply_dict in ctx['usernames']:
                    ctx['admin_infos'][reply_dict['id']] = {'username': reply_dict['author__username']}

        ctx['replies_channel'] = self._op_comment.replies_channel.sync()

        # Get relevant sidebar data
        remix_of, reply_to = [], []
        # Remix of
        if self._op_content and self._op_content.remix_of:
            op_remix_of_caption = self._op_content.remix_of.first_caption
            if op_remix_of_caption:
                remix_of = [op_remix_of_caption.details]
            ctx['op_remix_of_caption'] = op_remix_of_caption
        # Reply to
        if self._op_comment.parent_comment and self._op_comment.parent_comment.is_visible():
            reply_to = [self._op_comment.parent_comment.details]

        (
            (op_comment,),
            (linked_comment,),
            remix_of,
            reply_to,
            replies,
            recent_replies,
            top_replies,
            replied,
        ) = CachedCall.many_multicall(
            [self.op_comment],
            [self.linked_comment],
            remix_of,
            reply_to,
            replies,
            recent_replies,
            top_replies,
            replied,
        )

        op_comment.is_my_post = bool(self._op_comment.author == self.request.user)
        op_comment.moderated = op_comment.visibility not in Visibility.public_choices

        linked_comment = TemplateComment(linked_comment, is_op=(linked_comment.id == op_comment.id),
                                        request=self.request, title=op_comment.title)

        if self.page_current == 1 and op_comment.has_content():
            first_comment_with_content = op_comment
        else:
            first_comment_with_content = None
            for reply in replies:
                if reply.has_content():
                    first_comment_with_content = reply
                    break

        last_comment_with_content = None
        for reply in reversed(replies):
            if reply.has_content():
                last_comment_with_content = reply
                break

        comment_to_expand = first_comment_with_content
        if self.gotoreply:
            comment_to_expand = linked_comment

        ctx.update({
            'op_comment': op_comment,
            'linked_comment': linked_comment,
            'remix_of': remix_of,
            'reply_to': reply_to,
            'replies': replies,
            'recent_replies': recent_replies,
            'top_replies': top_replies,
            'top_remixes': [reply for reply in top_replies if reply.has_content()],
            'replied': replied,

            'linked_comment': linked_comment,
            'large_thread_view': len(replies) >= 50,
            'title': getattr(op_comment, 'title', None),

            'first_comment_with_content': first_comment_with_content,
            'last_comment_with_content': last_comment_with_content,
            'comment_to_expand': comment_to_expand,
        })

        return ctx