Twitter Bot for Series recommendations help please

Joined
Oct 1, 2024
Messages
1
Reaction score
0
So I'm trying to create a twitter bot to tweet out max two images from a folder, with a caption, alt image, and following tweet with the full description of the series. The bot will tweet series recommendations that I have, the structure of the folders is the main folder (Series), with folders inside, each folder being a different series. In the individual series folder there are images from the series, and a text file with the series info on it.
The bot runs and tweets, but I'm trying to figure out a way to ensure series/images don't get tweeted repeatedly too close to each other. Ive tried a few different ways, with creating log files with recent tweets / images tweeted so the script could avoid those, but it never worked. there's over 500 series in the Series folder and for some reason it keeps tweeting the same ~5. Ended up deleting the logging part and trying my luck with just a simple randomize, but still the bot is only focusing on ~5 series out of 500. I've checked the folders with the images to make sure everything is formatted properly, but it's still not working. I omitted some personal details from the code but if anyone could look it over and give me a few tips I would really appreciate it. I also want the script to be able to skip folders that are not formatted properly, but it keeps skipping to just the same series. Thank you in advance!!

import os
import random
import tweepy
from time import sleep
from datetime import datetime

# Initialize Tweepy clients
client_v2 = tweepy.Client(
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET,
access_token=ACCESS_KEY,
access_token_secret=ACCESS_SECRET
)

auth = tweepy.OAuth1UserHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_KEY, ACCESS_SECRET)
api = tweepy.API(auth)

# Directory where series folders are stored
base_folder = 'omitted path but I promise its correct and works'

# Supported image formats
supported_formats = ('.jpg', '.jpeg', '.png', '.gif')

def get_alt_text_from_description(file_path):
try:
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
alt_text = "".join(lines[:2]).strip() # First two lines for alt text
full_text = "".join(lines).strip() # Full text for the second tweet
return alt_text, full_text # Return both alt text and full text
except Exception as e:
print(f"Error reading description file {file_path}: {e}")
return None, None # Return None for both if there's an error

def tweet_images_from_folder(folder_path):
images = []
description_file = None

# Collect images and description file from the selected folder
for item in os.listdir(folder_path):
item_path = os.path.join(folder_path, item)
if os.path.isfile(item_path):
if item.lower().endswith(supported_formats):
images.append(item_path)
elif item.lower().startswith('descrip') and (item.lower().endswith('.txt') or item.lower().endswith('.rtf')):
description_file = item_path

if not images: # Skip if no images are found
print(f"No images found in folder: {folder_path}")
return False

alt_text, full_text = get_alt_text_from_description(description_file)
if not alt_text or not full_text:
print(f"Error retrieving description from: {folder_path}")
return False

# Randomly select up to 2 images to tweet
random.shuffle(images)
images_to_tweet = images[:2]
media_ids = []

# First tweet with alt text
for image in images_to_tweet:
try:
media = api.media_upload(image)
api.create_media_metadata(media.media_id, alt_text) # Add alt text for the media
media_ids.append(media.media_id)
except tweepy.errors.TooManyRequests:
sleep(15 * 60) # Rate limit hit, sleep for 15 minutes
return False
except Exception as e:
print(f"Error tweeting image {image}: {e}")
return False

if media_ids:
try:
# Tweet text for the images
tweet_text = "rec"
response = client_v2.create_tweet(text=tweet_text, media_ids=media_ids)

# Follow-up tweet with full description text
client_v2.create_tweet(text=full_text, in_reply_to_tweet_id=response.data['id'])

# Print output to terminal
print(f"Series tweeted: {alt_text} at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

except Exception as e:
print(f"Error tweeting text: {e}")
return False

return True

def tweet_random_images():
if not os.path.exists(base_folder):
print("Base folder does not exist.")
return

# Get all folders in the base directory
all_folders = [f for f in os.listdir(base_folder) if os.path.isdir(os.path.join(base_folder, f))]

if not all_folders:
print("No folders found in base directory.")
return

random.shuffle(all_folders) # Randomize folder selection

for selected_folder in all_folders:
selected_folder_path = os.path.join(base_folder, selected_folder)
print(f"Selected folder: {selected_folder}")

success = tweet_images_from_folder(selected_folder_path)

if success:
break # Exit after one successful tweet
else:
print("Retrying with another folder...")

# Run the tweet
tweet_random_images()
 
Joined
Sep 21, 2022
Messages
156
Reaction score
22
Debugging: The basics

You need to break your program up, and test each function seperately.

In a perfect world, each function would have been written, tested, and debugged, BEFORE they were combined into an application.

A skeleton is a program that has the same mainline as the application, but the functions (except the one you're testing) do nothing (return constants, aka a test stub).

I suggest writing a skeleton for every complicated thing your program does.

There is another approach, start with a very simple program, put back one feature at a time, test the program at every stage, if a bug pops up then you know exactly where it is, in the last change.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,917
Messages
2,570,033
Members
46,431
Latest member
mmec

Latest Threads

Top