def test_comment_post_moderated(self):
        """
        See that soft delete works properly.
        """
        # Double check preconditions for moderation
        self.assertIsNotNone(get_model_moderator(Article))
        self.assertTrue(len(signals.comment_will_be_posted.receivers))
        self.assertEqual(id(get_comment_model()),
                         signals.comment_will_be_posted.receivers[0][0][1])

        content_type = "article.article"
        timestamp = str(int(time.time()))
        article = factories.create_article()

        form = CommentForm(article)
        security_hash = form.generate_security_hash(content_type,
                                                    str(article.pk), timestamp)
        post_data = {
            "content_type": content_type,
            "object_pk": article.pk,
            "name": "Testing name",
            "email": "*****@*****.**",
            "comment": "Testing comment",
            "timestamp": timestamp,
            "security_hash": security_hash,
        }

        for url, is_ajax in [
            (reverse("comments-post-comment-ajax"), True),
            (reverse("comments-post-comment"), False),
        ]:
            with patch.object(Akismet,
                              "_request",
                              return_value=MockedResponse(True)) as m:
                response = self.client.post(
                    url, post_data, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
            self.assertEqual(m.call_count, 1, "Moderator not called by " + url)

            if is_ajax:
                self.assertContains(response,
                                    "Testing comment",
                                    status_code=200)
                self.assertEqual(response.status_code, 200)

                json_response = json.loads(response.content.decode("utf-8"))
                self.assertTrue(json_response["success"])
                self.assertEqual(json_response["errors"], {})
            else:
                self.assertRedirects(response,
                                     reverse("comments-comment-done") + "?c=1")

            comment = get_comment_model().objects.filter(
                user_email="*****@*****.**")[0]
            self.assertFalse(comment.is_public, "Not moderated by " + url)
            self.assertTrue(comment.is_removed)
Example #2
0
def zinnia_statistics(template="zinnia/tags/statistics.html"):
    """
    Return statistics on the content of Zinnia.
    """
    content_type = ContentType.objects.get_for_model(Entry)
    discussions = get_comment_model().objects.filter(content_type=content_type)

    entries = Entry.published
    categories = Category.objects
    tags = tags_published()
    authors = Author.published
    replies = discussions.filter(flags=None, is_public=True)
    pingbacks = discussions.filter(flags__flag=PINGBACK, is_public=True)
    trackbacks = discussions.filter(flags__flag=TRACKBACK, is_public=True)
    rejects = discussions.filter(is_public=False)

    entries_count = entries.count()
    replies_count = replies.count()
    pingbacks_count = pingbacks.count()
    trackbacks_count = trackbacks.count()

    if entries_count:
        first_entry = entries.order_by("creation_date")[0]
        last_entry = entries.latest()
        months_count = (last_entry.creation_date - first_entry.creation_date).days / 31.0
        entries_per_month = entries_count / (months_count or 1.0)

        comments_per_entry = float(replies_count) / entries_count
        linkbacks_per_entry = float(pingbacks_count + trackbacks_count) / entries_count

        total_words_entry = 0
        for e in entries.all():
            total_words_entry += e.word_count
        words_per_entry = float(total_words_entry) / entries_count

        words_per_comment = 0.0
        if replies_count:
            total_words_comment = 0
            for c in replies.all():
                total_words_comment += len(c.comment.split())
            words_per_comment = float(total_words_comment) / replies_count
    else:
        words_per_entry = words_per_comment = entries_per_month = comments_per_entry = linkbacks_per_entry = 0.0

    return {
        "template": template,
        "entries": entries_count,
        "categories": categories.count(),
        "tags": tags.count(),
        "authors": authors.count(),
        "comments": replies_count,
        "pingbacks": pingbacks_count,
        "trackbacks": trackbacks_count,
        "rejects": rejects.count(),
        "words_per_entry": words_per_entry,
        "words_per_comment": words_per_comment,
        "entries_per_month": entries_per_month,
        "comments_per_entry": comments_per_entry,
        "linkbacks_per_entry": linkbacks_per_entry,
    }
Example #3
0
def create_comment(comment_model=None, article=None, user=None, **kwargs):
    """
    Create a new comment.
    """
    if article is None:
        article = create_article()

    article_ctype = ContentType.objects.get_for_model(article)
    defaults = dict(
        user=user,
        user_name="Test-Name",
        user_email="*****@*****.**",
        user_url="http://example.com",
        comment="Test-Comment",
        submit_date=now(),
        site=Site.objects.get_current(),
        ip_address='127.0.0.1',
        is_public=True,
        is_removed=False,
    )
    defaults.update(kwargs)

    Comment = comment_model or get_comment_model()
    return Comment.objects.create(content_type=article_ctype,
                                  object_pk=article.pk,
                                  **defaults)
Example #4
0
def comment_admin_urlname(action):
    """
    Return the admin URLs for the comment app used.
    """
    comment = get_comment_model()
    return 'admin:%s_%s_%s' % (comment._meta.app_label,
                               comment._meta.model_name, action)
def create_comment(comment_model=None, article=None, user=None, **kwargs):
    """
    Create a new comment.
    """
    if article is None:
        article = create_article()

    article_ctype = ContentType.objects.get_for_model(article)
    defaults = dict(
        user=user,
        user_name="Test-Name",
        user_email="*****@*****.**",
        user_url="http://example.com",
        comment="Test-Comment",
        submit_date=now(),
        site=Site.objects.get_current(),
        ip_address='127.0.0.1',
        is_public=True,
        is_removed=False,
    )
    defaults.update(kwargs)

    Comment = comment_model or get_comment_model()
    return Comment.objects.create(
        content_type=article_ctype,
        object_pk=article.pk,
        **defaults
    )
Example #6
0
def comment_admin_urlname(action):
    """
    Return the admin URLs for the comment app used.
    """
    comment = get_comment_model()
    return 'admin:%s_%s_%s' % (
        comment._meta.app_label, comment._meta.model_name,
        action)
    def test_comment_post_moderated(self):
        """
        See that soft delete works properly.
        """
        # Double check preconditions for moderation
        self.assertIsNotNone(get_model_moderator(Article))
        self.assertTrue(len(signals.comment_will_be_posted.receivers))
        self.assertEqual(id(get_comment_model()), signals.comment_will_be_posted.receivers[0][0][1])

        content_type = "article.article"
        timestamp = str(int(time.time()))
        article = factories.create_article()

        form = CommentForm(article)
        security_hash = form.generate_security_hash(content_type, str(article.pk), timestamp)
        post_data = {
            "content_type": content_type,
            "object_pk": article.pk,
            "name": "Testing name",
            "email": "*****@*****.**",
            "comment": "Testing comment",
            "timestamp": timestamp,
            "security_hash": security_hash,
        }

        for url, is_ajax in [
            (reverse("comments-post-comment-ajax"), True),
            (reverse("comments-post-comment"), False),
        ]:
            with patch.object(Akismet, '_request', return_value=MockedResponse(True)) as m:
                response = self.client.post(url, post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
            self.assertEqual(m.call_count, 1, "Moderator not called by " + url)

            if is_ajax:
                self.assertContains(response, "Testing comment", status_code=200)
                self.assertEqual(response.status_code, 200)

                json_response = json.loads(response.content.decode("utf-8"))
                self.assertTrue(json_response['success'])
                self.assertEqual(json_response['errors'], {})
            else:
                self.assertRedirects(response, reverse('comments-comment-done') + "?c=1")

            comment = get_comment_model().objects.filter(user_email="*****@*****.**")[0]
            self.assertFalse(comment.is_public, "Not moderated by " + url)
            self.assertTrue(comment.is_removed)
Example #8
0
def get_recent_comments(number=5, template='zinnia/tags/comments_recent.html'):
    """
    Return the most recent comments.
    """
    # Using map(smart_text... fix bug related to issue #8554
    entry_published_pks = map(smart_text,
                              Entry.published.values_list('id', flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    comments = get_comment_model().objects.filter(
        Q(flags=None) | Q(flags__flag=CommentFlag.MODERATOR_APPROVAL),
        content_type=content_type, object_pk__in=entry_published_pks,
        is_public=True).order_by('-pk')[:number]

    comments = comments.prefetch_related('content_object')

    return {'template': template,
            'comments': comments}
Example #9
0
def get_recent_comments(number=5, template='zinnia/tags/comments_recent.html'):
    """
    Return the most recent comments.
    """
    # Using map(smart_text... fix bug related to issue #8554
    entry_published_pks = map(smart_text,
                              Entry.published.values_list('id', flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    comments = get_comment_model().objects.filter(
        Q(flags=None) | Q(flags__flag=CommentFlag.MODERATOR_APPROVAL),
        content_type=content_type,
        object_pk__in=entry_published_pks,
        is_public=True).order_by('-pk')[:number]

    comments = comments.prefetch_related('content_object')

    return {'template': template, 'comments': comments}
Example #10
0
def get_recent_linkbacks(number=5,
                         template='zinnia/tags/linkbacks_recent.html'):
    """
    Return the most recent linkbacks.
    """
    entry_published_pks = map(smart_text,
                              Entry.published.values_list('id', flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    linkbacks = get_comment_model().objects.filter(
        content_type=content_type,
        object_pk__in=entry_published_pks,
        flags__flag__in=[PINGBACK, TRACKBACK],
        is_public=True).order_by('-pk')[:number]

    linkbacks = linkbacks.prefetch_related('content_object')

    return {'template': template, 'linkbacks': linkbacks}
Example #11
0
def get_recent_linkbacks(number=5,
                         template='zinnia/tags/linkbacks_recent.html'):
    """
    Return the most recent linkbacks.
    """
    entry_published_pks = map(smart_text,
                              Entry.published.values_list('id', flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    linkbacks = get_comment_model().objects.filter(
        content_type=content_type,
        object_pk__in=entry_published_pks,
        flags__flag__in=[PINGBACK, TRACKBACK],
        is_public=True).order_by('-pk')[:number]

    linkbacks = linkbacks.prefetch_related('content_object')

    return {'template': template,
            'linkbacks': linkbacks}
Example #12
0
def get_recent_linkbacks(number=5, template="zinnia/tags/linkbacks_recent.html"):
    """
    Return the most recent linkbacks.
    """
    entry_published_pks = map(smart_text, Entry.published.values_list("id", flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    linkbacks = (
        get_comment_model()
        .objects.filter(
            content_type=content_type,
            object_pk__in=entry_published_pks,
            flags__flag__in=[PINGBACK, TRACKBACK],
            is_public=True,
        )
        .order_by("-pk")[:number]
    )

    linkbacks = linkbacks.prefetch_related("content_object")

    return {"template": template, "linkbacks": linkbacks}
Example #13
0
def get_recent_comments(number=5, template="zinnia/tags/comments_recent.html"):
    """
    Return the most recent comments.
    """
    # Using map(smart_text... fix bug related to issue #8554
    entry_published_pks = map(smart_text, Entry.published.values_list("id", flat=True))
    content_type = ContentType.objects.get_for_model(Entry)

    comments = (
        get_comment_model()
        .objects.filter(
            Q(flags=None) | Q(flags__flag=CommentFlag.MODERATOR_APPROVAL),
            content_type=content_type,
            object_pk__in=entry_published_pks,
            is_public=True,
        )
        .order_by("-pk")[:number]
    )

    comments = comments.prefetch_related("content_object")

    return {"template": template, "comments": comments}
Example #14
0
class Listing(models.Model):
    SOCIAL_NETWORKS = [
        'Facebook', 'Twitter', 'Google', 'Instagram', 'Vimeo', 'YouTube',
        'LinkedIn', 'Dribbble', 'Skype', 'Foursquare', 'Behance'
    ]  # TODO: move to settings

    PRICE_UNITS = [
        ('PERSON', _('person')),
        ('NIGHT', _('night')),
        ('DAY', _('day')),
    ]

    # definition
    title = models.CharField(_('title'), max_length=100, unique=True)
    description = models.TextField(_('description'), blank=True)

    # management
    author = models.ForeignKey(settings.AUTH_USER_MODEL,
                               on_delete=models.CASCADE,
                               verbose_name=_('author'))
    published = models.BooleanField(_('published'), default=True)
    promoted = models.BooleanField(_('promoted'), default=False)

    # specification
    categories = models.ManyToManyField(to='inventor.Category',
                                        verbose_name=_('categories'),
                                        blank=True,
                                        related_name='listings_of_category')
    amenities = models.ManyToManyField(to='inventor.Amenity',
                                       verbose_name=_('amenities'),
                                       blank=True,
                                       related_name='listings_having_amenity')
    features = models.ManyToManyField(to='inventor.Feature',
                                      verbose_name=_('features'),
                                      blank=True,
                                      related_name='listings_with_features')

    # price
    price_starts_at = models.BooleanField(_('price starts at'), default=False)
    price = models.DecimalField(_('price'),
                                help_text=inventor_settings.CURRENCY,
                                max_digits=10,
                                decimal_places=2,
                                db_index=True,
                                validators=[MinValueValidator(0)],
                                blank=True,
                                null=True,
                                default=None)
    price_unit = models.CharField(_('price per unit'),
                                  choices=PRICE_UNITS,
                                  max_length=6,
                                  blank=True)

    # address
    location = models.ForeignKey('inventor.Location',
                                 on_delete=models.SET_NULL,
                                 blank=True,
                                 null=True,
                                 default=None)
    street = models.CharField(_('street'), max_length=200)
    postcode = models.CharField(_('postcode'), max_length=30, db_index=True)
    city = models.CharField(_('city'), max_length=50)
    country = CountryField(verbose_name=_('country'), db_index=True)
    point = models.PointField(_('point'), blank=True, null=True, default=None)

    # previews
    image = models.ImageField(
        verbose_name=_('image'),
        help_text=_('photo or image'),
        max_length=1024,
        upload_to='images',
    )

    banner = models.ImageField(
        verbose_name=_('banner'),
        help_text=_('photo or image'),
        max_length=1024 * 5,
        upload_to='banners',
    )

    # contact information
    person = models.CharField(_('person'), max_length=100, blank=True)
    phone = models.CharField(_('phone'), max_length=40, blank=True)
    email = models.EmailField(_('email'), blank=True)
    website = models.URLField(_('website'), max_length=400, blank=True)

    # social
    social_networks = JSONField(verbose_name=_('social networks'),
                                blank=True,
                                default={})

    # relations
    comments = GenericRelation(get_comment_model(),
                               content_type_field='content_type',
                               object_id_field='object_pk',
                               related_query_name='contest')

    created = models.DateTimeField(_('created'), auto_now_add=True)
    modified = models.DateTimeField(_('modified'), auto_now=True)
    objects = ListingQuerySet.as_manager()

    class Meta:
        verbose_name = _('listing')
        verbose_name_plural = _('listings')
        ordering = ('title', )

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('inventor:listing_detail', args=(self.pk, ))

    def get_update_url(self):
        return reverse('inventor:listing_update', args=(self.pk, ))

    @property
    def address(self):
        return '{}, {} {}, {}'.format(self.street, self.postcode, self.city,
                                      self.country).strip(', ')

    @property
    def country_and_city(self):
        address_parts = [self.get_country_display(), self.city]

        return ', '.join(address_parts).strip(' ,')

    @property
    def get_price_display(self):
        if not self.price:
            return ''

        if inventor_settings.CURRENCY_AFTER_AMOUNT:
            price_display = '{}{}'.format(self.price,
                                          inventor_settings.CURRENCY)
        else:
            price_display = '{}{}'.format(inventor_settings.CURRENCY,
                                          self.price)

        if self.price_starts_at:
            price_display = '{} {}'.format(_('starts at'), price_display)

        if self.price_unit:
            price_display = '{} / {}'.format(price_display,
                                             self.get_price_unit_display())

        return price_display

    @cached_property
    def rating(self):
        avg_rating = self.comments.aggregate(Avg('rating'))
        rating = avg_rating['rating__avg']
        if rating:
            rating = round(rating, 2)
        return rating

    def delete(self, **kwargs):
        """ Deletes file before deleting instance """
        self.delete_banner()
        super().delete(**kwargs)

    def delete_banner(self):
        """ Deletes image file """
        try:
            os.remove(self.banner.path)
        except ValueError:
            pass
        except IOError:
            pass
        except OSError:
            pass
Example #15
0
    def comment_list():
        """Show 4 most recent comments by date."""

        return get_comment_model().objects.order_by("-submit_date")[:4]
Example #16
0
def zinnia_statistics(template='zinnia/tags/statistics.html'):
    """
    Return statistics on the content of Zinnia.
    """
    content_type = ContentType.objects.get_for_model(Entry)
    discussions = get_comment_model().objects.filter(content_type=content_type)

    entries = Entry.published
    categories = Category.objects
    tags = tags_published()
    authors = Author.published
    replies = discussions.filter(flags=None, is_public=True)
    pingbacks = discussions.filter(flags__flag=PINGBACK, is_public=True)
    trackbacks = discussions.filter(flags__flag=TRACKBACK, is_public=True)
    rejects = discussions.filter(is_public=False)

    entries_count = entries.count()
    replies_count = replies.count()
    pingbacks_count = pingbacks.count()
    trackbacks_count = trackbacks.count()

    if entries_count:
        first_entry = entries.order_by('publication_date')[0]
        last_entry = entries.latest()
        months_count = (last_entry.publication_date -
                        first_entry.publication_date).days / 31.0
        entries_per_month = entries_count / (months_count or 1.0)

        comments_per_entry = float(replies_count) / entries_count
        linkbacks_per_entry = float(pingbacks_count + trackbacks_count) / \
            entries_count

        total_words_entry = 0
        for e in entries.all():
            total_words_entry += e.word_count
        words_per_entry = float(total_words_entry) / entries_count

        words_per_comment = 0.0
        if replies_count:
            total_words_comment = 0
            for c in replies.all():
                total_words_comment += len(c.comment.split())
            words_per_comment = float(total_words_comment) / replies_count
    else:
        words_per_entry = words_per_comment = entries_per_month = \
            comments_per_entry = linkbacks_per_entry = 0.0

    return {
        'template': template,
        'entries': entries_count,
        'categories': categories.count(),
        'tags': tags.count(),
        'authors': authors.count(),
        'comments': replies_count,
        'pingbacks': pingbacks_count,
        'trackbacks': trackbacks_count,
        'rejects': rejects.count(),
        'words_per_entry': words_per_entry,
        'words_per_comment': words_per_comment,
        'entries_per_month': entries_per_month,
        'comments_per_entry': comments_per_entry,
        'linkbacks_per_entry': linkbacks_per_entry
    }
from django.core.management.base import CommandError
from django.core.management.base import NoArgsCommand
from django.contrib.contenttypes.models import ContentType

from django_comments import get_model as get_comment_model

from zinnia import __version__
from zinnia.models.entry import Entry
from zinnia.models.author import Author
from zinnia.models.category import Category
from zinnia.managers import DRAFT, PUBLISHED
from zinnia.signals import disconnect_entry_signals
from zinnia.signals import disconnect_discussion_signals

gdata_service = None
Comment = get_comment_model()


class Command(NoArgsCommand):
    """
    Command object for importing a Blogger blog
    into Zinnia via Google's gdata API.
    """

    help = "Import a Blogger blog into Zinnia."

    option_list = NoArgsCommand.option_list + (
        make_option(
            "--blogger-username", dest="blogger_username", default="", help="The username to login to Blogger with"
        ),
        make_option(
Example #18
0
def zinnia_statistics(template='zinnia/tags/statistics.html'):
    """
    Return statistics on the content of Zinnia.
    """
    content_type = ContentType.objects.get_for_model(Entry)
    discussions = get_comment_model().objects.filter(
        content_type=content_type)

    entries = Entry.published
    categories = Category.objects
    tags = tags_published()
    authors = Author.published
    replies = discussions.filter(
        flags=None, is_public=True)
    pingbacks = discussions.filter(
        flags__flag=PINGBACK, is_public=True)
    trackbacks = discussions.filter(
        flags__flag=TRACKBACK, is_public=True)
    rejects = discussions.filter(is_public=False)

    entries_count = entries.count()
    replies_count = replies.count()
    pingbacks_count = pingbacks.count()
    trackbacks_count = trackbacks.count()

    if entries_count:
        first_entry = entries.order_by('publication_date')[0]
        last_entry = entries.latest()
        months_count = (last_entry.publication_date -
                        first_entry.publication_date).days / 31.0
        entries_per_month = entries_count / (months_count or 1.0)

        comments_per_entry = float(replies_count) / entries_count
        linkbacks_per_entry = float(pingbacks_count + trackbacks_count) / \
            entries_count

        total_words_entry = 0
        for e in entries.all():
            total_words_entry += e.word_count
        words_per_entry = float(total_words_entry) / entries_count

        words_per_comment = 0.0
        if replies_count:
            total_words_comment = 0
            for c in replies.all():
                total_words_comment += len(c.comment.split())
            words_per_comment = float(total_words_comment) / replies_count
    else:
        words_per_entry = words_per_comment = entries_per_month = \
            comments_per_entry = linkbacks_per_entry = 0.0

    return {'template': template,
            'entries': entries_count,
            'categories': categories.count(),
            'tags': tags.count(),
            'authors': authors.count(),
            'comments': replies_count,
            'pingbacks': pingbacks_count,
            'trackbacks': trackbacks_count,
            'rejects': rejects.count(),
            'words_per_entry': words_per_entry,
            'words_per_comment': words_per_comment,
            'entries_per_month': entries_per_month,
            'comments_per_entry': comments_per_entry,
            'linkbacks_per_entry': linkbacks_per_entry}
Example #19
0
from django.core.management.base import CommandError
from django.core.management.base import NoArgsCommand
from django.contrib.contenttypes.models import ContentType

from django_comments import get_model as get_comment_model

from zinnia import __version__
from zinnia.models.entry import Entry
from zinnia.models.author import Author
from zinnia.models.category import Category
from zinnia.managers import DRAFT, PUBLISHED
from zinnia.signals import disconnect_entry_signals
from zinnia.signals import disconnect_discussion_signals

gdata_service = None
Comment = get_comment_model()


class Command(NoArgsCommand):
    """
    Command object for importing a Blogger blog
    into Zinnia via Google's gdata API.
    """
    help = 'Import a Blogger blog into Zinnia.'

    option_list = NoArgsCommand.option_list + (
        make_option('--blogger-username',
                    dest='blogger_username',
                    default='',
                    help='The username to login to Blogger with'),
        make_option('--category-title',