update consistency
This commit is contained in:
@@ -6,6 +6,8 @@ import signal
|
||||
import sys
|
||||
import fcntl
|
||||
import os
|
||||
from foodie_config import ENGAGEMENT_REFERENCE_DATE_FILE
|
||||
REFERENCE_DATE_FILE = ENGAGEMENT_REFERENCE_DATE_FILE
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from openai import OpenAI
|
||||
from foodie_utils import post_tweet, AUTHORS, SUMMARY_MODEL, load_post_counts, save_post_counts
|
||||
|
||||
@@ -197,17 +197,18 @@ def filter_posts_for_week(posts, start_date, end_date):
|
||||
return filtered_posts
|
||||
|
||||
def generate_intro_tweet(author):
|
||||
"""Generate an intro tweet for the weekly thread."""
|
||||
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']}")
|
||||
return None
|
||||
author_handle = credentials["x_username"]
|
||||
logging.debug(f"Generating intro tweet for {author_handle}")
|
||||
persona = author["persona"] # Add persona
|
||||
persona_config = PERSONA_CONFIGS[persona]
|
||||
logging.debug(f"Generating intro tweet for {author_handle} as {persona}")
|
||||
|
||||
prompt = (
|
||||
f"Generate a concise tweet (under 280 characters) for {author_handle}. "
|
||||
f"Introduce a thread of their top 10 foodie posts of the week on InsiderFoodie.com. "
|
||||
f"Generate a concise tweet (under 280 characters) for {author_handle} as {persona_config['description']}. "
|
||||
f"Introduce a thread of their top 10 foodie posts of the week on InsiderFoodie.com in {persona_config['tone']}. "
|
||||
f"Make it engaging, create curiosity, and include a call to action to visit InsiderFoodie.com, follow {author_handle}, or like the thread. "
|
||||
f"Avoid using the word 'elevate'—use more humanized language like 'level up' or 'bring to life'. "
|
||||
f"Do not include emojis, hashtags, or reward-driven incentives (e.g., giveaways)."
|
||||
|
||||
+42
-20
@@ -6,6 +6,7 @@ import time
|
||||
import sys
|
||||
import signal
|
||||
import os
|
||||
from foodie_utils import load_post_counts, save_post_counts # Add imports
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from openai import OpenAI
|
||||
from foodie_config import OPENAI_API_KEY, AUTHORS, LIGHT_TASK_MODEL, PERSONA_CONFIGS, AUTHOR_BACKGROUNDS_FILE
|
||||
@@ -16,6 +17,8 @@ load_dotenv()
|
||||
|
||||
LOG_FILE = "/home/shane/foodie_automator/foodie_x_poster.log"
|
||||
LOG_PRUNE_DAYS = 30
|
||||
MAX_RETRIES = 3
|
||||
RETRY_BACKOFF = 2
|
||||
|
||||
def setup_logging():
|
||||
if os.path.exists(LOG_FILE):
|
||||
@@ -76,35 +79,54 @@ def generate_engagement_tweet(author, persona):
|
||||
"For engagement tweets, ask a question about food trends, foods, or articles to engage the public.",
|
||||
f"Generate an engagement tweet asking a question about {theme} to engage the public."
|
||||
)
|
||||
try:
|
||||
response = client.chat.completions.create(
|
||||
model=LIGHT_TASK_MODEL,
|
||||
messages=[
|
||||
{"role": "system", "content": prompt},
|
||||
{"role": "user", "content": f"Generate engagement tweet for {author['username']} about {theme}."}
|
||||
],
|
||||
max_tokens=100,
|
||||
temperature=0.9
|
||||
)
|
||||
tweet = response.choices[0].message.content.strip()
|
||||
if len(tweet) > 280:
|
||||
tweet = tweet[:277] + "..."
|
||||
logging.info(f"Generated engagement tweet for {author['username']}: {tweet}")
|
||||
return tweet
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to generate engagement tweet for {author['username']}: {e}")
|
||||
return f"What’s your take on {theme}? Let’s talk!"
|
||||
for attempt in range(MAX_RETRIES):
|
||||
try:
|
||||
response = client.chat.completions.create(
|
||||
model=LIGHT_TASK_MODEL,
|
||||
messages=[
|
||||
{"role": "system", "content": prompt},
|
||||
{"role": "user", "content": f"Generate engagement tweet for {author['username']} about {theme}."}
|
||||
],
|
||||
max_tokens=100,
|
||||
temperature=0.9
|
||||
)
|
||||
tweet = response.choices[0].message.content.strip()
|
||||
if len(tweet) > 280:
|
||||
tweet = tweet[:277] + "..."
|
||||
logging.info(f"Generated engagement tweet for {author['username']}: {tweet}")
|
||||
return tweet
|
||||
except Exception as e:
|
||||
logging.warning(f"Failed to generate engagement tweet for {author['username']} (attempt {attempt + 1}): {e}")
|
||||
if attempt < MAX_RETRIES - 1:
|
||||
time.sleep(RETRY_BACKOFF * (2 ** attempt))
|
||||
else:
|
||||
logging.error(f"Failed to generate engagement tweet after {MAX_RETRIES} attempts")
|
||||
return f"What’s your take on {theme}? Let’s talk!"
|
||||
|
||||
def main():
|
||||
global is_posting
|
||||
logging.info("***** X Poster Launched *****")
|
||||
post_counts = load_post_counts() # Load counts
|
||||
for author in AUTHORS:
|
||||
# Check limits
|
||||
author_count = next((entry for entry in post_counts if entry["username"] == author["username"]), None)
|
||||
if not author_count:
|
||||
logging.error(f"No post count entry for {author['username']}, skipping")
|
||||
continue
|
||||
if author_count["monthly_count"] >= 500:
|
||||
logging.warning(f"Monthly post limit (500) reached for {author['username']}, skipping")
|
||||
continue
|
||||
if author_count["daily_count"] >= 20:
|
||||
logging.warning(f"Daily post limit (20) reached for {author['username']}, skipping")
|
||||
continue
|
||||
is_posting = True
|
||||
tweet = generate_engagement_tweet(author, author["persona"])
|
||||
post_tweet(author, tweet)
|
||||
if post_tweet(author, tweet):
|
||||
author_count["monthly_count"] += 1 # Update counts
|
||||
author_count["daily_count"] += 1
|
||||
save_post_counts(post_counts)
|
||||
is_posting = False
|
||||
time.sleep(random.uniform(3600, 7200))
|
||||
|
||||
logging.info("X posting completed")
|
||||
return random.randint(600, 1800)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user