import streamlit as st from dotenv import load_dotenv import google.generativeai as genai import os from youtube_transcript_api import YouTubeTranscriptApi import time import re import tiktoken import time from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type from google.api_core.exceptions import ResourceExhausted # Load environment variables from a .env file load_dotenv() genai.configure(api_key='AIzaSyBMb20Nck_BV_4297NnxlEju73UL5vsvYY') @retry( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=60), retry=retry_if_exception_type(ResourceExhausted), reraise=True ) def generate_content_with_retry(model, prompt): time.sleep(2) # Increased delay between API calls try: return model.generate_content(prompt) except ResourceExhausted as e: st.warning(f"API quota exceeded. Retrying in a moment... ({e})") raise e # Define the base prompt template base_prompt_template = ''' You are an expert content writer and storyteller with years of experience in creating viral blog posts. Your task is to transform the input content into a captivating, human-like blog post that feels personally written and connects deeply with readers. Guidelines for Creating an Authentic, Engaging Blog Post: 1. Voice & Personality: - Write as if you're having a coffee chat with the reader - Include personal observations and insights - Use "I", "we", and "you" to create connection - Add thoughtful rhetorical questions to engage readers - Include relevant personal anecdotes or examples 2. Enhanced Structure: - Hook: Start with a powerful personal story or provocative question - Introduction: Create an emotional connection with the reader's pain points - Story Arc: Maintain narrative tension throughout - Strategic Cliffhangers: Keep readers engaged between sections - Memorable Conclusion: End with inspiration or call-to-action 3. Human Touch Elements: - Add occasional conversational asides (e.g., "Now, here's the interesting part...") - Include relatable real-world examples - Share practical tips from personal experience - Address potential reader objections naturally - Use humor and wit where appropriate 4. Engagement Boosters: - Create "Aha!" moments - Include surprising statistics or counterintuitive insights - Add social proof through expert quotes or case studies - Use power words and emotional triggers - Create shareable, quotable moments 5. Modern Content Optimization: - Write scannable content with varied paragraph lengths - Use bucket brigades to maintain flow - Include tweet-worthy quotes - Add content upgrades or bonus tips - Suggest related resources 6. Visual Flow: - Use descriptive scene-setting - Include sensory details - Suggest relevant image placements - Break up text with varied formatting - Create visual hierarchy with subheadings 7. Viral Elements: - Include controversial or debate-worthy points - Add "share-worthy" statistics or facts - Create memorable metaphors - Include practical takeaways - End with discussion-provoking questions 8. Reader Experience: - Address common objections preemptively - Include FAQs in conversational style - Add expert tips and insider secrets - Provide actionable next steps - Create FOMO (Fear of Missing Out) elements 9. Content Enhancement: - Add relevant industry trends - Include success stories or case studies - Provide practical implementation steps - Share common mistakes to avoid - Offer exclusive insights 10. SEO & Readability: - Natural keyword integration: {keywords} - Use power words and emotional triggers - Create skimmable sections - Include meta description and title suggestions - Optimize for featured snippets Tone Guidelines: - Maintain a {tone} voice throughout - Balance expertise with accessibility - Use conversational language - Show personality and authenticity - Be empathetic and understanding Length: Aim for {word_count} words while maintaining quality and engagement Please transform the following input into a captivating, human-like blog post that readers won't be able to resist sharing: {input_text} Remember: Write as if you're the world's most engaging storyteller sharing invaluable insights with a friend. Make every word count and every paragraph impossible to skip. ''' # Expanded tone options TONE_OPTIONS = [ "Professional", "Casual", "Humorous", "Inspirational", "Educational", "Conversational", "Formal", "Enthusiastic", "Empathetic", "Authoritative" ] # Article length options LENGTH_OPTIONS = { "Medium (1000-1500 words)": 1250, "Long (1500-2500 words)": 2000, "Extra Long (2500-3500 words)": 3000, "Comprehensive (3500-5000 words)": 4250 } # Function to extract video ID from various YouTube URL formats def extract_video_id(url): patterns = [ r'(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(?:embed\/)?(?:v\/)?(?:shorts\/)?(?:live\/)?(?:feature=player_embedded&v=)?([^?&"\'>]+)', ] for pattern in patterns: match = re.search(pattern, url) if match: return match.group(1) return None import threading # Cache for storing processed data cache = {} cache_lock = threading.Lock() # Optimized transcript fetching with caching @st.cache_data def get_transcript(youtube_video_url): """Get transcript from YouTube video with verification dropdown""" try: video_id = youtube_video_url.split("=")[1] transcript_text = YouTubeTranscriptApi.get_transcript(video_id, languages=['en-IN', 'en', 'hi']) transcript = " ".join([entry["text"] for entry in transcript_text]) # Store transcript in session state for verification st.session_state.current_transcript = transcript # Add expandable section to verify transcript with st.expander("🔍 View Raw Transcript", expanded=False): st.markdown("### Raw Transcript") st.markdown("*Verify the transcript before generating the blog post:*") # Display transcript with scroll st.markdown( f"""
Transform Content into Engaging Blog Posts
", unsafe_allow_html=True) st.markdown("---") tone = st.selectbox("Select tone:", TONE_OPTIONS) keywords = st.text_input("Enter keywords (comma-separated):") length = st.selectbox("Select length:", list(LENGTH_OPTIONS.keys())) # Generate button if st.button("Generate Blog Post") and input_text: st.session_state.processing = True st.session_state.cancel_generation = False try: with st.spinner("Generating a single, comprehensive blog post..."): # Add a cancel button if st.button("Cancel Generation"): st.session_state.cancel_generation = True blog_post = generate_blog_post( input_text, tone, keywords.split(",") if keywords else [], length ) if blog_post and not st.session_state.cancel_generation: st.session_state.blog_post = blog_post st.success("Blog post generated successfully!") elif st.session_state.cancel_generation: st.warning("Blog post generation was cancelled.") else: st.error("Failed to generate the blog post. Please try again later.") except Exception as e: st.error(f"An unexpected error occurred: {str(e)}") finally: st.session_state.processing = False # Display results if st.session_state.blog_post: st.markdown(st.session_state.blog_post) col1, col2 = st.columns(2) with col1: if st.download_button( "Download Blog Post", st.session_state.blog_post, "blog_post.md", "text/markdown" ): st.success("Blog post downloaded successfully!") with col2: if st.button("Reset"): st.session_state.blog_post = None st.experimental_rerun() if __name__ == "__main__": main() # Sidebar with creator information st.sidebar.markdown("---") st.sidebar.title("About the Creator") st.sidebar.info(""" Designed by Richardson Gunde 🎨 This advanced application uses AI to generate a single, comprehensive blog post based on long-form content from YouTube videos or user input. 🔗 [LinkedIn](https://www.linkedin.com/in/richardson-gunde) 📧 [Email](mailto:gunderichardson@gmail.com) """) st.markdown(""" --- :green[This advanced app leverages the power of Google's Gemini AI to generate a single, detailed, SEO-optimized long-form blog post from YouTube videos or custom text. It handles extensive content while ensuring a cohesive output.] """)