def test_no_change_to_comment_publicity(self): """ Assert that no change made to the `is_public` or `is_removed` properties of a comment result in no changes to the comment count or last comment keys of the content object. """ # Create a new public comment on the publishable comment = self._create_comment() tools.assert_equals(comments.get_model()._default_manager.count(), 1) tools.assert_equals(comments.get_model()._default_manager.filter(is_public=True, is_removed=False).count(), 1) # Assert that the comment count key on the publishable was set correctly to 1 tools.assert_equals( int(client.get(self._build_publishable_comment_count_key(self.publishable))), 1 ) # Update this comment (but do not change "publicity") and assert that # nothing has changed regarding the comment count on the publishable comment.comment = 'New comment text' tools.assert_true(comment.is_public) tools.assert_false(comment.is_removed) comment.save() # Assert that the comment count key on the publishable is still set correctly to 1 tools.assert_equals( int(client.get(self._build_publishable_comment_count_key(self.publishable))), 1 )
def comment_post_save(instance, **kwargs): if hasattr(instance, '__pub_info'): is_public = instance.is_public and not instance.is_removed was_public = instance.__pub_info['is_public'] and not instance.__pub_info['is_removed'] # comment being moderated if was_public and not is_public: count_key = COMCOUNT_KEY % (instance.content_type_id, instance.object_pk) client.decr(count_key) # commet back up elif not was_public and is_public: count_key = COMCOUNT_KEY % (instance.content_type_id, instance.object_pk) client.incr(count_key) else: # no change return last_keu = LASTCOM_KEY % (instance.content_type_id, instance.object_pk) try: # update the last comment info last_com = comments.get_model()._default_manager.filter(content_type_id=instance.content_type_id, object_pk=instance.object_pk, is_public=True, is_removed=False).latest('submit_date') client.hmset(last_keu, { 'submit_date': repr(time.mktime(last_com.submit_date.timetuple())), 'user_id': last_com.user_id or '', 'username': last_com.user.username if last_com.user_id else last_com.user_name, }) except comments.get_model().DoesNotExist: client.delete(last_keu) # update the listing handlers obj = instance.content_object if isinstance(obj, Publishable) and obj.is_published(): publishable_published(obj)
def get_comment_object(self): """ Return a new (unsaved) comment object based on the information in this form. Assumes that the form is already validated and will throw a ValueError if not. Does not set any of the fields that would come from a Request object (i.e. ``user`` or ``ip_address``). """ if not self.is_valid(): raise ValueError("get_comment_object may only be called on valid forms") parent_comment = None parent_pk = self.cleaned_data.get("parent_pk") if parent_pk: parent_comment = get_model().objects.get(pk=parent_pk) new = get_model()( content_type = ContentType.objects.get_for_model(self.target_object), object_pk = force_unicode(self.target_object._get_pk_val()), user_name = "", # self.cleaned_data["name"], user_email = "", # self.cleaned_data["email"], user_url = "", # self.cleaned_data["url"], comment = self.cleaned_data["comment"], submit_date = datetime.datetime.now(), site_id = settings.SITE_ID, is_public = parent_comment and parent_comment.is_public or True, is_removed = False, title = self.cleaned_data["title"], parent = parent_comment ) # FIXME: maybe re-implement duplicate checking later return new
def _lookup_content_object(data): # Look up the object we're trying to comment about ctype = data.get("content_type") object_pk = data.get("object_pk") parent_pk = data.get("parent_pk") if parent_pk: try: parent_comment = get_model().objects.get(pk=parent_pk) target = parent_comment.content_object model = target.__class__ except get_model().DoesNotExist: return CommentPostBadRequest( "Parent comment with PK %r does not exist." % \ escape(parent_pk)) elif ctype and object_pk: try: parent_comment = None model = models.get_model(*ctype.split(".", 1)) target = model._default_manager.get(pk=object_pk) except TypeError: return CommentPostBadRequest( "Invalid content_type value: %r" % escape(ctype)) except AttributeError: return CommentPostBadRequest( "The given content-type %r does not resolve to a valid model." % \ escape(ctype)) except ObjectDoesNotExist: return CommentPostBadRequest( "No object matching content-type %r and object PK %r exists." % \ (escape(ctype), escape(object_pk))) else: return CommentPostBadRequest("Missing content_type or object_pk field.") return (target, parent_comment, model)
def test_do_email_reply(self): comment = comments.get_model().objects.create( comment='My Comment 1', user=self.author, is_public=True, content_object=self.entry, site=self.site) moderator = EntryCommentModerator(Entry) moderator.email_notification_reply = True moderator.mail_comment_notification_recipients = [ u'*****@*****.**', u'*****@*****.**'] moderator.do_email_reply(comment, self.entry, 'request') self.assertEquals(len(mail.outbox), 0) comment = comments.get_model().objects.create( comment='My Comment 2', user_email='*****@*****.**', content_object=self.entry, is_public=True, site=self.site) moderator.do_email_reply(comment, self.entry, 'request') self.assertEquals(len(mail.outbox), 0) comment = comments.get_model().objects.create( comment='My Comment 3', user_email='*****@*****.**', content_object=self.entry, is_public=True, site=self.site) moderator.do_email_reply(comment, self.entry, 'request') self.assertEquals(len(mail.outbox), 1) self.assertEquals(mail.outbox[0].bcc, [u'*****@*****.**']) comment = comments.get_model().objects.create( comment='My Comment 4', user=self.author, is_public=True, content_object=self.entry, site=self.site) moderator.do_email_reply(comment, self.entry, 'request') self.assertEquals(len(mail.outbox), 2) self.assertEquals(mail.outbox[1].bcc, [u'*****@*****.**', u'*****@*****.**'])
def test_get_recent_comments(self): site = Site.objects.get_current() context = get_recent_comments() self.assertEquals(len(context['comments']), 0) self.assertEquals(context['template'], 'zinnia/tags/recent_comments.html') comment_1 = comments.get_model().objects.create( comment='My Comment 1', site=site, content_object=self.entry) context = get_recent_comments(3, 'custom_template.html') self.assertEquals(len(context['comments']), 0) self.assertEquals(context['template'], 'custom_template.html') self.publish_entry() context = get_recent_comments() self.assertEquals(len(context['comments']), 1) author = User.objects.create_user(username='******', email='*****@*****.**') comment_2 = comments.get_model().objects.create( comment='My Comment 2', site=site, content_object=self.entry) comment_2.flags.create(user=author, flag=CommentFlag.MODERATOR_APPROVAL) context = get_recent_comments() self.assertEquals(list(context['comments']), [comment_2, comment_1])
def test_get_recent_linkbacks(self): user = User.objects.create_user(username='******', email='*****@*****.**') site = Site.objects.get_current() context = get_recent_linkbacks() self.assertEquals(len(context['linkbacks']), 0) self.assertEquals(context['template'], 'zinnia/tags/recent_linkbacks.html') linkback_1 = comments.get_model().objects.create( comment='My Linkback 1', site=site, content_object=self.entry) linkback_1.flags.create(user=user, flag=PINGBACK) context = get_recent_linkbacks(3, 'custom_template.html') self.assertEquals(len(context['linkbacks']), 0) self.assertEquals(context['template'], 'custom_template.html') self.publish_entry() context = get_recent_linkbacks() self.assertEquals(len(context['linkbacks']), 1) linkback_2 = comments.get_model().objects.create( comment='My Linkback 2', site=site, content_object=self.entry) linkback_2.flags.create(user=user, flag=TRACKBACK) context = get_recent_linkbacks() self.assertEquals(list(context['linkbacks']), [linkback_2, linkback_1])
def test_modify_comment_publicity(self): """ Assert that a modification made to the `is_public` or `is_removed` properties of a comment result in changes to the comment count of the content object. """ # Create a new public comment on the publishable comment = self._create_comment() tools.assert_equals(comments.get_model()._default_manager.count(), 1) tools.assert_equals(comments.get_model()._default_manager.filter(is_public=True, is_removed=False).count(), 1) # Assert that the comment count key on the publishable was set correctly to 1 tools.assert_equals( int(client.get(self._build_publishable_comment_count_key(self.publishable))), 1 ) # Update this comment (and change "publicity" of it) comment.is_public = False comment.save() # Assert that the comment count key on the publishable has been updated to reflect # the fact that there are 0 public comments associated to it. tools.assert_equals( int(client.get(self._build_publishable_comment_count_key(self.publishable))), 0 )
def test_post_works_for_correct_data_with_parent(self): c = create_comment(self.publishable, self.publishable.content_type) form = comments.get_form()(target_object=self.publishable, parent=c.pk) response = self.client.post(self.get_url('new'), self.get_form_data(form)) self.assert_equals(302, response.status_code) self.assert_equals(2, comments.get_model().objects.count()) child = comments.get_model().objects.exclude(pk=c.pk)[0] self.assert_equals(c, child.parent)
def test_get_comment_for_user(self): boy = User.objects.create(username='******') girl = User.objects.create(username='******') first = create_comment(self.publishable, self.publishable.content_type, comment='first', user=boy) second = create_comment(self.publishable, self.publishable.content_type, comment='second', user=girl) tools.assert_equals(first, views.update_comment.get_comment_for_user(self.publishable, boy, first.pk)) tools.assert_raises(comments.get_model().DoesNotExist, lambda: views.update_comment.get_comment_for_user(self.publishable, boy, 1024)) tools.assert_raises(comments.get_model().DoesNotExist, lambda: views.update_comment.get_comment_for_user(self.publishable, boy, second.pk))
def connect(self): """ Hook up the moderation methods to pre- and post-save signals from the comment models. """ signals.comment_will_be_posted.connect(self.pre_save_moderation, sender=comments.get_model()) signals.comment_was_posted.connect(self.post_save_moderation, sender=comments.get_model())
def connect_signals(): from django.contrib.comments.signals import comment_was_posted from ella.core.signals import content_published, content_unpublished from django.db.models.signals import post_save content_published.connect(publishable_published) content_unpublished.connect(publishable_unpublished) comment_was_posted.connect(comment_posted, sender=comments.get_model()) post_save.connect(comment_post_save, sender=comments.get_model())
def test_post_comment_child(self): Comment = comments.get_model() comment = self._post_comment() self.assertEqual(comment.tree_path, str(comment.pk).zfill(PATH_DIGITS)) child_comment = self._post_comment(data={'name': 'ericflo'}, parent=comment) comment_pk = str(comment.pk).zfill(PATH_DIGITS) child_comment_pk = str(child_comment.pk).zfill(PATH_DIGITS) self.assertEqual(child_comment.tree_path, PATH_SEPARATOR.join((comment.tree_path, child_comment_pk))) self.assertEqual(comment.pk, child_comment.parent.pk) comment = comments.get_model().objects.get(pk=comment.pk) self.assertEqual(comment.last_child, child_comment)
def comments_subtree(request, from_comment_pk, include_self=None, include_ancestors=None, cutoff=None, *args, **kwargs): comment = get_model().objects.select_related( 'content_type').get(pk=from_comment_pk) if not cutoff: cutoff = getattr(settings, 'MPTT_COMMENTS_CUTOFF', 3) cutoff_level = comment.level + cutoff bottom_level = not include_ancestors and ( comment.level - (include_self and 1 or 0)) or 0 qs = get_model().objects.filter_hidden_comments().filter( tree_id=comment.tree_id, lft__gte=comment.lft + (not include_self and 1 or 0), lft__lte=comment.rght, level__lte=cutoff_level - (include_self and 1 or 0) ) is_ajax = request.GET.get('is_ajax') and '_ajax' or '' if is_ajax: json_data = {'comments_for_update': [], 'comments_tree': {}} json_data['comments_tree'] = comment_tree_json(request, list( qs), comment.tree_id, cutoff_level, bottom_level) return HttpResponse(simplejson.dumps(json_data), mimetype='application/json') else: target = comment.content_object model = target.__class__ template_list = [ "comments/%s_%s_subtree.html" % tuple(str(model._meta).split(".")), "comments/%s_subtree.html" % model._meta.app_label, "comments/subtree.html" ] comments = list(qs) if include_ancestors: comments = list(comment.get_ancestors()) + comments return TemplateResponse(request, template_list, { "object": target, "detail_comment": comment, "comments": comments, "bottom_level": bottom_level, "cutoff_level": cutoff_level - 1, "collapse_levels_above": getattr(settings, 'MPTT_COMMENTS_COLLAPSE_ABOVE', 2), "collapse_levels_below": getattr(settings, 'MPTT_COMMENTS_COLLAPSE_BELOW_DETAIL', True) and comment.level or 0 })
def test_moderate_comment_on_entry_without_author(self): self.entry.authors.clear() comment = comments.get_model().objects.create( comment='My Comment', user=self.author, is_public=True, content_object=self.entry, site=self.site) moderator = EntryCommentModerator(Entry) moderator.auto_moderate_comments = False moderator.spam_checker_backends = ( 'zinnia.spam_checker.backends.all_is_spam',) self.assertEquals(moderator.moderate(comment, self.entry, 'request'), True) self.assertEquals(comments.get_model().objects.filter( flags__flag=SPAM).count(), 1)
def create_discussions(self, entry): comment = comments.get_model().objects.create( comment="My Comment", user=self.author, content_object=entry, site=self.site ) pingback = comments.get_model().objects.create( comment="My Pingback", user=self.author, content_object=entry, site=self.site ) pingback.flags.create(user=self.author, flag=PINGBACK) trackback = comments.get_model().objects.create( comment="My Trackback", user=self.author, content_object=entry, site=self.site ) trackback.flags.create(user=self.author, flag=TRACKBACK) return [comment, pingback, trackback]
def get_preview(self): preview = '' if self.type in ("PP","PS","FS"): post = self.content_object try: if isinstance(post, SharePost): post = post.content_object preview = post.content except: preview = '' if self.type in ("MP","MS","MM"): post_ids = [p.item_id for p in self.extra_set.all() if p.item_id] post = Post.objects.filter(id__in=post_ids).order_by('date')[0] post = post.get_inherited() try: if isinstance(post, SharePost): post = post.content_object preview = post.content except: preview = '' if self.type in ('CS','FC'): if self.related_object: preview = self.related_object.comment else: # old version post = self.content_object comment = comments.get_model().objects.filter( content_type=ContentType.objects.get_for_model(post), object_pk=post.pk, site__pk=settings.SITE_ID, is_removed=False, ).order_by('-submit_date')[0] preview = comment.comment if self.type in ('MC','MF'): comm_ids = [c.item_id for c in self.extra_set.all() if c.item_id] if comm_ids: comment = comments.get_model().objects.filter( id__in=comm_ids ).order_by('submit_date')[0] else: # old version post = self.content_object comment = comments.get_model().objects.filter( content_type=ContentType.objects.get_for_model(post), object_pk=post.pk, site__pk=settings.SITE_ID, is_removed=False, ).order_by('submit_date')[0] preview = comment.comment return preview
def post_comment_as_logged_in_user(self): c = create_comment(self.publishable, self.publishable.content_type) boy = User.objects.create(username='******', email='*****@*****.**') boy.set_password('boy') boy.save() self.client.login(username='******', password='******') form = comments.get_form()(target_object=self.publishable, parent=c.pk) data = { 'name': '', 'email': '', } response = self.client.post(self.get_url('new'), self.get_form_data(form, **data)) tools.assert_equals(302, response.status_code) tools.assert_equals(2, comments.get_model().objects.count()) child = comments.get_model().objects.exclude(pk=c.pk)[0] tools.assert_equals(u'boy', child.user_name) tools.assert_equals(u'*****@*****.**', child.user_email)
def test_do_email_reply(self): comment = comments.get_model().objects.create( comment="My Comment 1", user=self.author, is_public=True, content_object=self.entry, submit_date=timezone.now(), site=self.site, ) moderator = EntryCommentModerator(Entry) moderator.email_notification_reply = True moderator.mail_comment_notification_recipients = ["*****@*****.**", "*****@*****.**"] moderator.do_email_reply(comment, self.entry, "request") self.assertEqual(len(mail.outbox), 0) comment = comments.get_model().objects.create( comment="My Comment 2", user_email="*****@*****.**", content_object=self.entry, is_public=True, submit_date=timezone.now(), site=self.site, ) moderator.do_email_reply(comment, self.entry, "request") self.assertEqual(len(mail.outbox), 0) comment = comments.get_model().objects.create( comment="My Comment 3", user_email="*****@*****.**", content_object=self.entry, is_public=True, submit_date=timezone.now(), site=self.site, ) moderator.do_email_reply(comment, self.entry, "request") self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].bcc, ["*****@*****.**"]) comment = comments.get_model().objects.create( comment="My Comment 4", user=self.author, is_public=True, content_object=self.entry, submit_date=timezone.now(), site=self.site, ) moderator.do_email_reply(comment, self.entry, "request") self.assertEqual(len(mail.outbox), 2) self.assertEqual(set(mail.outbox[1].bcc), set(["*****@*****.**", "*****@*****.**"]))
def test_get_popular_entries(self): with self.assertNumQueries(2): context = get_popular_entries() self.assertEquals(len(context['entries']), 0) self.assertEquals(context['template'], 'zinnia/tags/popular_entries.html') self.publish_entry() with self.assertNumQueries(1): context = get_popular_entries(3, 'custom_template.html') self.assertEquals(len(context['entries']), 0) self.assertEquals(context['template'], 'custom_template.html') params = {'title': 'My second entry', 'content': 'My second content', 'tags': 'zinnia, test', 'status': PUBLISHED, 'slug': 'my-second-entry'} site = Site.objects.get_current() second_entry = Entry.objects.create(**params) second_entry.sites.add(site) c1 = comments.get_model().objects.create( comment='My Comment 1', site=site, content_object=self.entry, is_public=False) c2 = comments.get_model().objects.create( comment='My Comment 2', site=site, content_object=self.entry, is_public=False) comments.get_model().objects.create(comment='My Comment 3', site=site, content_object=self.entry, is_public=True) comments.get_model().objects.create(comment='My Comment 4', site=site, content_object=second_entry, is_public=True) comments.get_model().objects.create(comment='My Comment 5', site=site, content_object=second_entry, is_public=True) with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [second_entry, self.entry]) c1.is_public = True c1.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [self.entry, second_entry]) c2.is_public = True c2.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [self.entry, second_entry]) self.entry.status = DRAFT self.entry.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [second_entry])
def approve(request, comment_id, next=None): """ Approve a comment (that is, mark it as public and non-removed). Confirmation on GET, action on POST. Requires the "can moderate comments" permission. Templates: :template:`comments/approve.html`, Context: comment the `comments.comment` object for approval """ comment = get_object_or_404(comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) # Delete on POST if request.method == 'POST': # Flag the comment as approved. perform_approve(request, comment) return next_redirect(request, fallback=next or 'comments-approve-done', c=comment.pk) # Render a form on GET else: return render_to_response('comments/approve.html', {'comment': comment, "next": next}, template.RequestContext(request) )
def import_comments(self, nodetype, comment_nodes): """Loops over comments nodes and import then in django.contrib.comments""" for comment_node in comment_nodes: is_pingback = comment_node.find( '{%s}comment_type' % WP_NS).text == 'pingback' is_trackback = comment_node.find( '{%s}comment_type' % WP_NS).text == 'trackback' title = 'Comment #%s' % (comment_node.find( '{%s}comment_id/' % WP_NS).text) self.write_out(' > %s... ' % title) content = comment_node.find( '{%s}comment_content/' % WP_NS).text if not content: self.write_out(self.style.NOTICE('SKIPPED (unfilled)\n')) return submit_date = datetime.strptime( comment_node.find('{%s}comment_date' % WP_NS).text, '%Y-%m-%d %H:%M:%S') approvation = comment_node.find( '{%s}comment_approved' % WP_NS).text is_public = True is_removed = False if approvation != '1': is_removed = True if approvation == 'spam': is_public = False comment_dict = { 'content_object': nodetype, 'site': self.SITE, 'user_name': comment_node.find( '{%s}comment_author/' % WP_NS).text[:50], 'user_email': comment_node.find( '{%s}comment_author_email/' % WP_NS).text or '', 'user_url': comment_node.find( '{%s}comment_author_url/' % WP_NS).text or '', 'comment': content, 'submit_date': submit_date, 'ip_address': comment_node.find( '{%s}comment_author_IP/' % WP_NS).text or '', 'is_public': is_public, 'is_removed': is_removed, } comment = comments.get_model()(**comment_dict) comment.save() if approvation == 'spam': comment.flags.create( user=nodetype.authors.all()[0], flag='spam') if is_pingback: comment.flags.create( user=nodetype.authors.all()[0], flag='pingback') if is_trackback: comment.flags.create( user=nodetype.authors.all()[0], flag='trackback') self.write_out(self.style.ITEM('OK\n'))
def items(self, obj): rev_contenttype = get_object_or_404(ContentType, app_label='submission', model='revision') all_comments = comments.get_model().objects.filter( content_type=rev_contenttype, object_pk=obj.pk, is_removed = False) return all_comments.order_by('-submit_date')
def __init__(self, *args, **kwargs): super(CommentsRelation, self).__init__( to=comments.get_model(), content_type_field='content_type', object_id_field='object_pk', **kwargs )
def delete(request, comment_id, next=None): """ Deletes a comment. Confirmation on GET, action on POST. Requires the "can moderate comments" permission. Templates: :template:`comments/delete.html`, Context: comment the flagged `comments.comment` object """ comment = get_object_or_404(comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) # Delete on POST if request.method == 'POST': # Flag the comment as deleted instead of actually deleting it. perform_delete(request, comment) return next_redirect(request, fallback=next or 'comments-delete-done', c=comment.pk) # Render a form on GET else: return render_to_response('comments/delete.html', {'comment': comment, "next": next}, template.RequestContext(request) )
def list_comments(request, context): # basic queryset qs = comments.get_model().objects.for_model(context['object']).order_by('tree_path') # only individual branches requested if 'ids' in request.GET: ids = request.GET.getlist('ids') # branch is everything whose tree_path begins with the same prefix qs = qs.filter(reduce(operator.or_, map(lambda x: Q(tree_path__startswith=x.zfill(10)), ids))) # pagination if 'p' in request.GET and request.GET['p'].isdigit(): page_no = int(request.GET['p']) else: page_no = 1 paginate_by = getattr(settings, 'COMMENTS_PAGINATE_BY', 50) paginator = Paginator(qs, paginate_by) if page_no > paginator.num_pages or page_no < 1: raise Http404() page = paginator.page(page_no) context.update({ 'comment_list': page.object_list, 'page': page, 'is_paginated': paginator.num_pages > 1, 'results_per_page': paginate_by, }) return render_to_response( get_templates_from_placement('comment_list.html', context['placement']), context, RequestContext(request) )
def get_last_comment_date(self): # Im so sorry, db now = timezone.now() delta = dateclass.timedelta(days=365 * 5) latest_date = now - delta oldest = latest_date # find all posts in topic posts = self.posts.all() # find latest comment date for each if posts: for post in posts: comms = comments.get_model().objects.filter( content_type=ContentType.objects.get_for_model(post.get_post()), object_pk=post.pk, site__pk=settings.SITE_ID, is_removed=False, ) if comms: new_date = comms.latest('submit_date') if new_date.submit_date > latest_date: latest_date = new_date.submit_date if latest_date != oldest: return latest_date else: return None
def flag(request, comment_id, next=None): """ Flags a comment. Confirmation on GET, action on POST. Templates: `comments/flag.html`, Context: comment the flagged `comments.comment` object """ comment = get_object_or_404(comments.get_model(), pk=comment_id, site__pk=settings.SITE_ID) # Flag on POST if request.method == 'POST': flag, created = comments.models.CommentFlag.objects.get_or_create( comment = comment, user = request.user, flag = comments.models.CommentFlag.SUGGEST_REMOVAL ) signals.comment_was_flagged.send( sender = comment.__class__, comment = comment, flag = flag, created = created, request = request, ) return next_redirect(request.POST.copy(), next, flag_done, c=comment.pk) # Render a form on GET else: return render_to_response('comments/flag.html', {'comment': comment, "next": next}, template.RequestContext(request) )
def custom_urls(request, bits, context): # /object/comments/ opts = CommentOptionsObject.objects.get_for_object(context['object']) if opts.blocked: raise Http404('Comments is blocked for this object.') if not bits: return list_comments(request, context) # /object/comments/new/ elif bits[0] == slugify(_('new')): parent = None if len(bits) > 2: raise Http404() # /object/comments/new/ID/ elif len(bits) == 2: # reply parent = get_object_or_404(comments.get_model(), pk=bits[1]) return post_comment(request, context, parent) raise Http404()
def index(request): featured_videos = models.Video.objects.filter( site=request.sitelocation.site_id, status=models.VIDEO_STATUS_ACTIVE, last_featured__isnull=False) featured_videos = featured_videos.order_by( '-last_featured', '-when_approved', '-when_published', '-when_submitted') popular_videos = models.Video.objects.popular_since( datetime.timedelta(days=7), sitelocation=request.sitelocation, status=models.VIDEO_STATUS_ACTIVE) new_videos = models.Video.objects.new( site=request.sitelocation.site, status=models.VIDEO_STATUS_ACTIVE) \ .exclude(feed__avoid_frontpage=True) recent_comments = comments.get_model().objects.filter( site=request.sitelocation.site, content_type__app_label='localtv', content_type__model='video', object_pk__in=models.Video.objects.filter( status=models.VIDEO_STATUS_ACTIVE), is_removed=False, is_public=True).order_by('-submit_date') return render_to_response( 'localtv/index.html', {'featured_videos': featured_videos, 'popular_videos': popular_videos, 'new_videos': new_videos, 'comments': recent_comments}, context_instance=RequestContext(request))
def test_last_child_properly_created(self): Comment = comments.get_model() new_child_comment = Comment(comment="Comment 8", site_id=1, content_type_id=7, object_pk=1, parent_id=1) new_child_comment.save() comment = Comment.objects.get(pk=1) self.assertEqual(comment.last_child, new_child_comment)
def talks_data(tids): cached = zip(tids, talk_data.get_from_cache([(x, ) for x in tids])) missing = [x[0] for x in cached if x[1] is cache_me.CACHE_MISS] preload = {} talks = models.Talk.objects\ .filter(id__in=missing) speakers_data = models.TalkSpeaker.objects\ .filter(talk__in=talks.values('id'))\ .values('talk', 'speaker', 'helper',) tags = models.ConferenceTaggedItem.objects\ .filter( content_type=ContentType.objects.get_for_model(models.Talk), object_id__in=talks.values('id') )\ .values('object_id', 'tag__name') abstracts = models.MultilingualContent.objects\ .filter( content_type=ContentType.objects.get_for_model(models.Talk), object_id__in=talks.values('id') ) comment_list = comments.get_model().objects\ .filter(content_type__app_label='conference', content_type__model='talk')\ .filter(object_pk__in=talks.values('id'), is_public=True) events = models.Event.objects\ .filter(talk__in=missing)\ .values('talk', 'id') for t in talks: preload[t.id] = { 'talk': t, 'speakers_data': [], 'tags': set(), 'abstract': None, 'comments': [], 'event': [], } pids = set() for r in speakers_data: pids.add(r['speaker']) preload[r['talk']]['speakers_data'].append({ 'speaker': r['speaker'], 'helper': r['helper'], }) for r in tags: preload[r['object_id']]['tags'].add(r['tag__name']) for r in abstracts: if 'abstract' not in preload[r.object_id]: preload[r.object_id]['abstract'] = r else: if settings.LANGUAGE_CODE.startswith(r.language): preload[r.object_id]['abstract'] = r for r in comment_list: preload[int(r.object_pk)]['comments'].append(r) for r in events: preload[r['talk']]['event'].append(r['id']) # talk_data utilizza profile_data per recuperare alcuni dati sullo speaker, # precarico l'elenco per minimizzare il numero di query necessario profiles_data(pids) output = [] for ix, e in enumerate(cached): tid, val = e if val is cache_me.CACHE_MISS: val = talk_data(tid, preload=preload[tid]) output.append(val) return output
def discussions(self): """Return published discussions""" return comments.get_model().objects.for_model(self).filter( is_public=True)
def test_rendering_of_full_tree(self): output = loader.render_to_string('sample_tree.html', {'comment_list': comments.get_model().objects.all()}) self.assertEqual(self.EXPECTED_HTML_FULL, sanitize_html(output))
def test_root_path_returns_only_correct_nodes(self): c = comments.get_model().objects.get(pk=6) self.assertEqual([1, 4], [x.pk for x in c.root_path])
def remove_comments(self, request, queryset): self._bulk_flag(request, queryset, perform_delete, lambda n: ungettext('removed', 'removed', n)) remove_comments.short_description = _("Remove selected comments") def _bulk_flag(self, request, queryset, action, done_message): """ Flag, approve, or remove some comments from an admin action. Actually calls the `action` argument to perform the heavy lifting. """ n_comments = 0 for comment in queryset: action(request, comment) n_comments += 1 msg = ungettext(u'1 comment was successfully %(action)s.', u'%(count)s comments were successfully %(action)s.', n_comments) self.message_user( request, msg % { 'count': n_comments, 'action': done_message(n_comments) }) # Only register the default admin if the model is the built-in comment model # (this won't be true if there's a custom comment app). if get_model() is Comment: admin.site.register(Comment, CommentsAdmin)
def user_name_col(self, comment): if comment.user_name: return comment.user_name elif comment.user_id: # Can't do much else here, User model might be custom. return unicode(comment.user) else: return None user_name_col.short_description = _("user's name") def has_add_permission(self, request): return False def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'title': kwargs['widget'] = AdminTextInputWidget return super(FluentCommentsAdmin, self).formfield_for_dbfield(db_field, **kwargs) # Replace the old admin screen. if appsettings.FLUENT_COMMENTS_REPLACE_ADMIN: CommentModel = comments.get_model() try: admin.site.unregister(CommentModel) except admin.sites.NotRegistered as e: pass admin.site.register(CommentModel, FluentCommentsAdmin)
def testGetModel(self): from regressiontests.comment_tests.custom_comments.models import CustomComment self.assertEqual(comments.get_model(), CustomComment)
def pingback_ping(source, target): """pingback.ping(sourceURI, targetURI) => 'Pingback message' Notifies the server that a link has been added to sourceURI, pointing to targetURI. See: http://hixie.ch/specs/pingback/pingback-1.0""" try: if source == target: return UNDEFINED_ERROR site = Site.objects.get_current() try: document = ''.join( map(lambda byte_line: byte_line.decode("utf-8"), urlopen(source).readlines())) except (HTTPError, URLError): return SOURCE_DOES_NOT_EXIST if not target in document: return SOURCE_DOES_NOT_LINK scheme, netloc, path, query, fragment = urlsplit(target) if netloc != site.domain: return TARGET_DOES_NOT_EXIST try: view, args, kwargs = resolve(path) except Resolver404: return TARGET_DOES_NOT_EXIST try: entry = Entry.published.get(slug=kwargs['slug'], creation_date__year=kwargs['year'], creation_date__month=kwargs['month'], creation_date__day=kwargs['day']) if not entry.pingbacks_are_open: return TARGET_IS_NOT_PINGABLE except (KeyError, Entry.DoesNotExist): return TARGET_IS_NOT_PINGABLE soup = BeautifulSoup(document) title = six.text_type(soup.find('title')) title = title and strip_tags(title) or _('No title') description = generate_pingback_content(soup, target, PINGBACK_CONTENT_LENGTH) pingback, created = comments.get_model().objects.get_or_create( content_type=ContentType.objects.get_for_model(Entry), object_pk=entry.pk, user_url=source, site=site, defaults={ 'comment': description, 'user_name': title, 'submit_date': timezone.now() }) if created: pingback.flags.create(user=get_user_flagger(), flag=PINGBACK) pingback_was_posted.send(pingback.__class__, pingback=pingback, entry=entry) return 'Pingback from %s to %s registered.' % (source, target) return PINGBACK_ALREADY_REGISTERED except: return UNDEFINED_ERROR
def test_root_path_returns_empty_for_root_comments(self): c = comments.get_model().objects.get(pk=7) self.assertEqual([], [x.pk for x in c.root_path])
self._bulk_flag(queryset, perform_approve, lambda n: ungettext('approved', 'approved', n)) approve_comments.short_description = _("Approve selected comments") approve_comments.icon = 'ok' def remove_comments(self, request, queryset): self._bulk_flag(queryset, perform_delete, lambda n: ungettext('removed', 'removed', n)) remove_comments.short_description = _("Remove selected comments") remove_comments.icon = 'remove-circle' def _bulk_flag(self, queryset, action, done_message): """ Flag, approve, or remove some comments from an admin action. Actually calls the `action` argument to perform the heavy lifting. """ n_comments = 0 for comment in queryset: action(self.request, comment) n_comments += 1 msg = ungettext('1 comment was successfully %(action)s.', '%(count)s comments were successfully %(action)s.', n_comments) self.message_user(msg % {'count': n_comments, 'action': done_message(n_comments)}, 'success') # Only register the default admin if the model is the built-in comment model # (this won't be true if there's a custom comment app). if 'django.contrib.comments' in settings.INSTALLED_APPS and (get_model() is Comment): xadmin.site.register(Comment, CommentsAdmin)
def test_root_id_returns_self_for_root_comments(self): c = comments.get_model().objects.get(pk=7) self.assertEqual(c.pk, c.root_id)
def test_discussions(self): site = Site.objects.get_current() self.assertEquals(self.entry.discussions_qs.count(), 0) self.assertEquals(self.entry.comments_qs.count(), 0) self.assertEquals(self.entry.pingbacks_qs.count(), 0) self.assertEquals(self.entry.trackbacks_qs.count(), 0) comments.get_model().objects.create(comment='My Comment 1', content_object=self.entry, site=site) self.assertEquals(self.entry.discussions_qs.count(), 1) self.assertEquals(self.entry.comments_qs.count(), 1) self.assertEquals(self.entry.pingbacks_qs.count(), 0) self.assertEquals(self.entry.trackbacks_qs.count(), 0) comments.get_model().objects.create(comment='My Comment 2', content_object=self.entry, site=site, is_public=False) self.assertEquals(self.entry.discussions_qs.count(), 1) self.assertEquals(self.entry.comments_qs.count(), 1) self.assertEquals(self.entry.pingbacks_qs.count(), 0) self.assertEquals(self.entry.trackbacks_qs.count(), 0) author = User.objects.create_user(username='******', email='*****@*****.**') comment = comments.get_model().objects.create( comment='My Comment 3', content_object=self.entry, site=Site.objects.create(domain='http://toto.com', name='Toto.com')) comment.flags.create(user=author, flag=CommentFlag.MODERATOR_APPROVAL) self.assertEquals(self.entry.discussions_qs.count(), 2) self.assertEquals(self.entry.comments_qs.count(), 2) self.assertEquals(self.entry.pingbacks_qs.count(), 0) self.assertEquals(self.entry.trackbacks_qs.count(), 0) comment = comments.get_model().objects.create( comment='My Pingback 1', content_object=self.entry, site=site) comment.flags.create(user=author, flag=PINGBACK) self.assertEquals(self.entry.discussions_qs.count(), 3) self.assertEquals(self.entry.comments_qs.count(), 2) self.assertEquals(self.entry.pingbacks_qs.count(), 1) self.assertEquals(self.entry.trackbacks_qs.count(), 0) self.assertEquals(len(self.entry.discussions), 3) self.assertEquals(len(self.entry.comments), 2) self.assertEquals(len(self.entry.pingbacks), 1) self.assertEquals(len(self.entry.trackbacks), 0) comment = comments.get_model().objects.create( comment='My Trackback 1', content_object=self.entry, site=site) comment.flags.create(user=author, flag=TRACKBACK) self.assertEquals(self.entry.discussions_qs.count(), 4) self.assertEquals(self.entry.comments_qs.count(), 2) self.assertEquals(self.entry.pingbacks_qs.count(), 1) self.assertEquals(self.entry.trackbacks_qs.count(), 1) with self.assertNumQueries(0): # No queries will be performed and the results are outdated self.assertEquals(len(self.entry.discussions), 3) self.assertEquals(len(self.entry.comments), 2) self.assertEquals(len(self.entry.pingbacks), 1) self.assertEquals(len(self.entry.trackbacks), 0)
def items(self): """Items are the discussions on the entries""" content_type = ContentType.objects.get_for_model(Entry) return comments.get_model().objects.filter( content_type=content_type, is_public=True).order_by('-submit_date')[:FEEDS_MAX_ITEMS]
object_pk = models.TextField() content_object = GenericForeignKey(ct_field="content_type", fk_field="object_pk") site = models.ForeignKey(Site) user = models.ForeignKey(AUTH_USER_MODEL, related_name="%(class)s_comments") user_name = models.CharField(max_length=50, blank=True) user_email = models.EmailField(blank=True) user_url = models.URLField(blank=True) comment = models.TextField(max_length=3000) submit_date = models.DateTimeField(default=None) ip_address = models.GenericIPAddressField(unpack_ipv4=True, blank=True, null=True) is_public = models.BooleanField(default=True) is_removed = models.BooleanField(default=False) CommentModel = get_model() if IS_INSTALLED: class CommentRelation(GenericRelation): def __init__(self, to=CommentModel, **kwargs): kwargs.setdefault('object_id_field', 'object_pk') super(CommentRelation, self).__init__(to, **kwargs) else: class CommentRelation(models.Field): def __init__(self, *args, **kwargs): pass def contribute_to_class(self, cls, name, virtual_only=False):
from django import forms from django.forms.models import modelformset_factory, BaseModelFormSet from django.utils.translation import ugettext_lazy as _ from django.conf import settings from django.contrib import comments from django.contrib.comments import forms as comment_forms from django.contrib.comments.views.moderation import (perform_approve, perform_delete) try: from recaptcha_django import ReCaptchaField except ImportError: ReCaptchaField = None Comment = comments.get_model() class CommentForm(comment_forms.CommentForm): comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, max_length=comment_forms.COMMENT_MAX_LENGTH) email = forms.EmailField(label=_("Email address"), required=False) if ReCaptchaField and not settings.DEBUG and \ settings.RECAPTCHA_PRIVATE_KEY: captcha = ReCaptchaField() def __init__(self, target_object, data=None, initial=None): comment_forms.CommentForm.__init__(self, target_object, data, initial) if 'captcha' in self.fields and data and 'user' in data: from localtv.models import SiteLocation # avoid circular import
def test_root_id_returns_root_for_replies(self): c = comments.get_model().objects.get(pk=6) self.assertEqual(1, c.root_id)
elif sender is models.Speaker: tids = kw['instance'].talks().values('id') elif sender is comments.get_model(): o = kw['instance'] if o.content_type.app_label == 'conference' and o.content_type.model == 'talk': tids = [o.object_pk] else: tids = [] else: tids = [kw['instance'].talk_id] return ['talk_data:%s' % x for x in tids] talk_data = cache_me(models=(models.Talk, models.Speaker, models.TalkSpeaker, comments.get_model()), key='talk_data:%(tid)s')(talk_data, _i_talk_data) def talks_data(tids): cached = zip(tids, talk_data.get_from_cache([(x, ) for x in tids])) missing = [x[0] for x in cached if x[1] is cache_me.CACHE_MISS] preload = {} talks = models.Talk.objects\ .filter(id__in=missing) speakers_data = models.TalkSpeaker.objects\ .filter(talk__in=talks.values('id'))\ .values('talk', 'speaker', 'helper',) tags = models.ConferenceTaggedItem.objects\ .filter(
def import_comments(self, entry, comment_nodes): """Loops over comments nodes and import then in django.contrib.comments""" for comment_node in comment_nodes: is_pingback = comment_node.find( '{%s}comment_type' % WP_NS).text == PINGBACK is_trackback = comment_node.find( '{%s}comment_type' % WP_NS).text == TRACKBACK title = 'Comment #%s' % (comment_node.find( '{%s}comment_id' % WP_NS).text) self.write_out(' > %s... ' % title) content = comment_node.find( '{%s}comment_content' % WP_NS).text if not content: self.write_out(self.style.NOTICE('SKIPPED (unfilled)\n')) return submit_date = datetime.strptime( comment_node.find('{%s}comment_date' % WP_NS).text, '%Y-%m-%d %H:%M:%S') if settings.USE_TZ: submit_date = timezone.make_aware(submit_date, timezone.utc) approvation = comment_node.find( '{%s}comment_approved' % WP_NS).text is_public = True is_removed = False if approvation != '1': is_removed = True if approvation == 'spam': is_public = False comment_dict = { 'content_object': entry, 'site': self.SITE, 'user_name': comment_node.find( '{%s}comment_author' % WP_NS).text[:50], 'user_email': comment_node.find( '{%s}comment_author_email' % WP_NS).text or '', 'user_url': comment_node.find( '{%s}comment_author_url' % WP_NS).text or '', 'comment': content, 'submit_date': submit_date, 'ip_address': comment_node.find( '{%s}comment_author_IP' % WP_NS).text or '', 'is_public': is_public, 'is_removed': is_removed, } comment = comments.get_model()(**comment_dict) comment.save() if is_pingback: comment.flags.create( user=get_user_flagger(), flag=PINGBACK) if is_trackback: comment.flags.create( user=get_user_flagger(), flag=TRACKBACK) self.write_out(self.style.ITEM('OK\n')) entry.comment_count = entry.comments.count() entry.pingback_count = entry.pingbacks.count() entry.trackback_count = entry.trackbacks.count() entry.save(force_update=True)
def discussions(self): """ Returns a queryset of the published discussions. """ return comments.get_model().objects.for_model(self).filter( is_public=True, is_removed=False)
def get_comment_count(self): return get_model().objects.filter(object_pk=self.pk).count()
def test_get_popular_entries(self): with self.assertNumQueries(2): context = get_popular_entries() self.assertEquals(len(context['entries']), 0) self.assertEquals(context['template'], 'zinnia/tags/popular_entries.html') self.publish_entry() with self.assertNumQueries(1): context = get_popular_entries(3, 'custom_template.html') self.assertEquals(len(context['entries']), 0) self.assertEquals(context['template'], 'custom_template.html') params = { 'title': 'My second entry', 'content': 'My second content', 'tags': 'zinnia, test', 'status': PUBLISHED, 'slug': 'my-second-entry' } site = Site.objects.get_current() second_entry = Entry.objects.create(**params) second_entry.sites.add(site) c1 = comments.get_model().objects.create(comment='My Comment 1', site=site, content_object=self.entry, is_public=False) c2 = comments.get_model().objects.create(comment='My Comment 2', site=site, content_object=self.entry, is_public=False) comments.get_model().objects.create(comment='My Comment 3', site=site, content_object=self.entry, is_public=True) comments.get_model().objects.create(comment='My Comment 4', site=site, content_object=second_entry, is_public=True) comments.get_model().objects.create(comment='My Comment 5', site=site, content_object=second_entry, is_public=True) with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [second_entry, self.entry]) c1.is_public = True c1.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [self.entry, second_entry]) c2.is_public = True c2.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [self.entry, second_entry]) self.entry.status = DRAFT self.entry.save() with self.assertNumQueries(2): context = get_popular_entries(3) self.assertEquals(context['entries'], [second_entry])
def test_root_has_depth_1(self): c = comments.get_model().objects.get(pk=7) self.assertEqual(1, c.depth)