Skip to main content
Glama
image_generator.py6.08 kB
""" Image Generator for WordPress Articles Uses OpenAI DALL-E 3 to generate images for articles """ import os import tempfile import logging import re import hashlib from typing import Dict, Optional import requests from openai import OpenAI logger = logging.getLogger(__name__) class ImageGenerator: """Image generator using OpenAI DALL-E 3""" def __init__(self): """Initialize the image generator""" self.client = None self.temp_dir = tempfile.gettempdir() # Initialize OpenAI client if API key is available api_key = os.getenv('OPENAI_API_KEY') if api_key: try: self.client = OpenAI(api_key=api_key) logger.info("Image generator initialized successfully") except Exception as e: logger.error(f"Failed to initialize OpenAI client: {e}") self.client = None else: logger.warning("OPENAI_API_KEY not found - image generation disabled") def is_available(self) -> bool: """Check if image generation is available""" return self.client is not None def clean_filename_string(self, text: str, max_length: int = 50) -> str: """Clean and shorten a string for use in filenames or titles""" if not text: return "image" # Remove HTML tags text = re.sub(r'<[^>]+>', '', text) # Keep only alphanumeric characters, spaces, hyphens, and underscores text = re.sub(r'[^\w\s\-]', '', text) # Replace multiple spaces with single space text = re.sub(r'\s+', ' ', text) # Replace spaces with underscores for filenames text = text.replace(' ', '_') # Convert to lowercase text = text.lower().strip() # Truncate to max length if len(text) > max_length: text = text[:max_length].rstrip('_') # Ensure it's not empty if not text: text = "image" return text def generate_short_filename(self, title: str) -> str: """Generate a short, clean filename based on the title""" # Clean the title for filename use clean_title = self.clean_filename_string(title, max_length=15) # Create a short hash for uniqueness title_hash = hashlib.md5(title.encode()).hexdigest()[:6] # Combine into a short filename filename = f"{clean_title}_{title_hash}.png" # Ensure total length is reasonable (max 30 characters) if len(filename) > 30: filename = f"img_{title_hash}.png" logger.info(f"Generated filename: {filename} (from title: {title[:50]}...)") return filename def create_prompt(self, title: str, content: str) -> str: """Create a prompt for image generation based on article content""" # Extract key themes from title and content combined_text = f"{title}. {content}" # Clean HTML tags from content clean_content = re.sub(r'<[^>]+>', '', combined_text) # Create a focused prompt prompt = f"""Create a professional, high-quality image for an article titled "{title}". The image should be: - Clean and modern - Relevant to the topic - Suitable for a blog article - Professional looking - Without any text overlays Style: Modern, clean, professional illustration or photography """ return prompt def generate_and_download_image(self, title: str, content: str) -> Optional[Dict[str, str]]: """Generate and download an image for the article""" if not self.is_available(): logger.warning("Image generator not available") return None try: # Create prompt prompt = self.create_prompt(title, content) logger.info(f"Generating image with prompt: {prompt[:100]}...") # Generate image using DALL-E 3 response = self.client.images.generate( model="dall-e-3", prompt=prompt, size="1024x1024", quality="standard", n=1, ) # Get image URL image_url = response.data[0].url logger.info(f"Image generated successfully: {image_url}") # Download image image_response = requests.get(image_url, timeout=60) image_response.raise_for_status() # Generate short, clean filename filename = self.generate_short_filename(title) temp_path = os.path.join(self.temp_dir, filename) with open(temp_path, 'wb') as f: f.write(image_response.content) logger.info(f"Image downloaded and saved to: {temp_path}") # Also create a shortened title for upload short_title = self.clean_filename_string(title, max_length=30).replace('_', ' ').title() return { "url": image_url, "local_path": temp_path, "filename": filename, "title": title, "short_title": short_title # Add shortened title for upload } except Exception as e: logger.error(f"Error generating image: {e}") return None def cleanup_temp_file(self, file_path: str) -> bool: """Clean up temporary image file""" try: if os.path.exists(file_path): os.remove(file_path) logger.info(f"Temporary file cleaned up: {file_path}") return True return False except Exception as e: logger.error(f"Error cleaning up temporary file {file_path}: {e}") return False

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/seomentor/wpmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server