aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-09-15 23:40:34 -0700
committerFuwn <[email protected]>2025-09-15 23:40:34 -0700
commit699966bd2d26683dc20c6d0bd42598f54d786af0 (patch)
tree4b2aaa7d26e0505e52f78a2166e7bfe3de57db0c /src
parentfeat(roleplay_limiter): Add system notice to removal message (diff)
downloadumabot-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.py5
-rw-r--r--src/umabot/rules/spam_detector.py51
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
]