Esempio n. 1
0
def check_can_add_moderator_with_username_to_community_with_name(user, username, community_name):
    if not user.is_administrator_of_community_with_name(community_name=community_name):
        raise ValidationError(
            _('Only administrators of the community can add other moderators.'),
        )

    Community = get_community_model()

    if Community.is_user_with_username_administrator_of_community_with_name(username=username,
                                                                            community_name=community_name):
        raise ValidationError(
            _('User is an administrator.'),
        )

    if Community.is_user_with_username_moderator_of_community_with_name(username=username,
                                                                        community_name=community_name):
        raise ValidationError(
            _('User is already a moderator.'),
        )

    if not Community.is_user_with_username_member_of_community_with_name(username=username,
                                                                         community_name=community_name):
        raise ValidationError(
            _('Can\'t make moderator a user that is not part of the community.'),
        )
Esempio n. 2
0
    def test_not_displays_private_communities(self):
        """
        should not display private communities and return 200
        """
        user = make_user()

        amount_of_communities = 5

        Community = get_community_model()

        for i in range(0, amount_of_communities):
            community_owner = make_user()
            community = make_community(creator=community_owner, type=Community.COMMUNITY_TYPE_PRIVATE)

        headers = make_authentication_headers_for_user(user)

        url = self._get_url()

        response = self.client.get(url, **headers, format='multipart')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        response_communities = json.loads(response.content)

        self.assertEqual(len(response_communities), 0)
Esempio n. 3
0
def check_can_invite_user_with_username_to_community_with_name(
        user, username, community_name):
    if not user.is_member_of_community_with_name(
            community_name=community_name):
        raise ValidationError(
            _('You can only invite people to a community you are member of.'),
        )

    if user.has_invited_user_with_username_to_community_with_name(
            username=username, community_name=community_name):
        raise ValidationError(
            _('You have already invited this user to join the community.'), )

    Community = get_community_model()

    if Community.is_user_with_username_member_of_community_with_name(
            username=username, community_name=community_name):
        raise ValidationError(
            _('The user is already part of the community.'), )

    if not Community.is_community_with_name_invites_enabled(
            community_name=community_name) and not (
                user.is_administrator_of_community_with_name(
                    community_name=community_name)
                or user.is_moderator_of_community_with_name(
                    community_name=community_name)):
        raise ValidationError(
            _('Invites for this community are not enabled. Only administrators & moderators can invite.'
              ), )
Esempio n. 4
0
def check_can_exclude_community(user, community):
    if user.has_excluded_community_with_name(community_name=community.name):
        raise ValidationError(
            _('You have already marked this community as excluded.'), )
    Community = get_community_model()
    if community.type == Community.COMMUNITY_TYPE_PRIVATE:
        raise ValidationError(
            _('Private communities are always excluded from top posts.'), )
Esempio n. 5
0
def check_can_get_posts_for_community_with_name(user, community_name):
    check_is_not_banned_from_community_with_name(user=user, community_name=community_name)
    Community = get_community_model()
    if Community.is_community_with_name_private(
            community_name=community_name) and not user.is_member_of_community_with_name(
        community_name=community_name):
        raise ValidationError(
            _('The community is private. You must become a member to retrieve its posts.'),
        )
Esempio n. 6
0
def check_can_get_community_with_name_members(user, community_name):
    check_is_not_banned_from_community_with_name(user=user, community_name=community_name)

    Community = get_community_model()

    if Community.is_community_with_name_private(community_name=community_name):
        if not user.is_member_of_community_with_name(community_name=community_name):
            raise ValidationError(
                _('Can\'t see the members of a private community.'),
            )
Esempio n. 7
0
    def _get_trending_posts_query(cls):
        trending_posts_query = Q(created__gte=timezone.now() - timedelta(
            hours=12))

        Community = get_community_model()

        trending_posts_sources_query = Q(community__type=Community.COMMUNITY_TYPE_PUBLIC)

        trending_posts_query.add(trending_posts_sources_query, Q.AND)

        return trending_posts_query
Esempio n. 8
0
def check_can_remove_moderator_with_username_to_community_with_name(
        user, username, community_name):
    if not user.is_administrator_of_community_with_name(
            community_name=community_name):
        raise ValidationError(
            _('Only administrators of the community can remove other moderators.'
              ), )

    Community = get_community_model()
    if not Community.is_user_with_username_moderator_of_community_with_name(
            username=username, community_name=community_name):
        raise ValidationError(_('User to remove is not an moderator.'), )
Esempio n. 9
0
    def get(self, request):
        query_params = request.query_params.dict()
        serializer = self.serializer_class(data=query_params)
        serializer.is_valid(raise_exception=True)

        data = serializer.data
        category_name = data.get('category')

        Community = get_community_model()
        communities = Community.get_trending_communities(category_name=category_name)[:30]

        posts_serializer = CommunitiesCommunitySerializer(communities, many=True, context={"request": request})
        return Response(posts_serializer.data, status=status.HTTP_200_OK)
Esempio n. 10
0
    def get_trending_posts(cls):
        Community = get_community_model()

        trending_posts_query = Q(created__gte=timezone.now() -
                                 timedelta(hours=12))

        trending_posts_sources_query = Q(
            community__type=Community.COMMUNITY_TYPE_PUBLIC)

        trending_posts_query.add(trending_posts_sources_query, Q.AND)

        return cls.objects.annotate(
            Count('reactions')).filter(trending_posts_query).order_by(
                '-reactions__count', '-created')
Esempio n. 11
0
def check_can_unban_user_with_username_from_community_with_name(
        user, username, community_name):
    if not user.is_administrator_of_community_with_name(
            community_name=community_name
    ) and not user.is_moderator_of_community_with_name(
            community_name=community_name):
        raise ValidationError(
            _('Only community administrators & moderators can ban community members.'
              ), )

    Community = get_community_model()
    if not Community.is_user_with_username_banned_from_community_with_name(
            username=username, community_name=community_name):
        raise ValidationError(_('Can\'t unban a not-banned user.'), )
Esempio n. 12
0
    def _get_trending_posts_query(cls):
        trending_posts_query = Q(created__gte=timezone.now() -
                                 timedelta(hours=12))

        Community = get_community_model()

        trending_posts_sources_query = Q(
            community__type=Community.COMMUNITY_TYPE_PUBLIC,
            status=cls.STATUS_PUBLISHED,
            is_closed=False,
            is_deleted=False)

        trending_posts_query.add(trending_posts_sources_query, Q.AND)

        return trending_posts_query
Esempio n. 13
0
def check_can_join_community_with_name(user, community_name):
    if user.is_banned_from_community_with_name(community_name):
        raise ValidationError(
            'You can\'t join a community you have been banned from.')

    if user.is_member_of_community_with_name(community_name):
        raise ValidationError(
            _('You are already a member of the community.'), )

    Community = get_community_model()
    if Community.is_community_with_name_private(community_name=community_name):
        if not user.is_invited_to_community_with_name(
                community_name=community_name):
            raise ValidationError(
                _('You are not invited to join this community.'), )
Esempio n. 14
0
    def create_post(cls,
                    creator,
                    circles_ids=None,
                    community_name=None,
                    image=None,
                    text=None,
                    video=None,
                    created=None,
                    is_draft=False):

        if not community_name and not circles_ids:
            raise ValidationError(
                _('A post requires circles or a community to be posted to.'))

        if community_name and circles_ids:
            raise ValidationError(
                _('A post cannot be posted both to a community and to circles.'
                  ))

        post = Post.objects.create(creator=creator, created=created)

        if image and video:
            raise ValidationError(
                _('A post must have an image or a video, not both.'))

        if text:
            post.text = text
            post.language = get_language_for_text(text)

        if image:
            post.add_media(file=image)
        elif video:
            post.add_media(file=video)

        if circles_ids:
            post.circles.add(*circles_ids)
        else:
            Community = get_community_model()
            post.community = Community.objects.get(name=community_name)

        # If on create we have a video or image, we automatically publish it
        # Backwards compat reasons.
        if not is_draft:
            post.publish()
        else:
            post.save()

        return post
Esempio n. 15
0
    def create_post(cls,
                    creator,
                    circles_ids=None,
                    community_name=None,
                    image=None,
                    text=None,
                    video=None,
                    created=None):

        if not community_name and not circles_ids:
            raise ValidationError(
                _('A post requires circles or a community to be posted to.'))

        if community_name and circles_ids:
            raise ValidationError(
                _('A post cannot be posted both to a community and to circles.'
                  ))

        if not text and not image and not video:
            raise ValidationError(_('A post requires text or an image/video.'))

        if image and video:
            raise ValidationError(
                _('A post must have an image or a video, not both.'))

        post = Post.objects.create(creator=creator, created=created)

        if text:
            post.text = text
            post.language = get_language_for_text(text)

        if image:
            PostImage.create_post_image(image=image, post_id=post.pk)

        if video:
            PostVideo.create_post_video(video=video, post_id=post.pk)

        if circles_ids:
            post.circles.add(*circles_ids)
        else:
            Community = get_community_model()
            post.community = Community.objects.get(name=community_name)

        post.save()

        return post
Esempio n. 16
0
    def unverify_with_actor_with_id(self, actor_id):
        current_verified = self.verified
        self.verified = False
        ModeratedObjectVerifiedChangedLog.create_moderated_object_verified_changed_log(
            changed_from=current_verified, changed_to=self.verified, moderated_object_id=self.pk, actor_id=actor_id)
        self.user_penalties.all().delete()
        content_object = self.content_object

        Post = get_post_model()
        PostComment = get_post_comment_model()
        Community = get_community_model()
        moderation_severity = self.category.severity

        if (isinstance(content_object, Post) or isinstance(content_object, PostComment) or isinstance(
                content_object,
                Community)) or (
                isinstance(content_object, User) and moderation_severity == ModerationCategory.SEVERITY_CRITICAL):
            content_object.unsoft_delete()
        self.save()
        content_object.save()
Esempio n. 17
0
def check_can_ban_user_with_username_from_community_with_name(user, username, community_name):
    if not user.is_administrator_of_community_with_name(
            community_name=community_name) and not user.is_moderator_of_community_with_name(
        community_name=community_name):
        raise ValidationError(
            _('Only community administrators & moderators can ban community members.'),
        )

    Community = get_community_model()
    if Community.is_user_with_username_banned_from_community_with_name(username=username,
                                                                       community_name=community_name):
        raise ValidationError(
            _('User is already banned'),
        )

    if Community.is_user_with_username_moderator_of_community_with_name(username=username,
                                                                        community_name=community_name) or Community.is_user_with_username_administrator_of_community_with_name(
        username=username, community_name=community_name):
        raise ValidationError(
            _('You can\'t ban moderators or administrators of the community'),
        )
Esempio n. 18
0
    def approve_with_actor_with_id(self, actor_id):
        Post = get_post_model()
        PostComment = get_post_comment_model()
        Community = get_community_model()
        User = get_user_model()

        content_object = self.content_object
        moderation_severity = self.category.severity
        current_status = self.status
        self.status = ModeratedObject.STATUS_APPROVED
        ModeratedObjectStatusChangedLog.create_moderated_object_status_changed_log(
            changed_from=current_status, changed_to=self.status, moderated_object_id=self.pk, actor_id=actor_id)

        if isinstance(content_object, Post) or \
                isinstance(content_object, PostComment) or \
                isinstance(content_object, Community):
            content_object.delete_notifications()

        if isinstance(content_object, User) and moderation_severity == ModerationCategory.SEVERITY_CRITICAL:
            content_object.delete_outgoing_notifications()

        self.save()
Esempio n. 19
0
def check_community_name_not_taken(user, community_name):
    Community = get_community_model()
    if Community.is_name_taken(community_name):
        raise ValidationError(
            _('A community with that name already exists.'), )
Esempio n. 20
0
    def verify_with_actor_with_id(self, actor_id):
        current_verified = self.verified
        self.verified = True
        ModeratedObjectVerifiedChangedLog.create_moderated_object_verified_changed_log(
            changed_from=current_verified, changed_to=self.verified, moderated_object_id=self.pk, actor_id=actor_id)

        Post = get_post_model()
        Hashtag = get_hashtag_model()
        PostComment = get_post_comment_model()
        Community = get_community_model()
        User = get_user_model()
        ModerationPenalty = get_moderation_penalty_model()

        content_object = self.content_object
        moderation_severity = self.category.severity
        penalty_targets = None

        if self.is_approved():
            if isinstance(content_object, User):
                penalty_targets = [content_object]
            elif isinstance(content_object, Post):
                penalty_targets = [content_object.creator]
            elif isinstance(content_object, PostComment):
                penalty_targets = [content_object.commenter]
            elif isinstance(content_object, Community):
                penalty_targets = content_object.get_staff_members()
            elif isinstance(content_object, ModeratedObject):
                penalty_targets = content_object.get_reporters()
            elif isinstance(content_object, Hashtag):
                penalty_targets = []

            for penalty_target in penalty_targets:
                duration_of_penalty = None
                penalties_count = penalty_target.count_moderation_penalties_for_moderation_severity(
                    moderation_severity=moderation_severity) + 1

                if moderation_severity == ModerationCategory.SEVERITY_CRITICAL:
                    duration_of_penalty = timezone.timedelta(weeks=5000)
                elif moderation_severity == ModerationCategory.SEVERITY_HIGH:
                    duration_of_penalty = timezone.timedelta(days=penalties_count ** 4)
                elif moderation_severity == ModerationCategory.SEVERITY_MEDIUM:
                    duration_of_penalty = timezone.timedelta(hours=penalties_count ** 3)
                elif moderation_severity == ModerationCategory.SEVERITY_LOW:
                    duration_of_penalty = timezone.timedelta(minutes=penalties_count ** 2)

                moderation_expiration = timezone.now() + duration_of_penalty

                ModerationPenalty.create_suspension_moderation_penalty(moderated_object=self,
                                                                       user_id=penalty_target.pk,
                                                                       expiration=moderation_expiration)

            if (isinstance(content_object, Post) or isinstance(content_object, PostComment) or isinstance(
                    content_object,
                    Community)) or (
                    isinstance(content_object, User) and moderation_severity == ModerationCategory.SEVERITY_CRITICAL):
                content_object.soft_delete()

                if moderation_severity == ModerationCategory.SEVERITY_CRITICAL and isinstance(content_object, Post):
                    # We have hashes
                    content_object.delete_media()

        content_object.save()
        self.save()
Esempio n. 21
0
    def __init__(self):
        PostReaction = get_post_reaction_model()
        PostComment = get_post_comment_model()
        User = get_user_model()
        Emoji = get_emoji_model()
        Post = get_post_model()
        CommunityInvite = get_community_invite_model()
        Community = get_community_model()

        class NotificationUserSerializer(serializers.ModelSerializer):
            class Meta:
                model = User
                fields = (
                    'id',
                    'username',
                )

        class NotificationEmojiSerializer(serializers.ModelSerializer):
            class Meta:
                model = Emoji
                fields = (
                    'id',
                    'keyword',
                )

        class NotificationPostSerializer(serializers.ModelSerializer):
            class Meta:
                model = Post
                fields = (
                    'id',
                    'uuid',
                )

        class NotificationPostReactionSerializer(serializers.ModelSerializer):
            reactor = NotificationUserSerializer()
            emoji = NotificationEmojiSerializer()
            post = NotificationPostSerializer()

            class Meta:
                model = PostReaction
                fields = ('id', 'reactor', 'emoji', 'post')

        self.NotificationPostReactionSerializer = NotificationPostReactionSerializer

        class NotificationCommunitySerializer(serializers.ModelSerializer):
            class Meta:
                model = Community
                fields = ('id', 'name', 'title')

        class NotificationCommunityInviteSerializer(serializers.ModelSerializer
                                                    ):
            creator = NotificationUserSerializer()
            invited_user = NotificationUserSerializer()
            community = NotificationCommunitySerializer()

            class Meta:
                model = CommunityInvite
                fields = ('id', 'creator', 'invited_user', 'community')

        self.NotificationCommunityInviteSerializer = NotificationCommunityInviteSerializer

        class NotificationPostCommentSerializer(serializers.ModelSerializer):
            commenter = NotificationUserSerializer()
            post = NotificationPostSerializer()

            class Meta:
                model = PostComment
                fields = ('id', 'commenter', 'post')

        self.NotificationPostCommentSerializer = NotificationPostCommentSerializer

        class NotificationPostCommentReplySerializer(
                serializers.ModelSerializer):
            commenter = NotificationUserSerializer()
            post = NotificationPostSerializer()

            class Meta:
                model = PostComment
                fields = ('id', 'commenter', 'post')

        self.NotificationPostCommentReplySerializer = NotificationPostCommentReplySerializer

        class FollowNotificationSerializer(serializers.Serializer):
            following_user = NotificationUserSerializer()

        self.FollowNotificationSerializer = FollowNotificationSerializer

        class ConnectionRequestNotificationSerializer(serializers.Serializer):
            connection_requester = NotificationUserSerializer()

        self.ConnectionRequestNotificationSerializer = ConnectionRequestNotificationSerializer
Esempio n. 22
0
def community_name_exists(community_name):
    Community = get_community_model()
    if not Community.objects.filter(name=community_name).exists():
        raise NotFound(_('No community with the provided name exists.'), )
Esempio n. 23
0
def community_name_not_taken_validator(community_name):
    Community = get_community_model()
    if Community.is_name_taken(community_name):
        raise ValidationError(_('Community name already taken.'), )
Esempio n. 24
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)
Esempio n. 25
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()
Esempio n. 26
0
def make_only_public_community_posts_query():
    Community = get_community_model()
    return Q(community__type=Community.COMMUNITY_TYPE_PUBLIC, )
Esempio n. 27
0
def community_name_exists(community_name):
    Community = get_community_model()
    if not Community.community_with_name_exists(community_name=community_name):
        raise NotFound(
            _('No community with the provided name exists.'),
        )