Files
reddit_stock_analyzer/post_to_reddit.py

156 lines
5.5 KiB
Python

# post_to_reddit.py
import argparse
import os
import glob
from datetime import datetime, timezone
import praw
from dotenv import load_dotenv
from pathlib import Path
# --- CONFIGURATION ---
IMAGE_DIR = "images"
def get_reddit_instance():
"""Initializes and returns a PRAW Reddit instance using OAuth2 refresh token."""
env_path = Path(__file__).parent / ".env"
load_dotenv(dotenv_path=env_path)
client_id = os.getenv("REDDIT_CLIENT_ID")
client_secret = os.getenv("REDDIT_CLIENT_SECRET")
user_agent = os.getenv("REDDIT_USER_AGENT")
refresh_token = os.getenv("REDDIT_REFRESH_TOKEN")
if not all([client_id, client_secret, user_agent, refresh_token]):
print(
"Error: Reddit API credentials (including REDDIT_REFRESH_TOKEN) must be set in .env file."
)
return None
return praw.Reddit(
client_id=client_id,
client_secret=client_secret,
user_agent=user_agent,
refresh_token=refresh_token,
)
def find_latest_image(pattern):
"""Finds the most recent file in the IMAGE_DIR that matches a given pattern."""
try:
search_path = os.path.join(IMAGE_DIR, pattern)
list_of_files = glob.glob(search_path)
if not list_of_files:
return None
# The latest file will be the one with the highest modification time
latest_file = max(list_of_files, key=os.path.getmtime)
return latest_file
except Exception as e:
print(f"Error finding image file: {e}")
return None
def get_flair_id(subreddit, flair_text):
"""
Attempts to find the ID of a flair by its text.
Returns the ID string or None if not found or an error occurs.
"""
if not flair_text:
return None
print(f"Attempting to find Flair ID for text: '{flair_text}'...")
try:
flairs = subreddit.flair.link_templates
for flair in flairs:
if flair['text'].lower() == flair_text.lower():
print(f" -> Found Flair ID: {flair['id']}")
return flair['id']
print(" -> Warning: No matching flair text found.")
return None
except Exception as e:
print(f" -> Warning: Could not fetch flairs for this subreddit (Error: {e}). Proceeding without flair.")
return None
def main():
"""Main function to find an image and post it to Reddit."""
parser = argparse.ArgumentParser(
description="Find the latest sentiment image and post it to a subreddit."
)
parser.add_argument("-s", "--subreddit", help="The source subreddit of the image to post. (Defaults to overall summary)")
parser.add_argument("-w", "--weekly", action="store_true", help="Post the weekly summary instead of the daily one.")
parser.add_argument("-t", "--target-subreddit", default="rstat", help="The subreddit to post the image to. (Default: rstat)")
parser.add_argument("--flair-text", help="The text of the flair to search for (e.g., 'Daily Summary').")
parser.add_argument("--flair-id", help="Manually provide a specific Flair ID (overrides --flair-text).")
args = parser.parse_args()
# --- 1. Determine filename pattern and post title ---
current_date_str = datetime.now(timezone.utc).strftime("%Y-%m-%d")
if args.subreddit:
view_type = "weekly" if args.weekly else "daily"
filename_pattern = f"{args.subreddit.lower()}_{view_type}_*.png"
post_title = f"{view_type.capitalize()} Ticker Sentiment for r/{args.subreddit} ({current_date_str})"
else:
# Default to the overall summary
if args.weekly:
print(
"Warning: --weekly flag has no effect for overall summary. Posting overall daily image."
)
filename_pattern = "overall_summary_*.png"
post_title = (
f"Overall Top 10 Ticker Mentions Across Reddit ({current_date_str})"
)
print(f"Searching for image pattern: {filename_pattern}")
# --- 2. Find the latest image file ---
image_to_post = find_latest_image(filename_pattern)
if not image_to_post:
print(
f"Error: No image found matching the pattern '{filename_pattern}'. Please run the scraper and exporter first."
)
return
print(f"Found image: {image_to_post}")
# --- 3. Connect to Reddit and submit ---
reddit = get_reddit_instance()
if not reddit:
return
try:
target_sub = reddit.subreddit(args.target_subreddit)
# --- NEW SMART FLAIR LOGIC ---
final_flair_id = None
if args.flair_id:
# If the user provides a specific ID, use it directly.
print(f"Using provided Flair ID: {args.flair_id}")
final_flair_id = args.flair_id
elif args.flair_text:
# If they provide text, try to find the ID automatically.
final_flair_id = get_flair_id(target_sub, args.flair_text)
print(f"Submitting '{post_title}' to r/{target_sub.display_name}...")
submission = target_sub.submit_image(
title=post_title,
image_path=image_to_post,
flair_id=final_flair_id # This will be the found ID or None
)
print("\n--- Post Successful! ---")
print(f"Post URL: {submission.shortlink}")
except Exception as e:
print(f"\nAn error occurred while posting to Reddit: {e}")
if 'FLAIR_REQUIRED' in str(e):
print("\nHint: This subreddit requires a flair. Try finding the flair text or ID and use the --flair-text or --flair-id argument.")
if __name__ == "__main__":
main()