Shane 7 months ago
parent 49e7311abd
commit 737c6e077c
  1. 57
      foodie_engagement_tweet.py

@ -7,6 +7,7 @@ import sys
import fcntl import fcntl
import os import os
import time import time
import re
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import tweepy import tweepy
from openai import OpenAI from openai import OpenAI
@ -56,7 +57,7 @@ def setup_logging():
logging.basicConfig( logging.basicConfig(
filename=LOG_FILE, filename=LOG_FILE,
level=logging.DEBUG, # Changed to DEBUG to show more details 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'
) )
@ -149,6 +150,27 @@ def validate_twitter_credentials(author):
return False return False
return False return False
def remove_emojis(text):
"""Remove emojis from the given text."""
# Unicode ranges for emojis
emoji_pattern = re.compile(
"["
"\U0001F600-\U0001F64F" # Emoticons
"\U0001F300-\U0001F5FF" # Symbols & Pictographs
"\U0001F680-\U0001F6FF" # Transport & Map Symbols
"\U0001F700-\U0001F77F" # Alchemical Symbols
"\U0001F780-\U0001F7FF" # Geometric Shapes Extended
"\U0001F800-\U0001F8FF" # Supplemental Arrows-C
"\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
"\U0001FA00-\U0001FA6F" # Chess Symbols
"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
"\U00002700-\U000027BF" # Dingbats
"\U00002600-\U000026FF" # Miscellaneous Symbols
"]+",
flags=re.UNICODE
)
return emoji_pattern.sub(r"", text)
def get_reference_date(): def get_reference_date():
"""Load or initialize the reference date for the 2-day interval.""" """Load or initialize the reference date for the 2-day interval."""
os.makedirs(os.path.dirname(REFERENCE_DATE_FILE), exist_ok=True) os.makedirs(os.path.dirname(REFERENCE_DATE_FILE), exist_ok=True)
@ -185,12 +207,28 @@ def generate_engagement_tweet(author):
# Case-insensitive lookup for background with whitespace stripping # Case-insensitive lookup for background with whitespace stripping
username_cleaned = username.strip().lower() username_cleaned = username.strip().lower()
background = next( background = {}
(bg for bg in AUTHOR_BACKGROUNDS if bg["username"].strip().lower() == username_cleaned), available_usernames = []
{} for bg in AUTHOR_BACKGROUNDS:
) bg_username = bg.get("username")
if bg_username is None:
logging.warning(f"Skipping background entry with missing username: {bg}")
continue
if not isinstance(bg_username, str):
logging.warning(f"Skipping background entry with non-string username: {bg_username} (type: {type(bg_username)})")
continue
bg_username_cleaned = bg_username.strip().lower()
available_usernames.append(bg_username)
logging.debug(
f"Comparing usernames for {username}: "
f"author username (cleaned) = '{username_cleaned}', "
f"background username (cleaned) = '{bg_username_cleaned}'"
)
if bg_username_cleaned == username_cleaned:
background = bg
break
if not background or "engagement_themes" not in background: if not background or "engagement_themes" not in background:
available_usernames = [bg["username"] for bg in AUTHOR_BACKGROUNDS]
logging.warning( logging.warning(
f"No background or engagement themes found for {username}. " f"No background or engagement themes found for {username}. "
f"Attempted username (cleaned): {username_cleaned}. " f"Attempted username (cleaned): {username_cleaned}. "
@ -211,8 +249,7 @@ def generate_engagement_tweet(author):
f"Keep it under 230 characters to ensure room for the URL. " f"Keep it under 230 characters to ensure room for the URL. "
f"Use {persona_config['tone']}. " f"Use {persona_config['tone']}. "
f"Include a call to action to follow {author_handle} or like the tweet, followed by the URL {URL} (do not mention InsiderFoodie.com separately in the text). " f"Include a call to action to follow {author_handle} or like the tweet, followed by the URL {URL} (do not mention InsiderFoodie.com separately in the text). "
f"Avoid using the word 'elevate'—use more humanized language like 'level up' or 'bring to life'. " f"Strictly avoid using any emojis, hashtags, or reward-driven incentives (e.g., giveaways)—do not include them under any circumstances. "
f"Do not include emojis, hashtags, or reward-driven incentives (e.g., giveaways). "
f"Return only the tweet text." f"Return only the tweet text."
) )
@ -228,6 +265,8 @@ def generate_engagement_tweet(author):
temperature=0.7 temperature=0.7
) )
tweet = response.choices[0].message.content.strip() tweet = response.choices[0].message.content.strip()
# Remove emojis as a safeguard
tweet = remove_emojis(tweet)
# Check for duplicate URLs and remove if present # Check for duplicate URLs and remove if present
url_count = tweet.lower().count(URL.lower()) url_count = tweet.lower().count(URL.lower())
if url_count > 1: if url_count > 1:
@ -266,6 +305,8 @@ def generate_engagement_tweet(author):
if total_length > 280: if total_length > 280:
tweet_without_url = tweet_without_url[:(280 - URL_SHORTENED_LENGTH - 3)] tweet_without_url = tweet_without_url[:(280 - URL_SHORTENED_LENGTH - 3)]
fallback = tweet_without_url + "..." + " " + URL fallback = tweet_without_url + "..." + " " + URL
# Remove emojis from fallback as well
fallback = remove_emojis(fallback)
logging.info(f"Using fallback engagement tweet: {fallback}") logging.info(f"Using fallback engagement tweet: {fallback}")
return fallback return fallback
return None return None

Loading…
Cancel
Save