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
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