Shane 7 months ago
parent 9a091a4fa4
commit 1091ed34c2
  1. 55
      foodie_weekly_thread.py

@ -7,6 +7,7 @@ from openai import OpenAI
from foodie_utils import post_tweet, AUTHORS, SUMMARY_MODEL from foodie_utils import post_tweet, AUTHORS, SUMMARY_MODEL
from foodie_config import X_API_CREDENTIALS from foodie_config import X_API_CREDENTIALS
from dotenv import load_dotenv from dotenv import load_dotenv
import tweepy
load_dotenv() load_dotenv()
@ -15,7 +16,6 @@ LOG_FILE = "/home/shane/foodie_automator/foodie_weekly_thread.log"
LOG_PRUNE_DAYS = 30 LOG_PRUNE_DAYS = 30
def setup_logging(): def setup_logging():
# Prune old logs
if os.path.exists(LOG_FILE): if os.path.exists(LOG_FILE):
with open(LOG_FILE, 'r') as f: with open(LOG_FILE, 'r') as f:
lines = f.readlines() lines = f.readlines()
@ -31,10 +31,9 @@ def setup_logging():
with open(LOG_FILE, 'w') as f: with open(LOG_FILE, 'w') as f:
f.writelines(pruned_lines) f.writelines(pruned_lines)
# Set up logging to file and console
logging.basicConfig( logging.basicConfig(
filename=LOG_FILE, filename=LOG_FILE,
level=logging.DEBUG, # Set to DEBUG for detailed output level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s', format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' datefmt='%Y-%m-%d %H:%M:%S'
) )
@ -51,19 +50,49 @@ if not os.getenv("OPENAI_API_KEY"):
logging.error("OPENAI_API_KEY is not set in environment variables") logging.error("OPENAI_API_KEY is not set in environment variables")
raise ValueError("OPENAI_API_KEY is required") raise ValueError("OPENAI_API_KEY is required")
# Validate X_API_CREDENTIALS # Validate X_API_CREDENTIALS and test API access
if not X_API_CREDENTIALS: def validate_twitter_credentials():
logging.error("X_API_CREDENTIALS is empty in foodie_config.py") logging.info("Validating Twitter API credentials for all authors")
raise ValueError("X_API_CREDENTIALS is required") valid_credentials = []
for author in AUTHORS:
credentials = next((cred for cred in X_API_CREDENTIALS if cred["username"] == author["username"]), None)
if not credentials:
logging.error(f"No X credentials found for {author['username']} in X_API_CREDENTIALS")
print(f"No X credentials found for {author['username']}")
continue
logging.debug(f"Testing credentials for {author['username']} (handle: {credentials['x_username']})")
try:
client = tweepy.Client(
consumer_key=credentials["api_key"],
consumer_secret=credentials["api_secret"],
access_token=credentials["access_token"],
access_token_secret=credentials["access_token_secret"]
)
# Test API access by fetching the user's profile
user = client.get_me()
logging.info(f"Credentials valid for {author['username']} (handle: {credentials['x_username']}, user_id: {user.data.id})")
print(f"Credentials valid for {author['username']} (handle: {credentials['x_username']})")
valid_credentials.append(credentials)
except tweepy.TweepyException as e:
logging.error(f"Failed to validate credentials for {author['username']} (handle: {credentials['x_username']}): {e}")
if hasattr(e, 'response') and e.response:
logging.error(f"Twitter API response: {e.response.text}")
print(f"Failed to validate credentials for {author['username']}: {e}")
if not valid_credentials:
logging.error("No valid Twitter credentials found for any author")
raise ValueError("No valid Twitter credentials found")
return valid_credentials
# Run credential validation
validate_twitter_credentials()
RECENT_POSTS_FILE = "/home/shane/foodie_automator/recent_posts.json" RECENT_POSTS_FILE = "/home/shane/foodie_automator/recent_posts.json"
def load_recent_posts(): def load_recent_posts():
posts = [] posts = []
unique_posts = {} # To track unique posts by title, URL, and author unique_posts = {}
logging.debug(f"Attempting to load posts from {RECENT_POSTS_FILE}") logging.debug(f"Attempting to load posts from {RECENT_POSTS_FILE}")
# Check if file exists and is readable
if not os.path.exists(RECENT_POSTS_FILE): if not os.path.exists(RECENT_POSTS_FILE):
logging.error(f"Recent posts file {RECENT_POSTS_FILE} does not exist") logging.error(f"Recent posts file {RECENT_POSTS_FILE} does not exist")
return posts return posts
@ -82,18 +111,15 @@ def load_recent_posts():
continue continue
try: try:
entry = json.loads(line.strip()) entry = json.loads(line.strip())
# Validate required fields
required_fields = ["title", "url", "author_username", "timestamp"] required_fields = ["title", "url", "author_username", "timestamp"]
if not all(key in entry for key in required_fields): if not all(key in entry for key in required_fields):
logging.warning(f"Skipping invalid entry at line {i}: missing fields {entry}") logging.warning(f"Skipping invalid entry at line {i}: missing fields {entry}")
continue continue
# Validate timestamp format
try: try:
datetime.fromisoformat(entry["timestamp"]) datetime.fromisoformat(entry["timestamp"])
except ValueError: except ValueError:
logging.warning(f"Skipping entry at line {i}: invalid timestamp {entry['timestamp']}") logging.warning(f"Skipping entry at line {i}: invalid timestamp {entry['timestamp']}")
continue continue
# Deduplicate based on title, URL, and author
key = (entry["title"], entry["url"], entry["author_username"]) key = (entry["title"], entry["url"], entry["author_username"])
if key in unique_posts: if key in unique_posts:
logging.debug(f"Skipping duplicate entry at line {i}: {entry['title']}") logging.debug(f"Skipping duplicate entry at line {i}: {entry['title']}")
@ -173,8 +199,7 @@ def post_weekly_thread():
print("Entering post_weekly_thread") print("Entering post_weekly_thread")
today = datetime.now(timezone.utc) today = datetime.now(timezone.utc)
# Fix week calculation to target the previous week (Monday to Sunday) days_to_monday = today.weekday()
days_to_monday = today.weekday() # 0 for Monday, 1 for Tuesday, etc.
start_date = (today - timedelta(days=days_to_monday + 7)).replace(hour=0, minute=0, second=0, microsecond=0) start_date = (today - timedelta(days=days_to_monday + 7)).replace(hour=0, minute=0, second=0, microsecond=0)
end_date = start_date + timedelta(days=6, hours=23, minutes=59, seconds=59) end_date = start_date + timedelta(days=6, hours=23, minutes=59, seconds=59)
@ -231,7 +256,7 @@ def post_weekly_thread():
intro_response = post_tweet(author, intro_tweet) intro_response = post_tweet(author, intro_tweet)
if not intro_response: if not intro_response:
logging.error(f"Failed to post intro tweet for {author['username']}") logging.error(f"Failed to post intro tweet for {author['username']}, skipping thread")
print(f"Failed to post intro tweet for {author['username']}") print(f"Failed to post intro tweet for {author['username']}")
continue continue

Loading…
Cancel
Save