diff options
| author | Fuwn <[email protected]> | 2025-09-15 23:40:34 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-09-15 23:40:34 -0700 |
| commit | 699966bd2d26683dc20c6d0bd42598f54d786af0 (patch) | |
| tree | 4b2aaa7d26e0505e52f78a2166e7bfe3de57db0c /src | |
| parent | feat(roleplay_limiter): Add system notice to removal message (diff) | |
| download | umabot-699966bd2d26683dc20c6d0bd42598f54d786af0.tar.xz umabot-699966bd2d26683dc20c6d0bd42598f54d786af0.zip | |
feat(spam_detector): Use UTC time as limit reset time
Diffstat (limited to 'src')
| -rw-r--r-- | src/umabot/config.py | 5 | ||||
| -rw-r--r-- | src/umabot/rules/spam_detector.py | 51 |
2 files changed, 36 insertions, 20 deletions
diff --git a/src/umabot/config.py b/src/umabot/config.py index f86bed5..7f635f1 100644 --- a/src/umabot/config.py +++ b/src/umabot/config.py @@ -23,7 +23,6 @@ class Config: subreddit_name: str # Bot messages - spam_message: str roleplay_message: str # Bot settings @@ -49,10 +48,6 @@ class Config: password=os.getenv("REDDIT_PASSWORD", ""), user_agent=os.getenv("REDDIT_USER_AGENT", "UmaBot/0.1.0"), subreddit_name=os.getenv("SUBREDDIT_NAME", ""), - spam_message=os.getenv( - "SPAM_MESSAGE", - "Your post has been removed for posting too frequently. Please wait before posting again." - ), roleplay_message=os.getenv( "ROLEPLAY_MESSAGE", "Your post has been removed. Only one roleplay post is allowed per user." diff --git a/src/umabot/rules/spam_detector.py b/src/umabot/rules/spam_detector.py index 4411fc8..3fccf0a 100644 --- a/src/umabot/rules/spam_detector.py +++ b/src/umabot/rules/spam_detector.py @@ -1,7 +1,7 @@ """Spam detection rule for limiting posts per user per day.""" import time -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from typing import Dict, List import praw.models from .base import Rule @@ -13,9 +13,8 @@ class SpamDetector(Rule): def __init__(self, config): """Initialize the spam detector.""" super().__init__(config) - self.user_posts: Dict[str, List[float]] = {} + self.user_posts: Dict[str, List[datetime]] = {} self.max_posts = config.max_posts_per_day - self.time_window = config.post_limit_window_hours * 60 * 60 # Convert hours to seconds def should_remove(self, submission: praw.models.Submission) -> bool: """Check if a user has posted too frequently.""" @@ -23,24 +22,24 @@ class SpamDetector(Rule): return False username = submission.author.name - current_time = time.time() + current_utc = datetime.now(timezone.utc) - # Clean old posts from tracking - self._clean_old_posts(username, current_time) + # Clean old posts from tracking (remove posts from previous days) + self._clean_old_posts(username, current_utc) - # Count current posts in the time window + # Count current posts in today's UTC day if username not in self.user_posts: self.user_posts[username] = [] post_count = len(self.user_posts[username]) # Add current post to tracking - self.user_posts[username].append(current_time) + self.user_posts[username].append(current_utc) # Check if this post exceeds the limit if post_count >= self.max_posts: self.logger.info( - f"User {username} has posted {post_count + 1} times in {self.config.post_limit_window_hours} hours " + f"User {username} has posted {post_count + 1} times today (UTC) " f"(limit: {self.max_posts})" ) return True @@ -48,16 +47,38 @@ class SpamDetector(Rule): return False def get_removal_message(self, submission: praw.models.Submission) -> str: - """Get the spam removal message.""" - return self.config.spam_message + """Get the spam removal message with time remaining until limit expires.""" + username = submission.author.name if submission.author else "Unknown" + current_utc = datetime.now(timezone.utc) + + # Calculate time until next UTC day (midnight UTC) + next_day = current_utc.replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1) + time_remaining = next_day - current_utc + + # Format time remaining + hours = int(time_remaining.total_seconds() // 3600) + minutes = int((time_remaining.total_seconds() % 3600) // 60) + + if hours > 0: + time_str = f"{hours}h {minutes}m" + else: + time_str = f"{minutes}m" + + return ( + f"Your post has been removed. Users in r/{self.config.subreddit_name} can submit up to " + f"{self.max_posts} posts per day (UTC). Your limit resets in {time_str}." + ) - def _clean_old_posts(self, username: str, current_time: float) -> None: - """Remove posts older than the time window from tracking.""" + def _clean_old_posts(self, username: str, current_utc: datetime) -> None: + """Remove posts from previous UTC days from tracking.""" if username not in self.user_posts: return - cutoff_time = current_time - self.time_window + # Get start of current UTC day + today_start = current_utc.replace(hour=0, minute=0, second=0, microsecond=0) + + # Keep only posts from today self.user_posts[username] = [ post_time for post_time in self.user_posts[username] - if post_time > cutoff_time + if post_time >= today_start ] |