Getting the twitter dashboard working.

This commit is contained in:
ajaysi
2025-04-16 19:31:51 +05:30
parent f854f0f30e
commit 3a871d4de0
3 changed files with 192 additions and 331 deletions

View File

@@ -1,342 +1,211 @@
import streamlit as st import streamlit as st
import re import streamlit.components.v1 as components
from typing import Dict, List
import json import json
import time
from typing import Dict, List, Tuple, Optional
import random
import emoji
from datetime import datetime
from ....gpt_providers.text_generation.main_text_generation import llm_text_gen from .tweet_generator import smart_tweet_generator
# Constants def load_feature_data() -> Dict:
MAX_TWEET_LENGTH = 280 """Load feature data from a structured format."""
EMOJI_CATEGORIES = {
"Humorous": ["😄", "😂", "🤣", "😊", "😉", "😎", "🤪", "😜", "🤓", "😇"],
"Informative": ["📚", "📊", "📈", "🔍", "💡", "📝", "📋", "🔎", "📖", "📑"],
"Inspirational": ["", "🌟", "💫", "", "🔥", "💪", "🙌", "👏", "💯", "🎯"],
"Serious": ["🤔", "💭", "🧐", "📢", "🔔", "⚖️", "🎓", "📊", "🔬", "📰"],
"Casual": ["👋", "👍", "🙋", "💁", "🤗", "👌", "✌️", "🤝", "👊", "🙏"]
}
def count_characters(text: str) -> int:
"""Count characters in tweet, accounting for emojis."""
return len(text)
def extract_hashtags(text: str) -> List[str]:
"""Extract hashtags from tweet text."""
return re.findall(r'#\w+', text)
def suggest_hashtags(topic: str, tone: str) -> List[str]:
"""Suggest relevant hashtags based on topic and tone."""
# Enhanced hashtag suggestions based on topic and tone
base_hashtags = {
"professional": ["#Business", "#Leadership", "#Innovation"],
"casual": ["#Life", "#Fun", "#Trending"],
"informative": ["#Learn", "#Tips", "#HowTo"],
"humorous": ["#Funny", "#LOL", "#Humor"],
"inspirational": ["#Motivation", "#Success", "#Growth"]
}
topic_hashtags = {
"tech": ["#Technology", "#TechNews", "#Innovation"],
"business": ["#Business", "#Entrepreneurship", "#Startup"],
"marketing": ["#Marketing", "#DigitalMarketing", "#SocialMedia"],
"education": ["#Education", "#Learning", "#Knowledge"],
"health": ["#Health", "#Wellness", "#Fitness"]
}
# Combine base and topic hashtags
suggested = base_hashtags.get(tone.lower(), []) + topic_hashtags.get(topic.lower(), [])
return list(set(suggested))[:5] # Return unique hashtags, max 5
def suggest_emojis(tone: str, count: int = 3) -> List[str]:
"""Suggest emojis based on tone."""
emoji_map = {
"professional": ["💼", "📊", "🎯", "💡", "📈"],
"casual": ["😊", "👍", "🙌", "", "🌟"],
"informative": ["📚", "🔍", "💡", "📝", "🎓"],
"humorous": ["😄", "😂", "🤣", "😉", "😎"],
"inspirational": ["", "🌟", "💫", "🔥", "💪"]
}
return emoji_map.get(tone.lower(), [""])[:count]
def predict_tweet_performance(tweet: str, target_audience: str, tone: str) -> Dict:
"""Predict tweet performance with enhanced metrics."""
char_count = count_characters(tweet)
hashtags = extract_hashtags(tweet)
# Enhanced performance metrics
metrics = {
"character_count": {
"score": min(100, (char_count / 280) * 100),
"status": "optimal" if 100 <= char_count <= 200 else "suboptimal",
"suggestion": "Consider adjusting length for optimal engagement" if char_count < 100 or char_count > 200 else "Length is optimal"
},
"hashtag_usage": {
"score": min(100, (len(hashtags) / 3) * 100),
"status": "optimal" if 1 <= len(hashtags) <= 3 else "suboptimal",
"suggestion": "Add more hashtags" if len(hashtags) < 1 else "Reduce hashtag count" if len(hashtags) > 3 else "Hashtag count is optimal"
},
"engagement_potential": {
"score": 0,
"status": "needs_improvement",
"suggestion": ""
},
"audience_alignment": {
"score": 0,
"status": "needs_improvement",
"suggestion": ""
}
}
# Calculate engagement potential
engagement_triggers = ["?", "!", "RT", "like", "follow", "check", "learn", "discover"]
trigger_count = sum(1 for trigger in engagement_triggers if trigger.lower() in tweet.lower())
metrics["engagement_potential"]["score"] = min(100, (trigger_count / 3) * 100)
metrics["engagement_potential"]["status"] = "optimal" if trigger_count >= 1 else "needs_improvement"
metrics["engagement_potential"]["suggestion"] = "Add engagement triggers" if trigger_count < 1 else "Good engagement potential"
# Calculate audience alignment
audience_keywords = {
"professionals": ["business", "industry", "professional", "career"],
"students": ["learn", "study", "education", "student"],
"general": ["everyone", "people", "community", "world"]
}
keyword_count = sum(1 for keyword in audience_keywords.get(target_audience.lower(), [])
if keyword.lower() in tweet.lower())
metrics["audience_alignment"]["score"] = min(100, (keyword_count / 2) * 100)
metrics["audience_alignment"]["status"] = "optimal" if keyword_count >= 1 else "needs_improvement"
metrics["audience_alignment"]["suggestion"] = "Add audience-specific keywords" if keyword_count < 1 else "Good audience alignment"
# Calculate overall score
overall_score = sum(metric["score"] for metric in metrics.values()) / len(metrics)
return { return {
"metrics": metrics, "tweet_generation": {
"overall_score": overall_score, "title": "Tweet Generation & Optimization",
"status": "excellent" if overall_score >= 80 else "good" if overall_score >= 60 else "fair" if overall_score >= 40 else "needs_improvement" "icon": "🐦",
"description": "Create and optimize engaging tweets with AI assistance",
"features": [
{
"name": "Smart Tweet Generator",
"description": "Generate multiple tweet variations with optimal character count, hashtags, and emojis",
"status": "active",
"icon": "",
"function": smart_tweet_generator
},
{
"name": "Tweet Performance Predictor",
"description": "Predict engagement rates and best posting times for maximum impact",
"status": "coming_soon",
"icon": "📊"
}
]
},
"content_strategy": {
"title": "Content Strategy Tools",
"icon": "📅",
"description": "Plan and manage your Twitter content strategy effectively",
"features": [
{
"name": "Content Calendar Generator",
"description": "Create weekly/monthly content plans with theme-based scheduling",
"status": "coming_soon",
"icon": "🗓️"
},
{
"name": "Hashtag Strategy Manager",
"description": "Research and manage trending hashtags for better reach",
"status": "coming_soon",
"icon": "#️⃣"
}
]
},
"visual_content": {
"title": "Visual Content Creation",
"icon": "🎨",
"description": "Create engaging visual content for your tweets",
"features": [
{
"name": "Image Generator",
"description": "Create tweet cards, infographics, and quote designs",
"status": "coming_soon",
"icon": "🖼️"
},
{
"name": "Video Content Assistant",
"description": "Generate video scripts and optimize captions",
"status": "coming_soon",
"icon": "🎥"
}
]
},
"engagement": {
"title": "Engagement & Community",
"icon": "🤝",
"description": "Manage and enhance community engagement",
"features": [
{
"name": "Reply Generator",
"description": "Generate context-aware responses with appropriate tone",
"status": "coming_soon",
"icon": "💬"
},
{
"name": "Community Tools",
"description": "Create polls and plan Q&A sessions",
"status": "coming_soon",
"icon": "👥"
}
]
},
"analytics": {
"title": "Analytics & Optimization",
"icon": "📈",
"description": "Track performance and optimize your Twitter strategy",
"features": [
{
"name": "Performance Analytics",
"description": "Track tweet performance and engagement metrics",
"status": "coming_soon",
"icon": "📊"
},
{
"name": "A/B Testing Assistant",
"description": "Test and optimize tweet variations for better results",
"status": "coming_soon",
"icon": "🔍"
}
]
},
"research": {
"title": "Research & Intelligence",
"icon": "🔎",
"description": "Gain insights and stay ahead of trends",
"features": [
{
"name": "Market Research",
"description": "Analyze competitors and track industry trends",
"status": "coming_soon",
"icon": "📊"
},
{
"name": "Content Inspiration",
"description": "Get trending topic suggestions and content ideas",
"status": "coming_soon",
"icon": "💡"
}
]
}
} }
def generate_tweet_variations( def render_feature_card(feature: Dict) -> None:
hook: str, """Render a single feature card with its details."""
target_audience: str,
tone: str,
call_to_action: str = "",
keywords: str = "",
length: str = "medium",
num_variations: int = 3
) -> List[Dict]:
"""Generate multiple tweet variations with enhanced AI suggestions."""
# Enhanced prompt template for better AI suggestions
prompt_template = f"""
Create {num_variations} engaging tweet variations with the following parameters:
- Hook/Topic: {hook}
- Target Audience: {target_audience}
- Tone: {tone}
- Call to Action: {call_to_action}
- Keywords: {keywords}
- Length: {length}
Each tweet should:
1. Start with an attention-grabbing hook
2. Include relevant hashtags
3. Use appropriate emojis
4. End with a clear call-to-action
5. Stay within Twitter's character limit
6. Match the specified tone and audience
Format each tweet as a JSON object with:
- text: The tweet content
- hashtags: List of suggested hashtags
- emojis: List of suggested emojis
- engagement_score: Predicted engagement score (0-100)
"""
# Simulate AI-generated tweets (replace with actual AI call)
sample_tweets = [
{
"text": f"🚀 {hook} #Innovation #Tech",
"hashtags": ["#Innovation", "#Tech"],
"emojis": ["🚀"],
"engagement_score": 85
},
{
"text": f"💡 {hook} #Business #Growth",
"hashtags": ["#Business", "#Growth"],
"emojis": ["💡"],
"engagement_score": 75
},
{
"text": f"{hook} #Success #Leadership",
"hashtags": ["#Success", "#Leadership"],
"emojis": [""],
"engagement_score": 80
}
]
return sample_tweets[:num_variations]
def suggest_improvements(tweet: str, performance: Dict) -> List[str]:
"""Generate actionable improvement suggestions."""
suggestions = []
metrics = performance["metrics"]
# Character count suggestions
if metrics["character_count"]["status"] == "suboptimal":
suggestions.append(f"📝 {metrics['character_count']['suggestion']}")
# Hashtag suggestions
if metrics["hashtag_usage"]["status"] == "suboptimal":
suggestions.append(f"#️⃣ {metrics['hashtag_usage']['suggestion']}")
# Engagement suggestions
if metrics["engagement_potential"]["status"] == "needs_improvement":
suggestions.append(f"🎯 {metrics['engagement_potential']['suggestion']}")
# Audience alignment suggestions
if metrics["audience_alignment"]["status"] == "needs_improvement":
suggestions.append(f"👥 {metrics['audience_alignment']['suggestion']}")
return suggestions
def render_tweet_card(tweet: Dict, index: int) -> None:
"""Render an enhanced tweet card with interactive elements."""
with st.container(): with st.container():
st.markdown(f""" st.markdown(f"""
<div style='padding: 20px; border-radius: 10px; background-color: #f0f2f6; margin-bottom: 20px;'> <div style='padding: 20px; border-radius: 10px; background-color: #f0f2f6; margin-bottom: 20px;'>
<h3 style='margin: 0;'>Tweet Variation {index + 1}</h3> <h3 style='margin: 0;'>{feature['icon']} {feature['name']}</h3>
<p style='margin: 10px 0;'>{tweet['text']}</p> <p style='margin: 10px 0;'>{feature['description']}</p>
<div style='display: flex; gap: 10px;'> <span style='background-color: {'#4CAF50' if feature['status'] == 'active' else '#ffd700'};
<span style='background-color: #e1e4e8; padding: 5px 10px; border-radius: 15px; font-size: 0.8em;'> padding: 5px 10px; border-radius: 15px; font-size: 0.8em;'>
Score: {tweet['engagement_score']}% {feature['status'].title()}
</span> </span>
</div>
</div> </div>
""", unsafe_allow_html=True) """, unsafe_allow_html=True)
# Interactive elements
col1, col2 = st.columns(2)
with col1:
if st.button(f"Copy Tweet {index + 1}", key=f"copy_{index}"):
st.write("Tweet copied to clipboard!")
with col2:
if st.button(f"Save Tweet {index + 1}", key=f"save_{index}"):
st.write("Tweet saved!")
def smart_tweet_generator(): def render_category_section(category: Dict) -> None:
"""Enhanced Smart Tweet Generator with improved UI and AI integration.""" """Render a category section with all its features."""
st.title("✨ Smart Tweet Generator") st.markdown(f"### {category['icon']} {category['title']}")
st.markdown("Create engaging tweets with AI-powered optimization") st.markdown(f"*{category['description']}*")
# Input section with improved UI col1, col2 = st.columns(2)
with st.expander("Tweet Parameters", expanded=True): with col1:
col1, col2 = st.columns(2) render_feature_card(category['features'][0])
with col2:
render_feature_card(category['features'][1])
def run_dashboard():
"""Main function to run the Twitter dashboard."""
# Header
st.title("🐦 Twitter AI Writer Dashboard")
st.markdown("""
Welcome to your all-in-one Twitter content creation and management platform.
Explore our AI-powered tools to enhance your Twitter marketing strategy.
""")
# Load feature data
features = load_feature_data()
# Create tabs for different sections
tab1, tab2, tab3 = st.tabs(["🎯 Quick Actions", "📊 Analytics", "⚙️ Settings"])
with tab1:
st.markdown("### 🚀 Quick Actions")
col1, col2, col3 = st.columns(3)
with col1: with col1:
hook = st.text_area("Tweet Hook/Topic", if st.button("📝 Create New Tweet", use_container_width=True):
placeholder="Enter your main message or topic...", # Call the Smart Tweet Generator
help="The main message or topic of your tweet") smart_tweet_generator()
target_audience = st.selectbox(
"Target Audience",
["Professionals", "Students", "General"],
help="Select your target audience"
)
tone = st.radio(
"Tweet Tone",
["Professional", "Casual", "Informative", "Humorous", "Inspirational"],
horizontal=True,
help="Choose the tone for your tweet"
)
with col2: with col2:
call_to_action = st.text_input( st.button("📅 Schedule Content", use_container_width=True)
"Call to Action", with col3:
placeholder="e.g., Learn more, Follow us...", st.button("📊 View Analytics", use_container_width=True)
help="What action do you want your audience to take?"
) with tab2:
st.markdown("### 📈 Analytics Dashboard")
keywords = st.text_input( st.info("Analytics features coming soon! Stay tuned for detailed insights and performance metrics.")
"Keywords/Hashtags",
placeholder="Enter keywords separated by commas", with tab3:
help="Keywords to include in your tweet" st.markdown("### ⚙️ Settings")
) st.info("Settings and configuration options coming soon!")
length = st.select_slider( # Main content area
"Tweet Length", st.markdown("## 🛠️ Available Tools")
options=["short", "medium", "long"],
value="medium",
help="Choose your desired tweet length"
)
num_variations = st.slider(
"Number of Variations",
min_value=1,
max_value=5,
value=3,
help="How many tweet variations would you like to generate?"
)
# Generate button with loading state # Render each category
if st.button("Generate Tweets", use_container_width=True): for category in features.values():
with st.spinner("Generating tweet variations..."): render_category_section(category)
tweets = generate_tweet_variations(
hook, target_audience, tone, # If this is the tweet generation category and the Smart Tweet Generator is active,
call_to_action, keywords, length, # add a button to launch it
num_variations if category["title"] == "Tweet Generation & Optimization" and category["features"][0]["status"] == "active":
) if st.button(f"🚀 Launch {category['features'][0]['name']}", use_container_width=True):
category["features"][0]["function"]()
# Display performance metrics
st.markdown("### 📊 Performance Metrics") # Footer
for tweet in tweets: st.markdown("---")
performance = predict_tweet_performance(tweet["text"], target_audience, tone) st.markdown("""
<div style='text-align: center;'>
# Overall score with progress bar <p>Need help? Check out our <a href='#'>documentation</a> or <a href='#'>contact support</a></p>
st.progress(performance["overall_score"] / 100) </div>
st.metric("Overall Score", f"{performance['overall_score']:.1f}%") """, unsafe_allow_html=True)
# Detailed metrics in columns
cols = st.columns(4)
metrics = performance["metrics"]
with cols[0]:
st.metric("Character Count", f"{metrics['character_count']['score']:.1f}%")
with cols[1]:
st.metric("Hashtag Usage", f"{metrics['hashtag_usage']['score']:.1f}%")
with cols[2]:
st.metric("Engagement", f"{metrics['engagement_potential']['score']:.1f}%")
with cols[3]:
st.metric("Audience Fit", f"{metrics['audience_alignment']['score']:.1f}%")
# Improvement suggestions
suggestions = suggest_improvements(tweet["text"], performance)
if suggestions:
st.markdown("### 💡 Improvement Suggestions")
for suggestion in suggestions:
st.info(suggestion)
# Tweet card
render_tweet_card(tweet, tweets.index(tweet))
st.markdown("---")
# Export options
st.markdown("### 📥 Export Options")
col1, col2 = st.columns(2)
with col1:
if st.button("Export as JSON"):
st.download_button(
"Download JSON",
data=json.dumps(tweets, indent=2),
file_name=f"tweets_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
mime="application/json"
)
with col2:
if st.button("Copy All Tweets"):
tweet_texts = "\n\n".join(tweet["text"] for tweet in tweets)
st.code(tweet_texts)
if __name__ == "__main__": if __name__ == "__main__":
smart_tweet_generator() run_dashboard()

View File

@@ -7,14 +7,6 @@ from ..manager import APIKeyManager
import os import os
from dotenv import load_dotenv # Keep if api_key_manager uses it from dotenv import load_dotenv # Keep if api_key_manager uses it
import sys import sys
# Corrected import: Assuming validation functions are in validation.py in the parent directory
from ..validation import (
test_serpapi_key,
test_tavily_key,
test_metaphor_key,
test_firecrawl_key
# Add others if needed later, e.g., test_bing_key, test_google_search_key
)
# Configure logger (assuming configured elsewhere or keep minimal here) # Configure logger (assuming configured elsewhere or keep minimal here)
logger.add(sys.stderr, level="INFO") # Keep simple example if needed logger.add(sys.stderr, level="INFO") # Keep simple example if needed

View File

@@ -199,7 +199,7 @@ def render_website_setup(api_key_manager: APIKeyManager) -> Dict[str, Any]:
# --- Removed Analysis Section --- # --- Removed Analysis Section ---
# The detailed website analysis should be a separate feature, not part of the initial setup validation. # The detailed website analysis should be a separate feature, not part of the initial setup validation.
st.markdown("--- ---“) st.markdown("---")
st.markdown(" *The detailed Website Analyzer tool is available separately in the main application.*") st.markdown(" *The detailed Website Analyzer tool is available separately in the main application.*")
st.info("Entering your website URL is optional. Click Continue to proceed.") st.info("Entering your website URL is optional. Click Continue to proceed.")