import streamlit as st from loguru import logger import asyncio from lib.web_crawlers.async_web_crawler import AsyncWebCrawlerService from lib.personalization.style_analyzer import StyleAnalyzer from lib.alwrity_ui.dashboard_styles import apply_dashboard_style, render_dashboard_header import sys # Configure logger logger.remove() # Remove default handler logger.add( "logs/settings_page.log", rotation="500 MB", retention="10 days", level="DEBUG", format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}", backtrace=True, diagnose=True ) logger.add( sys.stdout, level="INFO", format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {message}" ) def display_style_analysis(analysis_results: dict): """Display the style analysis results in a structured format with premium styling.""" try: # Writing Style Section st.markdown("""
🎨

Writing Style Analysis

""", unsafe_allow_html=True) writing_style = analysis_results.get("writing_style", {}) col1, col2 = st.columns(2) with col1: st.markdown(f"""
Tone: {writing_style.get("tone", "N/A")}
Voice: {writing_style.get("voice", "N/A")}
""", unsafe_allow_html=True) with col2: st.markdown(f"""
Complexity: {writing_style.get("complexity", "N/A")}
Engagement: {writing_style.get("engagement_level", "N/A")}
""", unsafe_allow_html=True) # Content Characteristics Section st.markdown("""
📊

Content Characteristics

""", unsafe_allow_html=True) content_chars = analysis_results.get("content_characteristics", {}) col1, col2 = st.columns(2) with col1: st.markdown(f"""
Sentence Structure: {content_chars.get("sentence_structure", "N/A")}
Vocabulary Level: {content_chars.get("vocabulary_level", "N/A")}
""", unsafe_allow_html=True) with col2: st.markdown(f"""
Organization: {content_chars.get("paragraph_organization", "N/A")}
Content Flow: {content_chars.get("content_flow", "N/A")}
""", unsafe_allow_html=True) # Target Audience Section st.markdown("""
🎯

Target Audience

""", unsafe_allow_html=True) target_audience = analysis_results.get("target_audience", {}) col1, col2 = st.columns(2) with col1: st.markdown(f"""
Demographics: {', '.join(target_audience.get("demographics", ["N/A"]))}
Expertise Level: {target_audience.get("expertise_level", "N/A")}
""", unsafe_allow_html=True) with col2: st.markdown(f"""
Industry Focus: {target_audience.get("industry_focus", "N/A")}
Geographic Focus: {target_audience.get("geographic_focus", "N/A")}
""", unsafe_allow_html=True) # Recommended Settings Section st.markdown("""
⚙️

Recommended Settings

""", unsafe_allow_html=True) recommended = analysis_results.get("recommended_settings", {}) st.markdown(f"""
🎭
Writing Tone
{recommended.get("writing_tone", "N/A")}
👥
Target Audience
{recommended.get("target_audience", "N/A")}
📝
Content Type
{recommended.get("content_type", "N/A")}
🎨
Creativity Level
{recommended.get("creativity_level", "N/A")}
""", unsafe_allow_html=True) except Exception as e: logger.error(f"Error displaying style analysis: {str(e)}") st.error(f"Error displaying analysis results: {str(e)}") def render_settings_page(): """Renders the settings page with premium glassmorphic design and all configuration options in tabs""" # Apply common dashboard styling apply_dashboard_style() # Add settings-specific CSS for tabs and form elements st.markdown(""" """, unsafe_allow_html=True) # Use the common dashboard header render_dashboard_header( "⚙️ Settings & Configuration", "Customize your AI experience with precision controls for content generation, personalization, and optimization. Fine-tune every aspect to match your unique requirements and style." ) # Create tabs for different settings categories with premium styling tabs = st.tabs([ "📝 Content", "🖼️ Images", "🤖 LLM", "🔍 Search", "🎨 AI Personalization" ]) # Content Settings Tab with tabs[0]: st.markdown("""

📝 Content Personalization

""", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: blog_length = st.text_input( "**Content Length (words)**", value="2000", key="settings_blog_length", help="Approximate word count for blogs. Note: Actual length may vary based on GPT provider and max token count." ) blog_tone_options = ["Casual", "Professional", "How-to", "Beginner", "Research", "Programming", "Social Media", "Customize"] blog_tone = st.selectbox( "**Content Tone**", options=blog_tone_options, key="settings_blog_tone", help="Select the desired tone for the blog content." ) # Initialize custom_tone variable custom_tone = "" if blog_tone == "Customize": custom_tone = st.text_input( "Enter the tone of your content", key="settings_custom_tone", help="Specify the tone of your content." ) if custom_tone: blog_tone = custom_tone else: st.warning("Please specify the tone of your content.") blog_demographic_options = ["Professional", "Gen-Z", "Tech-savvy", "Student", "Digital Marketing", "Customize"] blog_demographic = st.selectbox( "**Target Audience**", options=blog_demographic_options, key="settings_blog_demographic", help="Select the primary audience for the blog content." ) with col2: blog_type = st.selectbox( "**Content Type**", options=["Informational", "Commercial", "Company", "News", "Finance", "Competitor", "Programming", "Scholar"], key="settings_blog_type", help="Select the category that best describes the blog content." ) blog_language = st.selectbox( "**Content Language**", options=["English", "Spanish", "German", "Chinese", "Arabic", "Nepali", "Hindi", "Hindustani", "Customize"], key="settings_blog_language", help="Select the language in which the blog will be written." ) blog_output_format = st.selectbox( "**Content Output Format**", options=["markdown", "HTML", "plaintext"], key="settings_blog_output_format", help="Select the format for the blog output." ) # Images Settings Tab with tabs[1]: st.markdown("""

🖼️ Images Personalization

""", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: image_generation_model = st.selectbox( "**Image Generation Model**", options=["stable-diffusion", "dalle2", "dalle3"], key="settings_image_model", help="Select the model to generate images for the blog." ) with col2: number_of_blog_images = st.number_input( "**Number of Blog Images**", value=1, min_value=1, max_value=10, key="settings_number_of_images", help="Specify the number of images to include in the blog." ) # LLM Settings Tab with tabs[2]: st.markdown("""

🤖 LLM Personalization

""", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: gpt_provider = st.selectbox( "**GPT Provider**", options=["google", "openai", "minstral"], key="settings_gpt_provider", help="Select the provider for the GPT model." ) model = st.text_input( "**Model**", value="gemini-1.5-flash-latest", key="settings_model", help="Specify the model version to use from the selected provider." ) temperature = st.slider( "**Temperature**", min_value=0.1, max_value=1.0, value=0.7, step=0.1, key="settings_temperature", help="Controls the creativity level of the generated text." ) max_tokens = st.selectbox( "**Max Tokens**", options=[500, 1000, 2000, 4000, 16000, 32000, 64000], index=3, key="settings_max_tokens", help="Maximum length of the output sequence." ) with col2: top_p = st.slider( "**Top-p**", min_value=0.0, max_value=1.0, value=0.9, step=0.1, key="settings_top_p", help="Controls diversity in text generation." ) frequency_penalty = st.slider( "**Frequency Penalty**", min_value=0.0, max_value=2.0, value=1.0, step=0.1, key="settings_frequency_penalty", help="Reduces word repetition in output." ) # Search Settings Tab with tabs[3]: st.markdown("""

🔍 Search Engine Personalization

""", unsafe_allow_html=True) col1, col2 = st.columns(2) with col1: geographic_location = st.selectbox( "**Geographic Location**", options=["us", "in", "fr", "cn"], key="settings_geographic_location", help="Select the geographic location for tailoring search results." ) search_language = st.selectbox( "**Search Language**", options=["en", "zn-cn", "de", "hi"], key="settings_search_language", help="Select the language for the search results." ) number_of_results = st.number_input( "**Number of Results**", value=10, min_value=1, max_value=20, key="settings_number_of_results", help="Specify the number of search results to retrieve." ) with col2: time_range = st.selectbox( "**Time Range**", options=["anytime", "past day", "past week", "past month", "past year"], key="settings_time_range", help="Select the time range for filtering search results." ) include_domains = st.text_input( "**Include Domains**", value="", key="settings_include_domains", help="List specific domains to include in search results (comma-separated)." ) similar_url = st.text_input( "**Similar URL**", value="", key="settings_similar_url", help="Provide a URL to find similar results." ) # AI Personalization Tab with tabs[4]: st.markdown("""

🎨 AI Style Analysis

""", unsafe_allow_html=True) st.markdown("""

Enter a website URL or provide content samples to analyze your writing style and get personalized recommendations for optimal AI content generation.

""", unsafe_allow_html=True) # Create two columns for the layout col1, col2 = st.columns([2, 1]) with col1: # Website URL input st.markdown("#### 🌐 Website URL Analysis") url = st.text_input( "Enter your website URL", placeholder="https://example.com", key="settings_website_url", help="Provide your website URL to analyze your content style. Leave empty if you want to provide written samples instead." ) # Alternative: Written samples if not url: st.markdown("#### 📝 Written Samples") st.markdown("""

No website URL? No problem! You can provide written samples of your content instead. Share your best articles, blog posts, or any content that represents your writing style.

""", unsafe_allow_html=True) samples = st.text_area( "Paste your content samples here", key="settings_content_samples", help="Paste 2-3 samples of your best content. This helps ALwrity understand your writing style.", height=200 ) with col2: st.markdown("#### 🎯 Analysis Features") st.markdown("""

✨ Writing Style: Tone, voice, complexity analysis

📊 Content Analysis: Structure and vocabulary assessment

🎯 Audience Insights: Target demographic identification

⚙️ AI Recommendations: Personalized settings optimization

""", unsafe_allow_html=True) # Add spacing between categories st.markdown("
", unsafe_allow_html=True) if st.button("🎨 Analyze Writing Style", use_container_width=True, key="settings_analyze_style", type="primary"): if url: with st.status("Starting style analysis...", expanded=True) as status: try: # Step 1: Initialize crawler status.update(label="Step 1/4: Initializing web crawler...", state="running") crawler_service = AsyncWebCrawlerService() # Step 2: Crawl website status.update(label="Step 2/4: Crawling website content...", state="running") loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) result = loop.run_until_complete(crawler_service.crawl_website(url)) loop.close() if result.get('success', False): content = result.get('content', {}) # Step 3: Initialize style analyzer status.update(label="Step 3/4: Analyzing content style...", state="running") style_analyzer = StyleAnalyzer() # Step 4: Perform style analysis status.update(label="Step 4/4: Generating style recommendations...", state="running") style_analysis = style_analyzer.analyze_content_style(content) if style_analysis.get('error'): status.update(label="Analysis failed", state="error") st.error(f"Style analysis failed: {style_analysis['error']}") else: status.update(label="Analysis complete!", state="complete") # Display style analysis results display_style_analysis(style_analysis) # Display original content in tabs tab1, tab2, tab3 = st.tabs(["📄 Content", "📋 Metadata", "🔗 Links"]) with tab1: st.markdown("#### Main Content") st.markdown(f"""
{content.get('main_content', 'No content found')}
""", unsafe_allow_html=True) with tab2: st.markdown("#### Website Metadata") st.markdown(f"""
Title: {content.get('title', 'No title found')}
Description: {content.get('description', 'No description found')}
""", unsafe_allow_html=True) with tab3: st.markdown("#### Extracted Links") links = content.get('links', []) if links: for link in links[:10]: # Show first 10 links st.markdown(f"""
{link.get('text', 'No text')[:80]}...
""", unsafe_allow_html=True) else: st.markdown("No links found in the content.") else: status.update(label="Crawling failed", state="error") st.error("Failed to crawl the website. Please check the URL and try again.") except Exception as e: status.update(label="Analysis failed", state="error") st.error(f"An error occurred during analysis: {str(e)}") elif samples: with st.status("Starting style analysis...", expanded=True) as status: try: # Initialize style analyzer status.update(label="Analyzing content style...", state="running") style_analyzer = StyleAnalyzer() # Perform style analysis style_analysis = style_analyzer.analyze_content_style({"main_content": samples}) if style_analysis.get('error'): status.update(label="Analysis failed", state="error") st.error(f"Style analysis failed: {style_analysis['error']}") else: status.update(label="Analysis complete!", state="complete") # Display style analysis results display_style_analysis(style_analysis) except Exception as e: status.update(label="Analysis failed", state="error") st.error(f"An error occurred during analysis: {str(e)}") else: st.warning("Please provide either a website URL or content samples to analyze.") # Save Settings Button with premium styling st.markdown("
", unsafe_allow_html=True) if st.button("💾 Save All Settings", type="primary", use_container_width=True, key="settings_save_button"): # Save all settings to session state st.session_state.update({ 'blog_length': blog_length, 'blog_tone': blog_tone, 'blog_demographic': blog_demographic, 'blog_type': blog_type, 'blog_language': blog_language, 'blog_output_format': blog_output_format, 'image_generation_model': image_generation_model, 'number_of_blog_images': number_of_blog_images, 'gpt_provider': gpt_provider, 'model': model, 'temperature': temperature, 'top_p': top_p, 'max_tokens': max_tokens, 'frequency_penalty': frequency_penalty, 'geographic_location': geographic_location, 'search_language': search_language, 'number_of_results': number_of_results, 'time_range': time_range, 'include_domains': include_domains, 'similar_url': similar_url }) st.success("✅ Settings saved successfully! Your preferences have been applied to all AI tools.") # Show a summary of saved settings st.markdown("""

📋 Settings Summary

Content: {length} words, {tone} tone, {audience} audience

Images: {images} images using {model}

AI Model: {provider} - {ai_model}

Search: {location} region, {results} results

""".format( length=blog_length, tone=blog_tone, audience=blog_demographic, images=number_of_blog_images, model=image_generation_model, provider=gpt_provider, ai_model=model, location=geographic_location, results=number_of_results ), unsafe_allow_html=True)