Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| from bs4 import BeautifulSoup | |
| import google.generativeai as genai | |
| def fetch_article_content(url): | |
| """Fetch article content with basic error handling""" | |
| try: | |
| headers = {'User-Agent': 'Mozilla/5.0'} | |
| response = requests.get(url, headers=headers, timeout=8) | |
| response.raise_for_status() | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| # Extract first 8 paragraphs | |
| paragraphs = soup.find_all('p')[:8] | |
| content = ' '.join([p.get_text(strip=True) for p in paragraphs]) | |
| return content[:2000] # Keep it concise | |
| except Exception as e: | |
| return f"FETCH_ERROR: {str(e)}" | |
| def generate_platform_post(article_text, api_key): | |
| """Generate post using user-provided API key""" | |
| try: | |
| # Configure Gemini with user's API key | |
| genai.configure(api_key=api_key) | |
| model = genai.GenerativeModel('gemini-1.5-pro') | |
| prompt = f""" | |
| Create a Reddit/Quora-style post from this article: | |
| {article_text} | |
| Output format: | |
| Title: [short title] | |
| Post: [clean HTML with 1 image tag + alt text] | |
| Requirements: | |
| - Title < 100 characters | |
| - Include <img> with descriptive alt text | |
| - Minimal styling | |
| - Mobile-friendly | |
| """ | |
| response = model.generate_content(prompt) # Removed invalid timeout | |
| return parse_gemini_response(response.text) | |
| except Exception as e: | |
| return ("AI ERROR", f"<p>API Error: {str(e)}</p>") | |
| def parse_gemini_response(response): | |
| """Robust response parsing β returns two values (title, content)""" | |
| try: | |
| title = response.split("Title:")[1].split("Post:")[0].strip()[:100] | |
| content = response.split("Post:")[1].strip() | |
| return title, content | |
| except: | |
| return ("Formatting Error", "<p>Failed to parse AI response</p>") | |
| def process_url(url, api_key): | |
| """Main processing pipeline with status updates""" | |
| if not api_key or len(api_key.strip()) < 30: | |
| yield ("API Key Required", "<p>Please enter your Gemini API key above</p>") | |
| return | |
| if not url.startswith("http"): | |
| yield ("Invalid URL", "<p>Please enter a valid article URL</p>") | |
| return | |
| yield ("Fetching Article...", "<p>Connecting to URL...</p>") | |
| article_text = fetch_article_content(url) | |
| if article_text.startswith("FETCH_ERROR:"): | |
| yield ("Fetch Failed", f"<p>{article_text.replace('FETCH_ERROR: ', '')}</p>") | |
| return | |
| yield ("Generating Post...", "<p>Creating content with Gemini...</p>") | |
| result = generate_platform_post(article_text, api_key) | |
| yield result # This will now return (title, content) | |
| # Create Gradio interface | |
| url_input = gr.Textbox(label="Article URL", placeholder="https://example.com/article...") | |
| api_key_input = gr.Textbox( | |
| label="Gemini API Key", | |
| placeholder="AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", | |
| type="password" | |
| ) | |
| title_output = gr.Textbox(label="Generated Title") | |
| content_output = gr.HTML(label="Formatted Post") | |
| app = gr.Interface( | |
| fn=process_url, | |
| inputs=[url_input, api_key_input], | |
| outputs=[ | |
| gr.Textbox(label="Generated Title"), | |
| gr.HTML(label="Formatted Post") | |
| ], | |
| examples=[ | |
| ["https://google.com", "AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"] | |
| ], | |
| title="Article to Reddit/Quora Post Converter", | |
| description="Convert news articles into optimized posts with AI-generated formatting and image descriptions", | |
| allow_flagging="never", | |
| live=False, | |
| theme="default" | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() |