aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-09-17 18:33:02 -0700
committerFuwn <[email protected]>2025-09-17 18:33:02 -0700
commit9fc08bd758c990530a0cbb4d0374c743ebd114dd (patch)
tree1863e734a1702f93ee276925a7dacca94dade2a9 /src
parentfeat(roleplay_limiter): Add weekend limit information to removal message (diff)
downloadumabot-9fc08bd758c990530a0cbb4d0374c743ebd114dd.tar.xz
umabot-9fc08bd758c990530a0cbb4d0374c743ebd114dd.zip
feat(rules): Add word_count rule
Diffstat (limited to 'src')
-rw-r--r--src/umabot/bot.py3
-rw-r--r--src/umabot/rules/__init__.py3
-rw-r--r--src/umabot/rules/word_count.py122
3 files changed, 126 insertions, 2 deletions
diff --git a/src/umabot/bot.py b/src/umabot/bot.py
index e905d86..63b4985 100644
--- a/src/umabot/bot.py
+++ b/src/umabot/bot.py
@@ -9,7 +9,7 @@ from socketserver import ThreadingMixIn
from loguru import logger
from .config import Config
-from .rules import SpamDetector, RoleplayLimiter, MediaRequiredRule
+from .rules import SpamDetector, RoleplayLimiter, MediaRequiredRule, WordCountRule
# from .rules import StaticRoleplayLimiter # Disabled by default - uncomment to use static limiting
@@ -77,6 +77,7 @@ class UmaBot:
self.rules = [
SpamDetector(config),
MediaRequiredRule(config), # Requires media for roleplay posts
+ WordCountRule(config), # Sends short roleplay posts to mod queue
RoleplayLimiter(config, self.subreddit) # Surge-based roleplay limiter (default)
# StaticRoleplayLimiter(config) # Uncomment to use static roleplay limiting instead
]
diff --git a/src/umabot/rules/__init__.py b/src/umabot/rules/__init__.py
index 6122075..a196093 100644
--- a/src/umabot/rules/__init__.py
+++ b/src/umabot/rules/__init__.py
@@ -4,5 +4,6 @@ from .base import Rule
from .spam_detector import SpamDetector
from .roleplay_limiter import RoleplayLimiter, StaticRoleplayLimiter
from .media_required import MediaRequiredRule
+from .word_count import WordCountRule
-__all__ = ["Rule", "SpamDetector", "RoleplayLimiter", "StaticRoleplayLimiter", "MediaRequiredRule"]
+__all__ = ["Rule", "SpamDetector", "RoleplayLimiter", "StaticRoleplayLimiter", "MediaRequiredRule", "WordCountRule"]
diff --git a/src/umabot/rules/word_count.py b/src/umabot/rules/word_count.py
new file mode 100644
index 0000000..08fdafd
--- /dev/null
+++ b/src/umabot/rules/word_count.py
@@ -0,0 +1,122 @@
+"""Word count rule for roleplay posts."""
+
+import praw.models
+from .base import Rule
+
+
+class WordCountRule(Rule):
+ """Sends roleplay posts under 100 words to mod queue."""
+
+ def __init__(self, config):
+ """Initialize the word count rule."""
+ super().__init__(config)
+ self.roleplay_flair = "Roleplay"
+ self.min_word_count = 100
+
+ def should_remove(self, submission: praw.models.Submission) -> bool:
+ """Check if a roleplay post is under 100 words and send to mod queue."""
+ if not submission.author:
+ return False
+
+ # Check if this is a roleplay post
+ if not self._is_roleplay_post(submission):
+ return False
+
+ # Check word count
+ word_count = self._count_words(submission)
+
+ if word_count < self.min_word_count:
+ # Send to mod queue instead of removing
+ self._send_to_mod_queue(submission)
+
+ self.logger.info(
+ f"Roleplay post by {submission.author.name} sent to mod queue "
+ f"for low word count ({word_count} words, minimum: {self.min_word_count}) "
+ f"(post ID: {submission.id})"
+ )
+ return True
+
+ return False
+
+ def get_removal_message(self, submission: praw.models.Submission) -> str:
+ """Get the word count removal message."""
+ # Send mod mail instead of posting a comment
+ self._send_mod_mail(submission)
+ return "" # Return empty string since we're not posting a comment
+
+ def _is_roleplay_post(self, submission: praw.models.Submission) -> bool:
+ """Check if a submission has the roleplay flair."""
+ try:
+ # Check link flair text
+ if hasattr(submission, 'link_flair_text') and submission.link_flair_text:
+ return submission.link_flair_text.lower() == self.roleplay_flair.lower()
+
+ # Check flair template ID (if using new flair system)
+ if hasattr(submission, 'link_flair_template_id') and submission.link_flair_template_id:
+ # You might need to map flair template IDs to names
+ # For now, we'll just check the text
+ pass
+
+ return False
+
+ except Exception as e:
+ self.logger.error(f"Error checking flair for submission {submission.id}: {e}")
+ return False
+
+ def _count_words(self, submission: praw.models.Submission) -> int:
+ """Count words in a submission."""
+ try:
+ text = ""
+
+ # Get text from different submission types
+ if submission.is_self:
+ text = submission.selftext or ""
+ elif hasattr(submission, 'title'):
+ text = submission.title or ""
+
+ # Clean and count words
+ if text:
+ # Remove extra whitespace and split into words
+ words = text.strip().split()
+ return len(words)
+
+ return 0
+
+ except Exception as e:
+ self.logger.error(f"Error counting words for submission {submission.id}: {e}")
+ return 0
+
+ def _send_mod_mail(self, submission: praw.models.Submission) -> None:
+ """Send mod mail to the user about their low word count post."""
+ try:
+ word_count = self._count_words(submission)
+ username = submission.author.name if submission.author else "Unknown"
+
+ subject = f"Your roleplay post has been sent to mod queue for review"
+
+ message = (
+ f"Hello u/{username},\n\n"
+ f"Your roleplay post has been sent to the mod queue for review because it's under "
+ f"{self.min_word_count} words (currently {word_count} words). Roleplay posts in "
+ f"r/{self.config.subreddit_name} should be substantial and engaging.\n\n"
+ f"The moderators will review your post and may approve it if it meets quality standards.\n\n"
+ f"Post link: https://reddit.com{submission.permalink}\n\n"
+ f"Thank you for understanding!"
+ )
+
+ # Send mod mail to the user
+ submission.author.message(subject, message)
+ self.logger.info(f"Sent mod mail to {username} about low word count post {submission.id}")
+
+ except Exception as e:
+ self.logger.error(f"Error sending mod mail for submission {submission.id}: {e}")
+
+ def _send_to_mod_queue(self, submission: praw.models.Submission) -> None:
+ """Send a submission to the mod queue."""
+ try:
+ # Report the submission to send it to mod queue
+ submission.report("Low word count - under 100 words")
+ self.logger.info(f"Sent submission {submission.id} to mod queue for low word count")
+
+ except Exception as e:
+ self.logger.error(f"Error sending submission {submission.id} to mod queue: {e}")