Esempio n. 1
0
def toggle_spam(request, post, **kwargs):
    """
    Toggles spam status on post based on a status
    """

    url = post.get_absolute_url()

    # Moderators may only be suspended by admins (TODO).
    if post.author.profile.is_moderator and post.spam in (Post.DEFAULT,
                                                          Post.NOT_SPAM):
        messages.warning(
            request, "cannot toggle spam on a post created by a moderator")
        return url

    # The user performing the action.
    user = request.user

    # Drop the cache for the post.
    delete_post_cache(post)

    # Current state of the toggle.
    if post.is_spam:
        Post.objects.filter(id=post.id).update(spam=Post.NOT_SPAM,
                                               status=Post.OPEN)
    else:
        Post.objects.filter(id=post.id).update(spam=Post.SPAM,
                                               status=Post.CLOSED)

    # Refetch up to date state of the post.
    post = Post.objects.filter(id=post.id).get()

    # Set the state for the user (only non moderators are affected)
    state = Profile.SUSPENDED if post.is_spam else Profile.NEW

    # Apply the user change.
    change_user_state(mod=user, target=post.author, state=state)

    # Generate logging messages.
    if post.is_spam:
        text = f"marked post as spam"
    else:
        text = f"restored post from spam"

        # Set indexed flag to False, so it's removed from spam index
        Post.objects.filter(id=post.id).update(indexed=False)

    # Set a logging message.
    messages.success(request, text)

    # Submit the log into the database.
    auth.db_logger(user=user,
                   action=Log.MODERATE,
                   target=post.author,
                   text=text,
                   post=post)

    url = post.get_absolute_url()

    return url
Esempio n. 2
0
def spam_check(uid):
    from biostar.forum.models import Post, Log, delete_post_cache
    from biostar.accounts.models import User, Profile
    from biostar.forum.auth import db_logger

    post = Post.objects.filter(uid=uid).first()
    author = post.author

    # Automated spam disabled in for trusted user
    if author.profile.trusted or author.profile.score > 50:
        return

    # Classify spam only if we have not done it yet.
    if post.spam != Post.DEFAULT:
        return

    # Drop the cache for the post.
    delete_post_cache(post)

    try:
        from biostar.utils import spamlib

        if not os.path.isfile(settings.SPAM_MODEL):
            spamlib.build_model(fname=settings.SPAM_DATA,
                                model=settings.SPAM_MODEL)

        # Classify the content.
        flag = spamlib.classify_content(post.content,
                                        model=settings.SPAM_MODEL)

        # Another process may have already classified it as spam.
        check = Post.objects.filter(uid=post.uid).first()
        if check and check.spam == Post.SPAM:
            return

        ## Links in title usually mean spam.
        spam_words = ["http://", "https://"]
        for word in spam_words:
            flag = flag or (word in post.title)

        if flag:

            Post.objects.filter(uid=post.uid).update(spam=Post.SPAM,
                                                     status=Post.CLOSED)

            # Get the first admin.
            user = User.objects.filter(
                is_superuser=True).order_by("pk").first()

            create_messages(template="messages/spam-detected.md",
                            extra_context=dict(post=post),
                            user_ids=[post.author.id])

            spam_count = Post.objects.filter(spam=Post.SPAM,
                                             author=author).count()

            db_logger(user=user,
                      action=Log.CLASSIFY,
                      target=post.author,
                      text=f"classified the post as spam",
                      post=post)

            if spam_count > 1 and low_trust(post.author):
                # Suspend the user
                Profile.objects.filter(user=author).update(
                    state=Profile.SUSPENDED)
                db_logger(user=user,
                          action=Log.MODERATE,
                          text=f"suspended",
                          target=post.author)

    except Exception as exc:
        print(exc)
        logger.error(exc)

    return False