Beispiel #1
0
    def count_replies_with_user(self, user):
        # Count replies excluding users blocked by authenticated user
        count_query = ~Q(
            Q(commenter__blocked_by_users__blocker_id=user.pk)
            | Q(commenter__user_blocks__blocked_user_id=user.pk))

        if self.post.community:
            if not user.is_staff_of_community_with_name(
                    community_name=self.post.community.name):
                # Dont retrieve comments except from staff members
                blocked_users_query_staff_members = Q(
                    commenter__communities_memberships__community_id=self.post.
                    community.pk)
                blocked_users_query_staff_members.add(
                    Q(commenter__communities_memberships__is_administrator=True
                      )
                    | Q(commenter__communities_memberships__is_moderator=True),
                    Q.AND)

                count_query.add(~blocked_users_query_staff_members, Q.AND)

            # Don't count items that have been reported and approved by community moderators
            ModeratedObject = get_moderated_object_model()
            count_query.add(
                ~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED),
                Q.AND)

        # Dont count soft deleted items
        count_query.add(Q(is_deleted=False), Q.AND)

        # Dont count items we have reported
        count_query.add(~Q(moderated_object__reports__reporter_id=user.pk),
                        Q.AND)

        return self.replies.filter(count_query).count()
Beispiel #2
0
    def count_replies_with_user(self, user):
        count_query = Q()

        if self.post.community_id:
            # Don't count items that have been reported and approved by community moderators
            ModeratedObject = get_moderated_object_model()
            count_query.add(~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED), Q.AND)

        # Dont count soft deleted items
        count_query.add(Q(is_deleted=False), Q.AND)

        # Dont count items we have reported
        count_query.add(~Q(moderated_object__reports__reporter_id=user.pk), Q.AND)

        return self.replies.filter(count_query).count()
Beispiel #3
0
    def count_comments_with_user(self, user):
        # Only count top level comments
        count_query = Q(parent_comment__isnull=True)

        if self.community:
            # Don't count items that have been reported and approved by community moderators
            ModeratedObject = get_moderated_object_model()
            count_query.add(~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED), Q.AND)

        # Dont count soft deleted items
        count_query.add(Q(is_deleted=False), Q.AND)

        # Dont count items we have reported
        count_query.add(~Q(moderated_object__reports__reporter_id=user.pk), Q.AND)

        return self.comments.filter(count_query).count()
Beispiel #4
0
 def count_pending_moderated_objects(self):
     ModeratedObject = get_moderated_object_model()
     return self.moderated_objects.filter(status=ModeratedObject.STATUS_PENDING).count()
Beispiel #5
0
def curate_top_posts():
    """
    Curates the top posts.
    This job should be scheduled to be run every n hours.
    """
    Post = get_post_model()
    Community = get_community_model()
    PostComment = get_post_comment_model()
    ModeratedObject = get_moderated_object_model()
    TopPost = get_top_post_model()
    logger.info('Processing top posts at %s...' % timezone.now())

    top_posts_community_query = Q(top_post__isnull=True)
    top_posts_community_query.add(
        Q(community__isnull=False,
          community__type=Community.COMMUNITY_TYPE_PUBLIC), Q.AND)
    top_posts_community_query.add(
        Q(is_closed=False, is_deleted=False, status=Post.STATUS_PUBLISHED),
        Q.AND)
    top_posts_community_query.add(
        ~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED), Q.AND)

    top_posts_criteria_query = Q(total_comments_count__gte=settings.MIN_UNIQUE_TOP_POST_COMMENTS_COUNT) | \
                               Q(reactions_count__gte=settings.MIN_UNIQUE_TOP_POST_REACTIONS_COUNT)

    posts_select_related = 'community'
    posts_prefetch_related = ('comments__commenter', 'reactions__reactor')
    posts_only = ('id', 'status', 'is_deleted', 'is_closed', 'community__type')

    posts = Post.objects. \
        select_related(posts_select_related). \
        prefetch_related(*posts_prefetch_related). \
        only(*posts_only). \
        filter(top_posts_community_query). \
        annotate(total_comments_count=Count('comments__commenter_id'),
                 reactions_count=Count('reactions__reactor_id')). \
        filter(top_posts_criteria_query)

    top_posts_objects = []
    total_checked_posts = 0
    total_curated_posts = 0

    for post in _chunked_queryset_iterator(posts, 1000):
        total_checked_posts = total_checked_posts + 1
        if not post.reactions_count >= settings.MIN_UNIQUE_TOP_POST_REACTIONS_COUNT:
            unique_comments_count = PostComment.objects.filter(post=post). \
                values('commenter_id'). \
                annotate(user_comments_count=Count('commenter_id')).count()

            if unique_comments_count >= settings.MIN_UNIQUE_TOP_POST_COMMENTS_COUNT:
                top_post = _add_post_to_top_post(post=post)
                if top_post is not None:
                    top_posts_objects.append(top_post)
        else:
            top_post = _add_post_to_top_post(post=post)
            if top_post is not None:
                top_posts_objects.append(top_post)

        if len(top_posts_objects) > 1000:
            TopPost.objects.bulk_create(top_posts_objects)
            total_curated_posts += len(top_posts_objects)
            top_posts_objects = []

    if len(top_posts_objects) > 0:
        total_curated_posts += len(top_posts_objects)
        TopPost.objects.bulk_create(top_posts_objects)

    return 'Checked: %d. Curated: %d' % (total_checked_posts,
                                         total_curated_posts)
Beispiel #6
0
def clean_top_posts():
    """
    Cleans up top posts, that no longer meet the criteria.
    """
    Post = get_post_model()
    Community = get_community_model()
    TopPost = get_top_post_model()
    PostComment = get_post_comment_model()
    ModeratedObject = get_moderated_object_model()

    # if any of these is true, we will remove the top post
    top_posts_community_query = Q(
        post__community__type=Community.COMMUNITY_TYPE_PRIVATE)
    top_posts_community_query.add(Q(post__is_closed=True), Q.OR)
    top_posts_community_query.add(Q(post__is_deleted=True), Q.OR)
    top_posts_community_query.add(Q(post__status=Post.STATUS_DRAFT), Q.OR)
    top_posts_community_query.add(Q(post__status=Post.STATUS_PROCESSING), Q.OR)
    top_posts_community_query.add(
        Q(post__moderated_object__status=ModeratedObject.STATUS_APPROVED),
        Q.OR)

    # counts less than minimum
    top_posts_criteria_query = Q(total_comments_count__lt=settings.MIN_UNIQUE_TOP_POST_COMMENTS_COUNT) & \
                               Q(reactions_count__lt=settings.MIN_UNIQUE_TOP_POST_REACTIONS_COUNT)

    posts_select_related = 'post__community'
    posts_prefetch_related = ('post__comments__commenter',
                              'post__reactions__reactor')
    posts_only = ('post__id', 'post__status', 'post__is_deleted',
                  'post__is_closed', 'post__community__type')

    direct_removable_top_posts = TopPost.objects.select_related(posts_select_related). \
        prefetch_related(*posts_prefetch_related). \
        only(*posts_only). \
        filter(top_posts_community_query). \
        annotate(total_comments_count=Count('post__comments__commenter_id'),
                 reactions_count=Count('post__reactions__reactor_id')). \
        filter(top_posts_criteria_query)

    # bulk delete all that definitely dont meet the criteria anymore
    direct_removable_top_posts.delete()

    # Now we need to only check the ones where the unique comments count might have dropped,
    # while all other criteria is fine

    top_posts_community_query = Q(
        post__community__isnull=False,
        post__community__type=Community.COMMUNITY_TYPE_PUBLIC)
    top_posts_community_query.add(
        Q(post__is_closed=False,
          post__is_deleted=False,
          post__status=Post.STATUS_PUBLISHED), Q.AND)
    top_posts_community_query.add(
        ~Q(post__moderated_object__status=ModeratedObject.STATUS_APPROVED),
        Q.AND)

    top_posts_criteria_query = Q(total_comments_count__gte=settings.MIN_UNIQUE_TOP_POST_COMMENTS_COUNT) | \
                               Q(reactions_count__gte=settings.MIN_UNIQUE_TOP_POST_REACTIONS_COUNT)

    top_posts = TopPost.objects.select_related(posts_select_related). \
        prefetch_related(*posts_prefetch_related). \
        only(*posts_only). \
        filter(top_posts_community_query). \
        annotate(total_comments_count=Count('post__comments__commenter_id'),
                 reactions_count=Count('post__reactions__reactor_id')). \
        filter(top_posts_criteria_query)

    delete_ids = []

    for top_post in _chunked_queryset_iterator(top_posts, 1000):
        if not top_post.reactions_count >= settings.MIN_UNIQUE_TOP_POST_REACTIONS_COUNT:
            unique_comments_count = PostComment.objects.filter(post=top_post.post). \
                values('commenter_id'). \
                annotate(user_comments_count=Count('commenter_id')).count()

            if unique_comments_count < settings.MIN_UNIQUE_TOP_POST_COMMENTS_COUNT:
                delete_ids.append(top_post.pk)

    # bulk delete ids
    TopPost.objects.filter(id__in=delete_ids).delete()
Beispiel #7
0
def get_posts_for_user_collection(target_user,
                                  source_user,
                                  posts_only=None,
                                  posts_prefetch_related=None,
                                  max_id=None,
                                  min_id=None,
                                  include_community_posts=False):
    Post = get_post_model()

    posts_collection_manager = Post.objects

    if posts_prefetch_related:
        posts_collection_manager = posts_collection_manager.prefetch_related(
            *posts_prefetch_related)

    if posts_only:
        posts_collection_manager = posts_collection_manager.only(*posts_only)

    id_boundary_query = None

    if max_id:
        id_boundary_query = make_only_posts_with_max_id(max_id=max_id)
    elif min_id:
        id_boundary_query = make_only_posts_with_min_id(min_id=min_id)

    query = Q(
        # Created by the target user
        creator__username=target_user.username,
        # Not closed
        is_closed=False,
        # Not deleted
        is_deleted=False,
        # Published
        status=Post.STATUS_PUBLISHED,
    )

    posts_query = make_circles_posts_query_for_user(user=source_user)

    if include_community_posts:
        posts_query.add(make_community_posts_query_for_user(user=source_user),
                        Q.OR)

    query.add(posts_query, Q.AND)

    if id_boundary_query:
        query.add(id_boundary_query, Q.AND)

    ModeratedObject = get_moderated_object_model()

    posts_visibility_exclude_query = Q(
        # Reported posts
        Q(moderated_object__reports__reporter_id=source_user.pk) |
        # Approved reported posts
        Q(moderated_object__status=ModeratedObject.STATUS_APPROVED) |
        # Posts of users we blocked or that have blocked us
        Q(creator__blocked_by_users__blocker_id=source_user.pk)
        | Q(creator__user_blocks__blocked_user_id=source_user.pk) |
        # Posts of communities banned from
        Q(community__banned_users__id=source_user.pk))

    return posts_collection_manager.filter(query).exclude(
        posts_visibility_exclude_query).distinct()
Beispiel #8
0
def make_exclude_reported_and_approved_hashtags_query():
    ModeratedObject = get_moderated_object_model()
    return ~Q(moderated_object__status=ModeratedObject.STATUS_APPROVED)