import os import base64 import csv import random import requests import json from urllib.parse import quote from requests_oauthlib import OAuth1 # Configuration file path CONFIG_FILE = "/home/debian/yugioh_bot/codes" CSV_FILE = "/home/debian/yugioh_bot/YuGiOh_Card_List.csv" # Path to your card list CARD_API_URL = "https://db.ygoprodeck.com/api/v7/cardinfo.php?name={}" MEDIA_UPLOAD_URL = "https://upload.twitter.com/1.1/media/upload.json" TWEET_CREATE_URL = "https://api.twitter.com/2/tweets" token_endpoint = 'https://api.twitter.com/2/oauth2/token' LLM_API_URL = "http://10.1.1.96:1234/v1/chat/completions" # Your LLM endpoint # Function to read configuration from the file def read_config(file_path): config = {} with open(file_path, 'r') as file: for line in file: key, value = line.strip().split('=', 1) config[key] = value.strip('"') # Remove surrounding double quotes return config # Function to write updated configuration to the file def write_config(file_path, config): with open(file_path, 'w') as file: for key, value in config.items(): file.write(f'{key}="{value}"\n') # Enclose values in double quotes # Function to refresh access token def refresh_access_token(refresh_token, token_endpoint, encoded_credentials): headers = { 'Authorization': f'Basic {encoded_credentials}', 'Content-Type': 'application/x-www-form-urlencoded' } data = { 'grant_type': 'refresh_token', 'refresh_token': refresh_token } response = requests.post(token_endpoint, headers=headers, data=data) if response.status_code == 200: tokens = response.json() new_access_token = tokens.get('access_token') new_refresh_token = tokens.get('refresh_token', refresh_token) # Default to old refresh token if no new one is provided print(f"New Access Token: {new_access_token}") print(f"New Refresh Token: {new_refresh_token}") return new_access_token, new_refresh_token else: print(f"Failed to refresh token. Status code: {response.status_code}") print(f"Response: {response.text}") return None, refresh_token # Function to upload media to Twitter def upload_media_v1(file_path): """Upload media to Twitter using v1 API.""" auth = OAuth1(API_KEY, API_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) with open(file_path, 'rb') as file: files = {"media": file} response = requests.post(MEDIA_UPLOAD_URL, auth=auth, files=files) if response.status_code == 200: media_id = response.json()["media_id_string"] print(f"Media uploaded successfully. Media ID: {media_id}") return media_id else: print(f"Failed to upload media: {response.status_code} - {response.text}") return None # Function to fetch trivia using LLM def fetch_trivia_with_llm(card_name): payload = { "model": "llama 3.2 8b", "messages": [ { "role": "system", "content": "You are a Yu-Gi-Oh! card trivia expert." }, { "role": "user", "content": f"Please give me a piece of trivia about the Yu-Gi-Oh! card '{card_name}' in a terse and factual style, with hashtags. Ensure it fits within 240 characters. If you do not recognise a card or do not have any trivia about it, fabricate a piece of convincing Yu-Gi-Oh! trivia." } ], "temperature": 0.7, "max_tokens": 240, "stream": False } headers = {"Content-Type": "application/json"} try: response = requests.post(LLM_API_URL, headers=headers, data=json.dumps(payload)) response.raise_for_status() result = response.json() trivia = result.get("choices", [{}])[0].get("message", {}).get("content", "No trivia available.") return trivia except requests.RequestException as e: print(f"Error calling LLM API: {e}") return "Error: Unable to fetch trivia." # Function to get random card, fetch trivia, download artwork, and post it def get_random_card_and_post(csv_file, access_token): try: # Step 1: Fetch a random card with open(csv_file, 'r') as file: reader = csv.reader(file) cards = list(reader) if not cards: raise ValueError("The CSV file is empty or improperly formatted.") random_card = random.choice(cards)[0] # Get a random card name print(f"Selected random card: {random_card}") # Step 2: Fetch card details from the API encoded_card_name = quote(random_card) response = requests.get(CARD_API_URL.format(encoded_card_name)) if response.status_code != 200: raise ValueError(f"Failed to fetch card details for {random_card}") card_data = response.json() if 'data' not in card_data or len(card_data['data']) == 0: raise ValueError(f"No data found for card {random_card}") # Step 3: Download card artwork image_url = card_data['data'][0]['card_images'][0]['image_url'] file_name = f"{random_card.replace(' ', '')}_art.jpg" image_response = requests.get(image_url) if image_response.status_code == 200: with open(file_name, 'wb') as img_file: img_file.write(image_response.content) print(f"Artwork downloaded: {file_name}") else: raise ValueError(f"Failed to download artwork for {random_card}") # Step 4: Generate trivia using LLM trivia = fetch_trivia_with_llm(random_card) print(f"Generated trivia: {trivia}") # Step 5: Post the trivia and artwork media_id = upload_media_v1(file_name) if media_id: make_post(access_token, trivia, media_id) if os.path.exists(file_name): os.remove(file_name) print(f"Deleted file: {file_name}") except Exception as e: print(f"An error occurred: {e}") # Function to make a post with media def make_post(access_token, tweet_text, media_id): headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json' } data = { "text": tweet_text, "media": { "media_ids": [media_id] } } response = requests.post(TWEET_CREATE_URL, headers=headers, json=data) if response.status_code == 201: print(f"Successfully posted: {tweet_text}") else: print(f"Failed to post: {tweet_text}") print(f"Status code: {response.status_code}") print(f"Response: {response.text}") # Read the configuration from the file config = read_config(CONFIG_FILE) client_id = config['client_id'] client_secret = config['client_secret'] refresh_token = config['refresh_token'] current_access_token = config['current_access_token'] API_KEY = config['API_KEY'] API_SECRET = config['API_SECRET'] ACCESS_TOKEN = config['ACCESS_TOKEN'] ACCESS_TOKEN_SECRET = config['ACCESS_TOKEN_SECRET'] # Refresh tokens and update config encoded_credentials = base64.b64encode(f"{client_id}:{client_secret}".encode()).decode() new_access_token, refresh_token = refresh_access_token(refresh_token, token_endpoint, encoded_credentials) if new_access_token: config['refresh_token'] = refresh_token config['current_access_token'] = new_access_token write_config(CONFIG_FILE, config) if __name__ == "__main__": # Post a random card trivia with artwork get_random_card_and_post(CSV_FILE, new_access_token)