Updates to docker configs

This commit is contained in:
2026-03-05 17:07:19 +00:00
parent 5af4311719
commit 5dc2098581
3 changed files with 107 additions and 55 deletions

View File

@@ -1,27 +1,36 @@
# Bot authentication and global settings
username = ""
password = ""
client_id = ""
client_secret = ""
user_agent = "Flair Timer Comment Bot"
#Subreddits
subreddit = "" # "INEEEEDIT" "Ofcoursethatsathing" "All"
flair_text = "Waiting for OP" # Case Sensitive
interval = 30 # How often should the bot scan the subreddit for these posts, in seconds. Higher = slower/less accurate/save resources, lower = faster/more accurate/use more resources.
hours = 48 # How many hours must the flair been on the post to send the notification
searchlimit = 600 # Max: 1000, this should only be limited to save on resources. The bot sorts by new and if it isn't catching posts that are being changed to the flair simply because they are too old (say the 301st post on the subreddit is changed to the flair) then increase this limit.
# Comment message to post on old posts
comment_message = ""
# Subreddit to monitor
subreddit = "" # e.g. "INEEEEDIT", "Ofcoursethatsathing", "All"
# Whether the bot should lock the post after posting the comment (True/False)
# Default is False to avoid accidental locking; set to True to enable locking.
lock_post = False
# How often should the bot scan the subreddit for these posts, in seconds
interval = 30
# Whether the distinguished comment should be stickied (True/False)
# Some subreddits may require `True` to keep moderator comments visible.
distinguish_sticky = False
# Max posts to search (for performance)
searchlimit = 600
# Multiple flair time configs
# Each entry can have: flair_text, hours, comment_message, lock_post, distinguish_sticky
flair_times = [
{
"flair_text": "Waiting for OP", # Case Sensitive
"hours": 48, # How many hours must the flair been on the post to send the notification
"comment_message": "This post has had the 'Waiting for OP' flair for 48 hours.",
"lock_post": False,
"distinguish_sticky": False
},
# Add more configs as needed
# {
# "flair_text": "Needs Info",
# "hours": 24,
# "comment_message": "This post has had the 'Needs Info' flair for 24 hours.",
# "lock_post": True,
# "distinguish_sticky": True
# },
]

View File

@@ -7,11 +7,12 @@ CLIENT_ID=your_client_id
CLIENT_SECRET=your_client_secret
USER_AGENT=Flair Timer Comment Bot
# Subreddit to monitor
SUBREDDIT=your_subreddit
FLAIR_TEXT=Waiting for OP
INTERVAL=30
HOURS=48
SEARCHLIMIT=600
COMMENT_MESSAGE=Your comment message here
LOCK_POST=False
DISTINGUISH_STICKY=False
# Multiple flair configs as JSON string
# Example:
# FLAIR_TIMES_JSON=[{"flair_text": "Waiting for OP", "hours": 48, "comment_message": "Waiting for OP for 48 hours.", "lock_post": false, "distinguish_sticky": false}, {"flair_text": "Needs Info", "hours": 24, "comment_message": "Needs Info for 24 hours.", "lock_post": true, "distinguish_sticky": true}]
FLAIR_TIMES_JSON=[{"flair_text": "Waiting for OP", "hours": 48, "comment_message": "Waiting for OP for 48 hours.", "lock_post": false, "distinguish_sticky": false}]

View File

@@ -7,13 +7,26 @@ import time
# Helper to get env var or default
def env_or_default(var, default):
return os.environ.get(var, default)
# Helper to get flair_times from env
def get_flair_times_from_env():
flair_times_json = os.environ.get("FLAIR_TIMES_JSON", "")
if flair_times_json:
try:
return json.loads(flair_times_json)
except Exception as e:
print(f"Could not parse FLAIR_TIMES_JSON: {e}")
return None
# Create config/config.py from environment if missing or empty
default_config_path = os.path.join('config', 'config.py')
def write_config_from_env():
os.makedirs('config', exist_ok=True)
flair_times = get_flair_times_from_env()
with open(default_config_path, 'w') as f:
f.write(
f'username = "{env_or_default("USERNAME", "")}"\n'
@@ -23,14 +36,23 @@ def write_config_from_env():
f'user_agent = "{env_or_default("USER_AGENT", "Flair Timer Comment Bot")}"\n'
'\n'
f'subreddit = "{env_or_default("SUBREDDIT", "")}"\n'
f'flair_text = "{env_or_default("FLAIR_TEXT", "Waiting for OP")}"\n'
f'interval = {env_or_default("INTERVAL", "30")}\n'
f'hours = {env_or_default("HOURS", "48")}\n'
f'searchlimit = {env_or_default("SEARCHLIMIT", "600")}\n'
f'comment_message = "{env_or_default("COMMENT_MESSAGE", "")}"\n'
f'lock_post = {env_or_default("LOCK_POST", "False")}\n'
f'distinguish_sticky = {env_or_default("DISTINGUISH_STICKY", "False")}\n'
)
# Write flair_times as a Python list
if flair_times:
f.write(f'flair_times = {json.dumps(flair_times)}\n')
else:
# Fallback to single flair config from env vars
f.write('flair_times = [\n')
f.write(' {\n')
f.write(f' "flair_text": "{env_or_default("FLAIR_TEXT", "Waiting for OP")}",\n')
f.write(f' "hours": {env_or_default("HOURS", "48")},\n')
f.write(f' "comment_message": "{env_or_default("COMMENT_MESSAGE", "")}",\n')
f.write(f' "lock_post": {env_or_default("LOCK_POST", "False")},\n')
f.write(f' "distinguish_sticky": {env_or_default("DISTINGUISH_STICKY", "False")}\n')
f.write(' }\n')
f.write(']\n')
print(f"Configuration file auto-populated from environment variables at {default_config_path}.")
# Check if config file exists and is non-empty, else generate from env
@@ -59,60 +81,80 @@ def authentication():
print ("Authenticated as {}.".format(reddit.user.me()))
return reddit
def main(reddit, posts: dict):
def main(reddit, all_posts: dict):
# all_posts structure: {flair_text: {submission_id: timestamp}}
while True:
for submission in reddit.subreddit(config.subreddit).new(limit=config.searchlimit):
if not submission.saved:
if submission.id not in posts.keys() and submission.link_flair_text == config.flair_text:
posts[submission.id] = time.time()
print(f"Post {submission} has been flaired {config.flair_text}")
if submission.id in posts.keys() and submission.link_flair_text != config.flair_text:
posts.pop(submission.id)
print(f"Post {submission} has been unflaired {config.flair_text}")
for submission in posts:
if time.time() > posts[submission] + (config.hours * 60 * 60):
posts.pop(submission)
reddit.submission(submission).save()
# Optionally lock the post if configured
if getattr(config, 'lock_post', False):
for flair_cfg in config.flair_times:
flair_text = flair_cfg["flair_text"]
hours = flair_cfg["hours"]
comment_message = flair_cfg["comment_message"]
lock_post = flair_cfg.get("lock_post", False)
distinguish_sticky = flair_cfg.get("distinguish_sticky", False)
# Ensure posts dict for this flair
posts = all_posts.setdefault(flair_text, {})
for submission in reddit.subreddit(config.subreddit).new(limit=config.searchlimit):
if not submission.saved:
if submission.id not in posts and submission.link_flair_text == flair_text:
posts[submission.id] = time.time()
print(f"Post {submission} has been flaired {flair_text}")
if submission.id in posts and submission.link_flair_text != flair_text:
posts.pop(submission.id)
print(f"Post {submission} has been unflaired {flair_text}")
expired = []
for submission_id, flair_time in posts.items():
if time.time() > flair_time + (hours * 60 * 60):
expired.append(submission_id)
for submission_id in expired:
posts.pop(submission_id)
subm = reddit.submission(submission_id)
subm.save()
if lock_post:
try:
reddit.submission(submission).mod.lock()
subm.mod.lock()
except Exception as e:
print(f"Could not lock submission: {e}")
comment = reddit.submission(submission).reply(body=config.comment_message)
comment = subm.reply(body=comment_message)
try:
sticky = getattr(config, 'distinguish_sticky', False)
if sticky:
if distinguish_sticky:
comment.mod.distinguish(how="yes", sticky=True)
else:
comment.mod.distinguish(how="yes")
print(f"Distinguished comment (sticky={sticky})")
print(f"Distinguished comment (sticky={distinguish_sticky})")
except Exception as e:
print(f"Could not distinguish comment: {e}")
print(f"Post {submission} has been flaired {config.flair_text} for {config.hours} hours, posted comment")
break
save_posts(posts)
print(f"Post {submission_id} has been flaired {flair_text} for {hours} hours, posted comment")
save_posts(all_posts)
time.sleep(config.interval)
def load_posts():
if not os.path.exists("config/posts.json"):
with open("config/posts.json", "w+") as file:
json.dump({}, file)
with open("config/posts.json", "r+") as file:
data = json.load(file)
# Ensure structure: {flair_text: {submission_id: timestamp}}
if not isinstance(data, dict):
return {}
return data
def save_posts(data):
with open('config/posts.json', 'w+') as file:
json.dump(data, file)
while True:
try:
posts = load_posts()
main(reddit = authentication(), posts = posts)
main(reddit=authentication(), all_posts=posts)
except Exception as e:
print(e)