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}
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}
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