AI Backlinker, Google Ads Generator, Letter Writer - WIP

This commit is contained in:
ajaysi
2025-05-06 22:27:43 +05:30
parent 26b02b9719
commit 5f7d319859
38 changed files with 14572 additions and 302 deletions

View File

@@ -0,0 +1,557 @@
# Blog Outline Generator
A powerful AI-powered tool for generating comprehensive blog outlines with advanced editing capabilities, content generation, and image integration.
## 🛠 Technical Architecture
### Core Components
- **Backend**: Python-based implementation using Streamlit for UI
- **AI Integration**:
- Text Generation: Integration with multiple LLM providers (Gemini, OpenAI, Anthropic)
- Image Generation: Support for multiple image generation APIs (Gemini-AI, Dalle3, Stability-AI)
- **Data Structures**:
```python
class OutlineConfig:
content_type: ContentType
content_depth: ContentDepth
outline_style: OutlineStyle
target_word_count: int
num_main_sections: int
num_subsections_per_section: int
include_images: bool
image_style: str
image_engine: str
```
### Key Technologies
- **Streamlit**: Web application framework
- **Asyncio**: Asynchronous operations for AI calls
- **Loguru**: Advanced logging system
- **BeautifulSoup**: Web content parsing
- **Pydantic**: Data validation
- **Markdown**: Content formatting
## 🌟 Features with Examples
### 1. Content Generation
- **AI-Powered Content Creation**:
```python
# Example prompt for content generation
prompt = f"""
Generate content for a {content_type} article about {topic}.
Target audience: {target_audience}
Word count: {target_word_count}
Style: {outline_style}
"""
content = await llm_text_gen(prompt)
```
- **Multiple Content Types**:
```python
# Example configuration for different content types
config = OutlineConfig(
content_type=ContentType.TUTORIAL,
content_depth=ContentDepth.INTERMEDIATE,
target_word_count=2000
)
```
### 2. Outline Structure
- **Flexible Section Management**:
```python
# Example section generation
async def generate_sections(self, topic: str) -> List[str]:
sections = []
for i in range(self.config.num_main_sections):
section = await self._generate_section(topic, i)
sections.append(section)
return sections
```
- **Optional Components**:
```python
# Example FAQ generation
async def generate_faqs(self, topic: str) -> List[str]:
prompt = f"""
Generate 5 common questions about {topic}
Content type: {self.config.content_type}
Target audience: {self.config.target_audience}
"""
return await llm_text_gen(prompt)
```
### 3. Advanced Editing Capabilities
- **Section Content Editor**:
```python
# Example content editing interface
def edit_section_content(self, section: str, content: str) -> str:
edited_content = st.text_area(
"Edit Content",
value=content,
height=300,
key=f"content_edit_{section}"
)
return edited_content
```
- **Subsection Management**:
```python
# Example subsection reordering
def reorder_subsections(self, section: str, subsections: List[str]) -> List[str]:
for i, subsection in enumerate(subsections):
if st.button("↑", key=f"move_up_{section}_{i}"):
subsections[i], subsections[i-1] = subsections[i-1], subsections[i]
return subsections
```
### 4. Image Generation
- **AI Image Generation**:
```python
# Example image generation
async def generate_image(self, prompt: str, style: str) -> str:
image_prompt = f"""
Create a {style} image for: {prompt}
Style: {self.config.image_style}
"""
return await generate_image(image_prompt)
```
### 5. Content Optimization
- **SEO Features**:
```python
# Example SEO optimization
def optimize_content(self, content: str, keywords: List[str]) -> str:
for keyword in keywords:
content = self._naturally_insert_keyword(content, keyword)
return content
```
## 📊 Technical Implementation Details
### 1. Content Generation Pipeline
```python
async def generate_content(self, topic: str) -> Dict:
# 1. Generate outline structure
outline = await self.generate_outline(topic)
# 2. Generate content for each section
for section in outline:
content = await self.generate_section_content(section)
outline[section]['content'] = content
# 3. Generate images if enabled
if self.config.include_images:
for section in outline:
image = await self.generate_section_image(section)
outline[section]['image'] = image
return outline
```
### 2. AI Integration
```python
class AIIntegration:
def __init__(self, provider: str):
self.provider = provider
self.model = self._initialize_model()
async def generate_text(self, prompt: str) -> str:
if self.provider == "gemini":
return await gemini_text_response(prompt)
elif self.provider == "openai":
return await openai_chatgpt(prompt)
```
### 3. Image Processing
```python
class ImageProcessor:
def __init__(self, engine: str):
self.engine = engine
async def generate_image(self, prompt: str) -> str:
if self.engine == "Gemini-AI":
return await generate_gemini_image(prompt)
elif self.engine == "Dalle3":
return await generate_dalle3_images(prompt)
```
## 🔧 Configuration Examples
### 1. Basic Configuration
```python
config = OutlineConfig(
content_type=ContentType.GUIDE,
content_depth=ContentDepth.INTERMEDIATE,
target_word_count=2000,
num_main_sections=5,
num_subsections_per_section=3
)
```
### 2. Advanced Configuration
```python
config = OutlineConfig(
content_type=ContentType.TUTORIAL,
content_depth=ContentDepth.ADVANCED,
outline_style=OutlineStyle.MODERN,
target_word_count=3000,
include_images=True,
image_style="realistic",
image_engine="Gemini-AI",
target_audience="developers",
language="English",
keywords=["python", "tutorial", "advanced"]
)
```
## 📝 Usage Examples
### 1. Basic Usage
```python
# Initialize generator
generator = BlogOutlineGenerator()
# Generate outline
outline = await generator.generate_outline("Python Programming Basics")
# Export to markdown
markdown = generator.to_markdown()
```
### 2. Advanced Usage
```python
# Custom configuration
config = OutlineConfig(
content_type=ContentType.TUTORIAL,
content_depth=ContentDepth.ADVANCED,
include_images=True
)
# Initialize with config
generator = BlogOutlineGenerator(config)
# Generate with custom settings
outline = await generator.generate_outline(
"Advanced Python Decorators",
keywords=["python", "decorators", "advanced"]
)
# Export to multiple formats
markdown = generator.to_markdown()
json_output = generator.to_json()
html_output = generator.to_html()
```
## 🔍 Technical Considerations
### 1. Performance Optimization
- Asynchronous operations for AI calls
- Caching of generated content
- Batch processing for images
- Memory management for large documents
### 2. Error Handling
```python
try:
content = await llm_text_gen(prompt)
except Exception as e:
logger.error(f"Content generation failed: {e}")
return None
```
### 3. Data Validation
```python
from pydantic import BaseModel, validator
class SectionContent(BaseModel):
title: str
content: str
image_path: Optional[str]
@validator('content')
def validate_content_length(cls, v):
if len(v.split()) < 100:
raise ValueError("Content too short")
return v
```
## 🌟 Features
### 1. Content Generation
- **AI-Powered Content Creation**: Generate high-quality content for each section using advanced language models
- **Multiple Content Types**: Support for various content formats including:
- How-to guides
- Tutorials
- Listicles
- Comparisons
- Case studies
- Opinion pieces
- News articles
- Reviews
- General guides
- **Customizable Content Depth**:
- Basic: Simple, easy-to-understand content
- Intermediate: Balanced depth with practical examples
- Advanced: Detailed technical content
- Expert: In-depth analysis and advanced concepts
### 2. Outline Structure
- **Flexible Section Management**:
- Customizable number of main sections
- Configurable subsections per section
- Dynamic section reordering
- Easy addition/removal of sections
- **Optional Components**:
- Introduction section
- Conclusion section
- FAQ section
- Additional resources section
### 3. Advanced Editing Capabilities
- **Section Content Editor**:
- Rich text editing interface
- Real-time word count tracking
- Formatting options (Bold, Italic, Lists, Code Blocks, Links)
- AI-powered content enhancement
- **Subsection Management**:
- Drag-and-drop reordering
- Individual subsection editing
- Add/remove subsection functionality
- Bulk editing capabilities
- **Metadata Editing**:
- Section-specific settings
- Content depth adjustment
- Target word count configuration
- Image settings customization
### 4. Image Generation
- **AI Image Generation**:
- Multiple image styles (realistic, illustration, minimalist, photographic, artistic)
- Support for multiple image engines (Gemini-AI, Dalle3, Stability-AI)
- Custom image prompts
- Image regeneration capability
- **Image Integration**:
- Automatic image placement
- Image preview and editing
- Image prompt viewing and editing
- Image style customization
### 5. Content Optimization
- **SEO Features**:
- Keyword integration
- Content structure optimization
- Meta description generation
- SEO-friendly formatting
- **Audience Targeting**:
- Customizable target audience
- Language selection
- Content tone adjustment
- Reading level optimization
### 6. Export Options
- **Multiple Formats**:
- Markdown export
- JSON export
- HTML export
- Custom formatting options
- **Download Capabilities**:
- One-click download
- Format-specific styling
- Custom file naming
- Batch export options
### 7. User Interface
- **Intuitive Design**:
- Clean, modern interface
- Responsive layout
- Easy navigation
- Clear visual hierarchy
- **Interactive Features**:
- Real-time preview
- Drag-and-drop functionality
- Quick edit options
- Contextual help
### 8. Statistics and Analytics
- **Content Metrics**:
- Word count tracking
- Section statistics
- Subsection counts
- Content depth analysis
- **Progress Tracking**:
- Generation progress
- Edit history
- Version comparison
- Performance metrics
## 🚀 Getting Started
### Installation
```bash
pip install -r requirements.txt
```
### Usage
1. Launch the application:
```bash
streamlit run lib/ai_writers/ai_outline_writer/outline_ui.py
```
2. Configure your outline:
- Enter your blog topic
- Select content type and depth
- Choose outline style
- Set target word count
- Configure sections and subsections
3. Generate and edit:
- Click "Generate Outline"
- Review and edit sections
- Customize content and images
- Export in your preferred format
## 🔧 Configuration Options
### Basic Settings
- **Blog Topic**: Main subject of your content
- **Content Type**: Type of content to generate
- **Content Depth**: Level of detail and complexity
- **Outline Style**: Structure and formatting style
### Advanced Settings
- **Target Word Count**: Desired length of the content
- **Number of Sections**: Customize main sections
- **Subsections**: Configure subsections per section
- **Image Settings**: Customize image generation
- **Target Audience**: Define your audience
- **Language**: Select content language
- **Keywords**: Add SEO keywords
- **Excluded Topics**: Specify topics to avoid
## 📊 Output Formats
### 1. Preview Mode
- Interactive preview of the entire outline
- Real-time editing capabilities
- Image preview and management
- Content statistics
### 2. Markdown Export
- Clean markdown formatting
- Proper heading hierarchy
- Image embedding
- Code block formatting
### 3. JSON Export
- Structured data format
- Complete outline information
- Content and image metadata
- Configuration details
### 4. HTML Export
- Styled HTML output
- Responsive design
- Image integration
- Custom CSS support
## 💡 Best Practices
### Content Generation
1. Start with a clear topic and target audience
2. Choose appropriate content type and depth
3. Use relevant keywords for SEO
4. Review and edit generated content
5. Add personal insights and examples
### Outline Structure
1. Maintain logical flow between sections
2. Balance section lengths
3. Include relevant subsections
4. Add appropriate transitions
5. Ensure comprehensive coverage
### Image Usage
1. Choose appropriate image styles
2. Generate relevant images
3. Optimize image placement
4. Review image prompts
5. Consider image licensing
## 🔄 Workflow
1. **Initial Setup**
- Configure basic settings
- Set content parameters
- Define target audience
2. **Generation**
- Generate initial outline
- Review structure
- Generate content
- Create images
3. **Editing**
- Review and edit content
- Adjust structure
- Customize images
- Optimize for SEO
4. **Export**
- Choose export format
- Review final output
- Download content
- Save configuration
## 📝 Tips and Tricks
### Content Generation
- Use specific keywords for better results
- Provide clear context for the AI
- Review and refine generated content
- Add personal expertise
### Structure Optimization
- Maintain consistent section lengths
- Use clear subsection hierarchies
- Include relevant examples
- Add practical applications
### Image Enhancement
- Use descriptive image prompts
- Experiment with different styles
- Consider image placement
- Review image relevance
## 🤝 Contributing
We welcome contributions! Please follow these steps:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
## 📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
## 📞 Support
For support, please:
1. Check the documentation
2. Review existing issues
3. Create a new issue if needed
4. Contact the maintainers
## 🔮 Future Enhancements
Planned features:
- Multi-language support
- Advanced AI models
- More export formats
- Enhanced editing tools
- Collaboration features
- Version control integration
- Analytics dashboard
- Custom templates
- API integration
- Mobile optimization

View File

@@ -0,0 +1,336 @@
"""
Enhanced Blog Outline Generator
This module provides a sophisticated outline generation system that creates detailed,
well-structured outlines for blog posts based on user preferences and content requirements.
"""
import sys
from typing import Dict, List, Optional
from enum import Enum
from dataclasses import dataclass
from loguru import logger
from lib.gpt_providers.text_generation.main_text_generation import llm_text_gen
from lib.gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
logger.remove()
logger.add(sys.stdout,
colorize=True,
format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}")
class ContentType(Enum):
"""Types of content that can be generated."""
HOW_TO = "how-to"
TUTORIAL = "tutorial"
LISTICLE = "listicle"
COMPARISON = "comparison"
CASE_STUDY = "case-study"
OPINION = "opinion"
NEWS = "news"
REVIEW = "review"
GUIDE = "guide"
class ContentDepth(Enum):
"""Depth levels for content coverage."""
BASIC = "basic"
INTERMEDIATE = "intermediate"
ADVANCED = "advanced"
EXPERT = "expert"
class OutlineStyle(Enum):
"""Styles for outline structure."""
TRADITIONAL = "traditional"
MODERN = "modern"
CONVERSATIONAL = "conversational"
ACADEMIC = "academic"
SEO_OPTIMIZED = "seo-optimized"
@dataclass
class OutlineConfig:
"""Configuration for outline generation."""
content_type: ContentType = ContentType.GUIDE
content_depth: ContentDepth = ContentDepth.INTERMEDIATE
outline_style: OutlineStyle = OutlineStyle.MODERN
target_word_count: int = 2000
num_main_sections: int = 5
num_subsections_per_section: int = 3
include_introduction: bool = True
include_conclusion: bool = True
include_faqs: bool = True
include_resources: bool = True
target_audience: str = "general"
language: str = "English"
keywords: List[str] = None
exclude_topics: List[str] = None
include_images: bool = True
image_style: str = "realistic"
image_engine: str = "Gemini-AI"
@dataclass
class SectionContent:
"""Content for a section including text and image."""
title: str
content: str
image_prompt: Optional[str] = None
image_path: Optional[str] = None
class BlogOutlineGenerator:
"""Enhanced blog outline generator with comprehensive controls."""
def __init__(self, config: Optional[OutlineConfig] = None):
"""Initialize the outline generator with optional configuration."""
self.config = config or OutlineConfig()
self.outline = {}
self.section_contents = {}
async def generate_outline(self, topic: str) -> Dict:
"""Generate a comprehensive outline based on the topic and configuration."""
try:
# Step 1: Generate main sections
main_sections = await self._generate_main_sections(topic)
# Step 2: Generate subsections for each main section
detailed_sections = await self._generate_subsections(main_sections)
# Step 3: Add introduction and conclusion if requested
if self.config.include_introduction:
detailed_sections["Introduction"] = await self._generate_introduction(topic)
if self.config.include_conclusion:
detailed_sections["Conclusion"] = await self._generate_conclusion(topic)
# Step 4: Add FAQs if requested
if self.config.include_faqs:
detailed_sections["FAQs"] = await self._generate_faqs(topic)
# Step 5: Add resources if requested
if self.config.include_resources:
detailed_sections["Additional Resources"] = await self._generate_resources(topic)
self.outline = detailed_sections
# Step 6: Generate content for each section
await self._generate_section_contents(topic)
return self.outline
except Exception as err:
logger.error(f"Failed to generate outline: {err}")
raise
async def _generate_main_sections(self, topic: str) -> List[str]:
"""Generate main sections for the outline."""
prompt = f"""Generate {self.config.num_main_sections} main sections for a {self.config.content_type.value}
article about {topic} with the following characteristics:
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Target Word Count: {self.config.target_word_count}
Target Audience: {self.config.target_audience}
Style: {self.config.outline_style.value}
Additional Requirements:
- Each section should contribute to the overall word count goal
- Sections should flow logically
- Include key concepts and important points
- Consider SEO optimization
- Keywords to include: {', '.join(self.config.keywords or [])}
- Topics to exclude: {', '.join(self.config.exclude_topics or [])}
Please provide only the section titles, one per line."""
response = await llm_text_gen(prompt)
return [section.strip() for section in response.split('\n') if section.strip()]
async def _generate_subsections(self, main_sections: List[str]) -> Dict[str, List[str]]:
"""Generate subsections for each main section."""
detailed_sections = {}
for section in main_sections:
prompt = f"""Generate {self.config.num_subsections_per_section} subsections for the following section:
{section}
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
Each subsection should:
- Be specific and focused
- Support the main section's topic
- Include key points to cover
- Consider SEO optimization
Please provide only the subsection titles, one per line."""
response = await llm_text_gen(prompt)
detailed_sections[section] = [sub.strip() for sub in response.split('\n') if sub.strip()]
return detailed_sections
async def _generate_introduction(self, topic: str) -> List[str]:
"""Generate introduction subsections."""
prompt = f"""Generate introduction subsections for an article about {topic}.
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
The introduction should:
- Hook the reader
- Present the main topic
- Outline what's to come
- Set the tone for the article
Please provide only the subsection titles, one per line."""
response = await llm_text_gen(prompt)
return [sub.strip() for sub in response.split('\n') if sub.strip()]
async def _generate_conclusion(self, topic: str) -> List[str]:
"""Generate conclusion subsections."""
prompt = f"""Generate conclusion subsections for an article about {topic}.
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
The conclusion should:
- Summarize key points
- Provide final thoughts
- Include a call to action
- Leave a lasting impression
Please provide only the subsection titles, one per line."""
response = await llm_text_gen(prompt)
return [sub.strip() for sub in response.split('\n') if sub.strip()]
async def _generate_faqs(self, topic: str) -> List[str]:
"""Generate FAQ subsections."""
prompt = f"""Generate FAQ subsections for an article about {topic}.
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
The FAQs should:
- Address common questions
- Cover important aspects
- Be relevant to the target audience
- Include both basic and advanced questions
Please provide only the FAQ questions, one per line."""
response = await llm_text_gen(prompt)
return [sub.strip() for sub in response.split('\n') if sub.strip()]
async def _generate_resources(self, topic: str) -> List[str]:
"""Generate resource subsections."""
prompt = f"""Generate resource subsections for an article about {topic}.
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
The resources should:
- Include relevant links
- Suggest further reading
- Provide tools or references
- Include related materials
Please provide only the resource categories, one per line."""
response = await llm_text_gen(prompt)
return [sub.strip() for sub in response.split('\n') if sub.strip()]
async def _generate_section_contents(self, topic: str):
"""Generate content and images for each section."""
for section, subsections in self.outline.items():
if section not in ["Introduction", "Conclusion", "FAQs", "Additional Resources"]:
# Generate content for the main section
content_prompt = f"""Write a detailed section for a blog post about {topic}.
Section Title: {section}
Content Type: {self.config.content_type.value}
Content Depth: {self.config.content_depth.value}
Style: {self.config.outline_style.value}
Target Word Count: {self.config.target_word_count // self.config.num_main_sections}
Include:
- Clear explanation of the main points
- Examples and illustrations
- Key takeaways
- Relevant data or statistics
"""
content = await llm_text_gen(content_prompt)
# Generate image prompt if images are enabled
image_prompt = None
image_path = None
if self.config.include_images:
image_prompt = f"""Create a detailed image prompt for a blog section about {topic}.
Section: {section}
Content: {content[:200]}...
Style: {self.config.image_style}
"""
image_prompt = await llm_text_gen(image_prompt)
try:
image_path = generate_image(
image_prompt,
title=section,
description=content[:100],
tags=self.config.keywords
)
except Exception as err:
logger.warning(f"Failed to generate image for section {section}: {err}")
self.section_contents[section] = SectionContent(
title=section,
content=content,
image_prompt=image_prompt,
image_path=image_path
)
def to_markdown(self) -> str:
"""Convert outline to markdown format with content and images."""
markdown = f"# {self.outline.get('Introduction', [''])[0]}\n\n"
for section, subsections in self.outline.items():
if section not in ["Introduction", "Conclusion", "FAQs", "Additional Resources"]:
markdown += f"## {section}\n\n"
# Add section content if available
if section in self.section_contents:
content = self.section_contents[section]
markdown += f"{content.content}\n\n"
# Add image if available
if content.image_path:
markdown += f"![{section}]({content.image_path})\n\n"
# Add subsections
for subsection in subsections:
markdown += f"- {subsection}\n"
markdown += "\n"
if "Conclusion" in self.outline:
markdown += "## Conclusion\n\n"
for subsection in self.outline["Conclusion"]:
markdown += f"- {subsection}\n"
markdown += "\n"
if "FAQs" in self.outline:
markdown += "## Frequently Asked Questions\n\n"
for faq in self.outline["FAQs"]:
markdown += f"- {faq}\n"
markdown += "\n"
if "Additional Resources" in self.outline:
markdown += "## Additional Resources\n\n"
for resource in self.outline["Additional Resources"]:
markdown += f"- {resource}\n"
return markdown

View File

@@ -0,0 +1,489 @@
"""
Streamlit UI for Enhanced Blog Outline Generator
This module provides a user-friendly interface for generating comprehensive blog outlines
with AI-powered content and image generation capabilities.
"""
import streamlit as st
import asyncio
from pathlib import Path
from typing import Optional, Dict, List
import json
import time
from datetime import datetime
from .get_blog_outline import (
BlogOutlineGenerator,
OutlineConfig,
ContentType,
ContentDepth,
OutlineStyle
)
# Custom CSS for better styling
st.markdown("""
<style>
.main {
background-color: #f5f5f5;
}
.stButton>button {
background-color: #4CAF50;
color: white;
padding: 10px 24px;
border-radius: 4px;
border: none;
font-weight: bold;
}
.stButton>button:hover {
background-color: #45a049;
}
.section-card {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.content-preview {
background-color: #f8f9fa;
padding: 15px;
border-radius: 4px;
margin: 10px 0;
}
.image-container {
display: flex;
justify-content: center;
margin: 20px 0;
}
.stats-card {
background-color: #e8f5e9;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
}
.edit-section {
background-color: #e3f2fd;
padding: 15px;
border-radius: 4px;
margin: 10px 0;
}
.subsection-list {
margin-left: 20px;
}
</style>
""", unsafe_allow_html=True)
def edit_section_content(section: str, content: str) -> str:
"""Edit section content with advanced options."""
st.markdown('<div class="edit-section">', unsafe_allow_html=True)
# Content editing
edited_content = st.text_area(
"Edit Content",
value=content,
height=300,
key=f"content_edit_{section}"
)
# Word count and formatting
col1, col2 = st.columns(2)
with col1:
word_count = len(edited_content.split())
st.info(f"Word Count: {word_count}")
with col2:
formatting = st.multiselect(
"Formatting Options",
["Bold", "Italic", "Lists", "Code Blocks", "Links"],
key=f"format_{section}"
)
# AI enhancement options
with st.expander("AI Enhancement Options"):
enhance_options = st.multiselect(
"Select Enhancements",
["Improve Clarity", "Add Examples", "Expand Details", "Add Statistics", "Improve SEO"],
key=f"enhance_{section}"
)
if st.button("Apply Enhancements", key=f"apply_enhance_{section}"):
with st.spinner("Applying enhancements..."):
# TODO: Implement AI enhancement logic
st.success("Enhancements applied!")
st.markdown('</div>', unsafe_allow_html=True)
return edited_content
def edit_subsections(section: str, subsections: List[str]) -> List[str]:
"""Edit subsections with reordering and editing capabilities."""
st.markdown('<div class="edit-section">', unsafe_allow_html=True)
# Reorder subsections
st.markdown("### Reorder Subsections")
for i, subsection in enumerate(subsections):
col1, col2 = st.columns([4, 1])
with col1:
subsections[i] = st.text_input(
f"Subsection {i+1}",
value=subsection,
key=f"subsection_{section}_{i}"
)
with col2:
if st.button("", key=f"move_up_{section}_{i}") and i > 0:
subsections[i], subsections[i-1] = subsections[i-1], subsections[i]
st.experimental_rerun()
if st.button("", key=f"move_down_{section}_{i}") and i < len(subsections)-1:
subsections[i], subsections[i+1] = subsections[i+1], subsections[i]
st.experimental_rerun()
# Add/remove subsections
col1, col2 = st.columns(2)
with col1:
if st.button("Add Subsection", key=f"add_sub_{section}"):
subsections.append("New Subsection")
st.experimental_rerun()
with col2:
if st.button("Remove Last Subsection", key=f"remove_sub_{section}"):
if subsections:
subsections.pop()
st.experimental_rerun()
st.markdown('</div>', unsafe_allow_html=True)
return subsections
def edit_section_metadata(section: str, generator: BlogOutlineGenerator):
"""Edit section metadata and settings."""
st.markdown('<div class="edit-section">', unsafe_allow_html=True)
# Section settings
st.markdown("### Section Settings")
# Image settings
if generator.config.include_images:
col1, col2 = st.columns(2)
with col1:
new_image_style = st.selectbox(
"Image Style",
["realistic", "illustration", "minimalist", "photographic", "artistic"],
key=f"img_style_{section}"
)
with col2:
new_image_engine = st.selectbox(
"Image Engine",
["Gemini-AI", "Dalle3", "Stability-AI"],
key=f"img_engine_{section}"
)
if st.button("Regenerate Image", key=f"regen_img_{section}"):
with st.spinner("Regenerating image..."):
# TODO: Implement image regeneration logic
st.success("Image regenerated!")
# Content settings
st.markdown("### Content Settings")
col1, col2 = st.columns(2)
with col1:
target_word_count = st.number_input(
"Target Word Count",
min_value=100,
max_value=2000,
value=500,
step=100,
key=f"word_count_{section}"
)
with col2:
content_depth = st.selectbox(
"Content Depth",
[depth.value for depth in ContentDepth],
key=f"depth_{section}"
)
st.markdown('</div>', unsafe_allow_html=True)
def display_section(section: str, subsections: List[str], content: Optional[Dict] = None, generator: Optional[BlogOutlineGenerator] = None):
"""Display a section with its content and subsections."""
st.markdown(f"""
<div class="section-card">
<h2>{section}</h2>
""", unsafe_allow_html=True)
# Section editing controls
col1, col2 = st.columns([4, 1])
with col1:
st.markdown(f"### {section}")
with col2:
edit_mode = st.checkbox("Edit Mode", key=f"edit_mode_{section}")
if content:
# Display content with word count
word_count = len(content.content.split())
st.markdown(f"""
<div class="content-preview">
<p><strong>Content Preview</strong> ({word_count} words)</p>
{content.content[:500]}...
</div>
""", unsafe_allow_html=True)
# Display image if available
if content.image_path:
st.markdown('<div class="image-container">', unsafe_allow_html=True)
st.image(content.image_path, caption=section, use_column_width=True)
st.markdown('</div>', unsafe_allow_html=True)
# Display image prompt in expander
if content.image_prompt:
with st.expander("View Image Prompt"):
st.code(content.image_prompt, language="text")
# Edit mode controls
if edit_mode:
# Edit content
edited_content = edit_section_content(section, content.content)
content.content = edited_content
# Edit subsections
edited_subsections = edit_subsections(section, subsections)
subsections[:] = edited_subsections
# Edit metadata
if generator:
edit_section_metadata(section, generator)
# Display subsections
st.markdown("### Subsections")
st.markdown('<div class="subsection-list">', unsafe_allow_html=True)
for subsection in subsections:
st.markdown(f"- {subsection}")
st.markdown('</div>', unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)
def display_stats(generator, outline):
"""Display statistics about the generated outline."""
total_sections = len(outline)
total_subsections = sum(len(subsections) for subsections in outline.values())
total_content = sum(len(content.content.split()) for content in generator.section_contents.values())
col1, col2, col3 = st.columns(3)
with col1:
st.markdown(f"""
<div class="stats-card">
<h3>📊 Statistics</h3>
<p>Total Sections: {total_sections}</p>
<p>Total Subsections: {total_subsections}</p>
<p>Estimated Word Count: {total_content}</p>
</div>
""", unsafe_allow_html=True)
with col2:
st.markdown(f"""
<div class="stats-card">
<h3>🎯 Target</h3>
<p>Target Word Count: {generator.config.target_word_count}</p>
<p>Content Depth: {generator.config.content_depth.value}</p>
<p>Style: {generator.config.outline_style.value}</p>
</div>
""", unsafe_allow_html=True)
with col3:
st.markdown(f"""
<div class="stats-card">
<h3>📝 Content Type</h3>
<p>Type: {generator.config.content_type.value}</p>
<p>Audience: {generator.config.target_audience}</p>
<p>Language: {generator.config.language}</p>
</div>
""", unsafe_allow_html=True)
def main():
st.set_page_config(
page_title="Blog Outline Generator",
page_icon="📝",
layout="wide",
initial_sidebar_state="expanded"
)
# Header with description
st.title("Blog Outline Generator")
st.markdown("""
Generate comprehensive blog outlines with AI-powered content and images.
Customize your outline with various options and get detailed content for each section.
""")
# Sidebar for configuration
with st.sidebar:
st.header("Configuration")
# Basic settings
topic = st.text_input("Blog Topic", placeholder="Enter your blog topic")
content_type = st.selectbox(
"Content Type",
[type.value for type in ContentType]
)
content_depth = st.selectbox(
"Content Depth",
[depth.value for depth in ContentDepth]
)
outline_style = st.selectbox(
"Outline Style",
[style.value for style in OutlineStyle]
)
# Content structure
st.subheader("Content Structure")
target_word_count = st.slider("Target Word Count", 500, 5000, 2000, 100)
num_main_sections = st.slider("Number of Main Sections", 3, 10, 5)
num_subsections = st.slider("Subsections per Section", 2, 5, 3)
# Advanced settings
with st.expander("Advanced Settings"):
include_intro = st.checkbox("Include Introduction", value=True)
include_conclusion = st.checkbox("Include Conclusion", value=True)
include_faqs = st.checkbox("Include FAQs", value=True)
include_resources = st.checkbox("Include Resources", value=True)
# Image settings
st.subheader("Image Settings")
include_images = st.checkbox("Include Images", value=True)
if include_images:
image_style = st.selectbox(
"Image Style",
["realistic", "illustration", "minimalist", "photographic", "artistic"]
)
image_engine = st.selectbox(
"Image Engine",
["Gemini-AI", "Dalle3", "Stability-AI"]
)
# Target audience and language
st.subheader("Target Audience")
target_audience = st.text_input("Target Audience", value="general")
language = st.text_input("Language", value="English")
# Keywords and exclusions
st.subheader("Content Optimization")
keywords = st.text_area("Keywords (comma-separated)")
exclude_topics = st.text_area("Topics to Exclude (comma-separated)")
# Main content area
if topic:
# Create configuration
config = OutlineConfig(
content_type=ContentType(content_type),
content_depth=ContentDepth(content_depth),
outline_style=OutlineStyle(outline_style),
target_word_count=target_word_count,
num_main_sections=num_main_sections,
num_subsections_per_section=num_subsections,
include_introduction=include_intro,
include_conclusion=include_conclusion,
include_faqs=include_faqs,
include_resources=include_resources,
include_images=include_images,
image_style=image_style if include_images else "realistic",
image_engine=image_engine if include_images else "Gemini-AI",
target_audience=target_audience,
language=language,
keywords=[k.strip() for k in keywords.split(',')] if keywords else None,
exclude_topics=[t.strip() for t in exclude_topics.split(',')] if exclude_topics else None
)
# Initialize generator
generator = BlogOutlineGenerator(config)
# Generate outline
if st.button("Generate Outline"):
with st.spinner("Generating outline and content..."):
try:
# Add progress bar
progress_bar = st.progress(0)
for i in range(100):
time.sleep(0.01)
progress_bar.progress(i + 1)
outline = asyncio.run(generator.generate_outline(topic))
# Display results
st.success("Outline generated successfully!")
# Display statistics
display_stats(generator, outline)
# Output format selection
output_format = st.radio(
"Output Format",
["Preview", "Markdown", "JSON", "HTML"]
)
if output_format == "Preview":
# Display outline with content and images
for section, subsections in outline.items():
content = generator.section_contents.get(section)
display_section(section, subsections, content)
elif output_format == "Markdown":
st.code(generator.to_markdown(), language="markdown")
st.download_button(
"Download Markdown",
generator.to_markdown(),
file_name="blog_outline.md",
mime="text/markdown"
)
elif output_format == "JSON":
json_output = json.dumps({
"outline": outline,
"contents": {
section: {
"title": content.title,
"content": content.content,
"image_prompt": content.image_prompt,
"image_path": content.image_path
}
for section, content in generator.section_contents.items()
}
}, indent=2)
st.code(json_output, language="json")
st.download_button(
"Download JSON",
json_output,
file_name="blog_outline.json",
mime="application/json"
)
elif output_format == "HTML":
# Add HTML export functionality
html_output = f"""
<!DOCTYPE html>
<html>
<head>
<title>{topic} - Blog Outline</title>
<style>
body {{ font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }}
.section {{ margin-bottom: 30px; }}
.content {{ background: #f8f9fa; padding: 15px; border-radius: 4px; }}
img {{ max-width: 100%; height: auto; }}
</style>
</head>
<body>
<h1>{topic}</h1>
{generator.to_markdown().replace('#', '##')}
</body>
</html>
"""
st.code(html_output, language="html")
st.download_button(
"Download HTML",
html_output,
file_name="blog_outline.html",
mime="text/html"
)
except Exception as e:
st.error(f"Error generating outline: {str(e)}")
else:
st.info("Please enter a blog topic to get started.")
if __name__ == "__main__":
main()