diff --git a/README.md b/README.md
index e8c50836..86e7514b 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,7 @@ Our toolkit integrates **(OpenAI, Gemini, Anthropic)** AI models for text genera
- 
- 
- RoadMap - Coming Soon..
+- Present Focus: Nextjs react Alwrity App - Coming Soon..
---
> 
diff --git a/alwrity.py b/alwrity.py
index 977b1dae..785dc930 100644
--- a/alwrity.py
+++ b/alwrity.py
@@ -3,98 +3,25 @@ import os
import json
import base64
from datetime import datetime
-import streamlit as st
-from lib.utils.environment_utils import load_environment
+from dotenv import load_dotenv
+
from lib.utils.config_manager import save_config
from lib.utils.ui_setup import setup_ui
from lib.utils.api_key_manager import check_api_keys, check_llm_environs
from lib.utils.content_generators import ai_writers, content_planning_tools, blog_from_keyword, story_input_section, essay_writer, ai_news_writer, ai_finance_ta_writer, write_ai_prod_desc, do_web_research, competitor_analysis, ai_agents_content_planner
from lib.utils.seo_tools import ai_seo_tools
+from lib.utils.ui_setup import setup_ui, setup_tabs
from lib.utils.alwrity_utils import ai_agents_team, ai_social_writer
from lib.utils.file_processor import load_image, read_prompts, write_prompts
from lib.utils.voice_processing import record_voice
-# Placeholder function definitions for missing functions
-def blog_from_audio():
- """Placeholder for the blog_from_audio function."""
- st.write("This is a placeholder for the blog_from_audio function.")
+
def process_folder_for_rag(folder_path):
"""Placeholder for the process_folder_for_rag function."""
st.write(f"This is a placeholder for processing the folder: {folder_path}")
-@st.cache_data
-def check_api_keys():
- """
- Checks if the required API keys are present in the environment variables.
- Prompts the user to enter missing keys and saves them in the .env file.
- """
- api_keys = {
- "METAPHOR_API_KEY": "https://dashboard.exa.ai/login",
- "TAVILY_API_KEY": "https://tavily.com/#api",
- "SERPER_API_KEY": "https://serper.dev/signup",
- "STABILITY_API_KEY": "https://platform.stability.ai/",
- "FIRECRAWL_API_KEY": "https://www.firecrawl.dev/account"
- }
-
- missing_keys = {
- key: url for key, url in api_keys.items() if os.getenv(key) is None
- }
-
- if missing_keys:
- st.error("๐จ Some API keys are missing! Please provide them below:")
- for key, url in missing_keys.items():
- api_key = st.text_input(f"Enter ๐ {key}: ๐[Get it here]({url})๐")
- if api_key:
- os.environ[key] = api_key
- try:
- with open(".env", "a") as env_file:
- env_file.write(f"{key}={api_key}\n")
- except IOError as e:
- st.error(f"Failed to write {key} to .env file: {e}")
- st.success(f"โ
{key} added successfully!")
- return False
- return True
-
-
-@st.cache_data
-def check_llm_environs():
- """
- Ensures that the LLM provider and corresponding API key are set.
- Prompts the user to select a provider and enter the API key if missing.
- """
- gpt_provider = os.getenv("GPT_PROVIDER")
- supported_providers = {
- 'google': "GEMINI_API_KEY",
- 'openai': "OPENAI_API_KEY",
- 'mistralai': "MISTRAL_API_KEY"
- }
-
- if not gpt_provider or gpt_provider.lower() not in supported_providers:
- gpt_provider = st.selectbox(
- "Select your LLM Provider", options=list(supported_providers.keys())
- )
- os.environ["GPT_PROVIDER"] = gpt_provider
- try:
- with open(".env", "a") as env_file:
- env_file.write(f"GPT_PROVIDER={gpt_provider}\n")
- except IOError as e:
- st.error(f"Failed to write GPT_PROVIDER to .env file: {e}")
- st.success(f"GPT Provider set to {gpt_provider}")
-
- api_key_var = supported_providers[gpt_provider.lower()]
- if not os.getenv(api_key_var):
- api_key = st.text_input(f"Enter {api_key_var}:")
- if api_key:
- os.environ[api_key_var] = api_key
- with open(".env", "a") as env_file:
- env_file.write(f"{api_key_var}={api_key}\n")
- st.success(f"{api_key_var} added successfully!")
- return False
- return True
-
-
def save_config(config):
"""
Saves the provided configuration dictionary to a JSON file specified by the environment variable.
@@ -281,30 +208,10 @@ def sidebar_configuration():
-# Function to read prompts from the file
-@st.cache_data
-def read_prompts(file_path="prompt_llm.txt"):
- if os.path.exists(file_path):
- with open(file_path, "r") as file:
- prompts = file.readlines()
- return [prompt.strip() for prompt in prompts]
- return []
-
-# Function to write prompts to the file
-def write_prompts(prompts, file_path="prompt_llm.txt"):
- with open(file_path, "w") as file:
- for prompt in prompts:
- file.write(f"{prompt}\n")
-
-# Function to load and encode the image file
-def load_image(image_path):
- with open(image_path, "rb") as img_file:
- b64_string = base64.b64encode(img_file.read()).decode()
- return b64_string
-
-
def main():
- load_environment()
+ #load_environment
+ from dotenv import load_dotenv
+ load_dotenv()
setup_ui()
setup_environment_paths()
sidebar_configuration()
@@ -314,26 +221,6 @@ def main():
modify_prompts_sidebar()
-def setup_ui():
- """Sets up the Streamlit UI with custom CSS and logo."""
- try:
- css_file_path = os.path.join('lib', 'workspace', 'alwrity_ui_styling.css')
- with open(css_file_path) as f:
- custom_css = f.read()
- st.set_page_config(page_title="Alwrity", layout="wide")
- st.markdown(f'', unsafe_allow_html=True)
- except Exception as err:
- st.error(f"Failed in setting up Alwrity Streamlit UI: {err}")
-
- image_base64 = load_image("lib/workspace/alwrity_logo.png")
- st.markdown(f"""
-
-

- Welcome to Alwrity!
-
- """, unsafe_allow_html=True)
-
-
def setup_environment_paths():
"""Sets up environment paths for saving files and configurations."""
os.environ["SEARCH_SAVE_FILE"] = os.path.join(os.getcwd(), "lib", "workspace", "alwrity_web_research",
@@ -344,32 +231,6 @@ def setup_environment_paths():
os.environ["ALWRITY_CONFIG"] = os.path.join(os.getcwd(), "lib", "workspace", "alwrity_config", "main_config.json")
-def setup_tabs():
- """Sets up the main tabs in the Streamlit app."""
- tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(
- ["๐
Content Planning", " ๐๐คAI Writers", "๐ค๐คAgents Teams", "๐ ๏ธ๐AI SEO tools", "๐ฑAI Social Tools", " ๐ฌAsk Alwrity"])
- with tab1:
- content_planning_tools()
-
- with tab2:
- ai_writers()
-
- with tab3:
- ai_agents_team()
-
- with tab4:
- ai_seo_tools()
-
- with tab5:
- ai_social_writer()
-
- with tab6:
- st.subheader("Chat with your Data, Chat with any Data.. COMING SOON !")
- st.markdown("Create a collection by uploading files (PDF, MD, CSV, etc), or crawl a data source (Websites, more sources coming soon.")
- st.markdown("One can ask/chat, summarize and do semantic search over the uploaded data")
- # alwrity_chat_docqa()
-
-
def modify_prompts_sidebar():
"""Provides a sidebar for modifying prompts."""
st.sidebar.title("๐ Modify Prompts")
diff --git a/lib/ai_marketing_tools/.ai_backlinking.py.swp b/lib/ai_marketing_tools/.ai_backlinking.py.swp
new file mode 100644
index 00000000..887420ef
Binary files /dev/null and b/lib/ai_marketing_tools/.ai_backlinking.py.swp differ
diff --git a/lib/ai_marketing_tools/ai_backlinking.py b/lib/ai_marketing_tools/ai_backlinking.py
new file mode 100644
index 00000000..d2c1b00a
--- /dev/null
+++ b/lib/ai_marketing_tools/ai_backlinking.py
@@ -0,0 +1,302 @@
+#Problem:
+#
+#Finding websites for guest posts is manual, tedious, and time-consuming. Communicating with webmasters, maintaining conversations, and keeping track of backlinking opportunities is difficult to scale. Content creators and marketers struggle with discovering new websites and consistently getting backlinks.
+#Solution:
+#
+#An AI-powered backlinking app that automates web research, scrapes websites, extracts contact information, and sends personalized outreach emails to webmasters. This would simplify the entire process, allowing marketers to scale their backlinking strategy with minimal manual intervention.
+#Core Workflow:
+#
+# User Input:
+# Keyword Search: The user inputs a keyword (e.g., "AI writers").
+# Search Queries: Your app will append various search strings to this keyword to find backlinking opportunities (e.g., "AI writers + 'Write for Us'").
+#
+# Web Research:
+#
+# Use search engines or web scraping to run multiple queries:
+# Keyword + "Guest Contributor"
+# Keyword + "Add Guest Post"
+# Keyword + "Write for Us", etc.
+#
+# Collect URLs of websites that have pages or posts related to guest post opportunities.
+#
+# Scrape Website Data:
+# Contact Information Extraction:
+# Scrape the website for contact details (email addresses, contact forms, etc.).
+# Use natural language processing (NLP) to understand the type of content on the website and who the contact person might be (webmaster, editor, or guest post manager).
+# Website Content Understanding:
+# Scrape a summary of each websiteโs content (e.g., their blog topics, categories, and tone) to personalize the email based on the site's focus.
+#
+# Personalized Outreach:
+# AI Email Composition:
+# Compose personalized outreach emails based on:
+# The scraped data (website content, topic focus, etc.).
+# The user's input (what kind of guest post or content they want to contribute).
+# Example: โHi [Webmaster Name], I noticed that your site [Site Name] features high-quality content about [Topic]. I would love to contribute a guest post on [Proposed Topic] in exchange for a backlink.โ
+#
+# Automated Email Sending:
+# Review Emails (Optional HITL):
+# Let users review and approve the personalized emails before they are sent, or allow full automation.
+# Send Emails:
+# Automate email dispatch through an integrated SMTP or API (e.g., Gmail API, SendGrid).
+# Keep track of which emails were sent, bounced, or received replies.
+#
+# Scaling the Search:
+# Repeat for Multiple Keywords:
+# Run the same scraping and outreach process for a list of relevant keywords, either automatically suggested or uploaded by the user.
+# Keep Track of Sent Emails:
+# Maintain a log of all sent emails, responses, and follow-up reminders to avoid repetition or forgotten leads.
+#
+# Tracking Responses and Follow-ups:
+# Automated Responses:
+# If a website replies positively, AI can respond with predefined follow-up emails (e.g., proposing topics, confirming submission deadlines).
+# Follow-up Reminders:
+# If thereโs no reply, the system can send polite follow-up reminders at pre-set intervals.
+#
+#Key Features:
+#
+# Automated Web Scraping:
+# Scrape websites for guest post opportunities using a predefined set of search queries based on user input.
+# Extract key information like email addresses, names, and submission guidelines.
+#
+# Personalized Email Writing:
+# Leverage AI to create personalized emails using the scraped website information.
+# Tailor each email to the tone, content style, and focus of the website.
+#
+# Email Sending Automation:
+# Integrate with email platforms (e.g., Gmail, SendGrid, or custom SMTP).
+# Send automated outreach emails with the ability for users to review first (HITL - Human-in-the-loop) or automate completely.
+#
+# Customizable Email Templates:
+# Allow users to customize or choose from a set of email templates for different types of outreach (e.g., guest post requests, follow-up emails, submission offers).
+#
+# Lead Tracking and Management:
+# Track all emails sent, monitor replies, and keep track of successful backlinks.
+# Log each leadโs status (e.g., emailed, responded, no reply) to manage future interactions.
+#
+# Multiple Keywords/Queries:
+# Allow users to run the same process for a batch of keywords, automatically generating relevant search queries for each.
+#
+# AI-Driven Follow-Up:
+# Schedule follow-up emails if there is no response after a specified period.
+#
+# Reports and Analytics:
+# Provide users with reports on how many emails were sent, opened, replied to, and successful backlink placements.
+#
+#Advanced Features (for Scaling and Optimization):
+#
+# Domain Authority Filtering:
+# Use SEO APIs (e.g., Moz, Ahrefs) to filter websites based on their domain authority or backlink strength.
+# Prioritize high-authority websites to maximize the impact of backlinks.
+#
+# Spam Detection:
+# Use AI to detect and avoid spammy or low-quality websites that might harm the userโs SEO.
+#
+# Contact Form Auto-Fill:
+# If the site only offers a contact form (without email), automatically fill and submit the form with AI-generated content.
+#
+# Dynamic Content Suggestions:
+# Suggest guest post topics based on the websiteโs focus, using NLP to analyze the site's existing content.
+#
+# Bulk Email Support:
+# Allow users to bulk-send outreach emails while still personalizing each message for scalability.
+#
+# AI Copy Optimization:
+# Use copywriting AI to optimize email content, adjusting tone and CTA based on the target audience.
+#
+#Challenges and Considerations:
+#
+# Legal Compliance:
+# Ensure compliance with anti-spam laws (e.g., CAN-SPAM, GDPR) by including unsubscribe options or manual email approval.
+#
+# Scraping Limits:
+# Be mindful of scraping limits on certain websites and employ smart throttling or use API-based scraping for better reliability.
+#
+# Deliverability:
+# Ensure emails are delivered properly without landing in spam folders by integrating proper email authentication (SPF, DKIM) and using high-reputation SMTP servers.
+#
+# Maintaining Email Personalization:
+# Striking the balance between automating the email process and keeping each message personal enough to avoid being flagged as spam.
+#
+#Technology Stack:
+#
+# Web Scraping: BeautifulSoup, Scrapy, or Puppeteer for scraping guest post opportunities and contact information.
+# Email Automation: Integrate with Gmail API, SendGrid, or Mailgun for sending emails.
+# NLP for Personalization: GPT-based models for email generation and web content understanding.
+# Frontend: React or Vue for the user interface.
+# Backend: Python/Node.js with Flask or Express for the API and automation logic.
+# Database: MongoDB or PostgreSQL to track leads, emails, and responses.
+#
+#This solution will significantly streamline the backlinking process by automating the most tedious tasks, from finding sites to personalizing outreach, enabling marketers to focus on content creation and high-level strategies.
+
+
+import sys
+from googlesearch import search
+from loguru import logger
+# Configure logger
+logger.remove()
+logger.add(sys.stdout,
+ colorize=True,
+ format="{level}|{file}:{line}:{function}| {message}"
+ )
+
+from lib.ai_web_researcher.firecrawl_web_crawler import scrape_website
+from lib.gpt_providers.text_generation.main_text_generation import llm_text_gen
+from lib.ai_web_researcher.firecrawl_web_crawler import scrape_url
+
+
+def generate_search_queries(keyword):
+ """
+ Generate a list of search queries for finding guest post opportunities.
+
+ Args:
+ keyword (str): The keyword to base the search queries on.
+
+ Returns:
+ list: A list of search queries.
+ """
+ return [
+ f"{keyword} + 'Guest Contributor'",
+# f"{keyword} + 'Add Guest Post'",
+# f"{keyword} + 'Guest Bloggers Wanted'",
+# f"{keyword} + 'Write for Us'",
+# f"{keyword} + 'Submit Guest Post'",
+# f"{keyword} + 'Become a Guest Blogger'",
+# f"{keyword} + 'guest post opportunities'",
+# f"{keyword} + 'Submit article'",
+ ]
+
+
+def find_backlink_opportunities(keyword):
+ """
+ Find backlink opportunities by scraping websites based on search queries.
+
+ Args:
+ keyword (str): The keyword to search for backlink opportunities.
+
+ Returns:
+ list: A list of results from the scraped websites.
+ """
+ search_queries = generate_search_queries(keyword)
+ results = []
+
+ for query in search_queries:
+ urls = search_for_urls(query)
+ for url in urls:
+ website_data = scrape_website(url)
+ logger.info(f"Scraped Website content for {url}: {website_data}")
+ if website_data:
+ contact_info = extract_contact_info(website_data)
+ logger.info("Contact details found for {url}: [contact_info]")
+
+ # AI-driven insights using website data
+ insights_prompt = f"""
+You are an expert in analyzing website content. Below is the content of a website. Please analyze it and provide actionable insights for a personalized guest post outreach:
+
+Website Content:
+{website_data.get("content_summary", "")}
+
+1. **Website Focus**: What is the primary topic, audience, and tone?
+2. **Guest Posting Guidelines**: Are there any guest post preferences (content type, length, etc.)?
+3. **Suggested Topics**: Based on the siteโs content, what topics might align well?
+4. **Personalization Tips**: How can we make the outreach more tailored to this site?
+"""
+
+ insights = llm_text_gen(insights_prompt)
+
+ detailed_result = {
+ "url": url,
+ "metadata": {
+ "title": website_data.get("metadata", {}).get("title", ""),
+ "description": website_data.get("metadata", {}).get("description", ""),
+ "keywords": website_data.get("metadata", {}).get("keywords", []),
+ },
+ "content_summary": website_data.get("content_summary", ""),
+ "contact_info": contact_info,
+ "insights": insights,
+ "backlink_opportunity": {
+ "query": query,
+ "context": "Guest post opportunity"
+ }
+ }
+ results.append(detailed_result)
+
+ return results
+
+
+def compose_personalized_email(website_data, insights, user_proposal):
+ """
+ Compose a personalized outreach email using AI LLM based on website data, insights, and user proposal.
+
+ Args:
+ website_data (dict): The data of the website including metadata and contact info.
+ insights (str): Insights generated by the LLM about the website.
+ user_proposal (dict): The user's proposal for a guest post or content contribution.
+
+ Returns:
+ str: A personalized email message.
+ """
+ contact_name = website_data.get("contact_info", {}).get("name", "Webmaster")
+ site_name = website_data.get("metadata", {}).get("title", "your site")
+ proposed_topic = user_proposal.get("topic", "a guest post")
+ user_name = user_proposal.get("user_name", "Your Name")
+ user_email = user_proposal.get("user_email", "your_email@example.com")
+
+ # Refined prompt for email generation
+ email_prompt = f"""
+You are an AI assistant tasked with composing a highly personalized outreach email for guest posting.
+
+Contact Name: {contact_name}
+Website Name: {site_name}
+Proposed Topic: {proposed_topic}
+
+User Details:
+Name: {user_name}
+Email: {user_email}
+
+Website Insights: {insights}
+
+Please compose a professional and engaging email that includes:
+1. A personalized introduction addressing the recipient.
+2. A mention of the website's content focus.
+3. A proposal for a guest post.
+4. A call to action to discuss the guest post opportunity.
+5. A polite closing with user contact details.
+"""
+
+ return llm_text_gen(email_prompt)
+
+
+def search_for_urls(query):
+ """
+ Search for URLs based on a query using Firecrawl.
+
+ Args:
+ query (str): The search query.
+
+ Returns:
+ list: A list of URLs.
+ """
+ # We can use Firecrawl, which also provides AI extraction.
+ try:
+ google_search_result = search(query, max_results=5)
+ print(google_search_result)
+ return google_search_result
+ except Exception as err:
+ logger.error("Failed to do GoogleSearch: {err}")
+
+
+def extract_contact_info(website_data):
+ """
+ Extract contact information from website data.
+
+ Args:
+ website_data (dict): Scraped data from the website.
+
+ Returns:
+ dict: Extracted contact information such as name, email, etc.
+ """
+ # Placeholder for extracting contact information logic
+ return {
+ "name": website_data.get("contact", {}).get("name", "Webmaster"),
+ "email": website_data.get("contact", {}).get("email", ""),
+ }
diff --git a/lib/ai_marketing_tools/backlinking_ui_streamlit.py b/lib/ai_marketing_tools/backlinking_ui_streamlit.py
new file mode 100644
index 00000000..3b57319d
--- /dev/null
+++ b/lib/ai_marketing_tools/backlinking_ui_streamlit.py
@@ -0,0 +1,60 @@
+import streamlit as st
+import pandas as pd
+from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode
+from lib.ai_marketing_tools.ai_backlinking import find_backlink_opportunities, compose_personalized_email
+
+
+# Streamlit UI function
+def backlinking_ui():
+ st.title("AI Backlinking Tool")
+
+ # Step 1: Get user inputs
+ keyword = st.text_input("Enter a keyword", value="technology")
+
+ # Step 2: Generate backlink opportunities
+ if st.button("Find Backlink Opportunities"):
+ if keyword:
+ backlink_opportunities = find_backlink_opportunities(keyword)
+
+ # Convert results to a DataFrame for display
+ df = pd.DataFrame(backlink_opportunities)
+
+ # Create a selectable table using st-aggrid
+ gb = GridOptionsBuilder.from_dataframe(df)
+ gb.configure_selection('multiple', use_checkbox=True, groupSelectsChildren=True)
+ gridOptions = gb.build()
+
+ grid_response = AgGrid(
+ df,
+ gridOptions=gridOptions,
+ update_mode=GridUpdateMode.SELECTION_CHANGED,
+ height=200,
+ width='100%'
+ )
+
+ selected_rows = grid_response['selected_rows']
+
+ if selected_rows:
+ st.write("Selected Opportunities:")
+ st.table(pd.DataFrame(selected_rows))
+
+ # Step 3: Option to generate personalized emails for selected opportunities
+ if st.button("Generate Emails for Selected Opportunities"):
+ user_proposal = {
+ "user_name": st.text_input("Your Name", value="John Doe"),
+ "user_email": st.text_input("Your Email", value="john@example.com")
+ }
+
+ emails = []
+ for selected in selected_rows:
+ insights = f"Insights based on content from {selected['url']}."
+ email = compose_personalized_email(selected, insights, user_proposal)
+ emails.append(email)
+
+ st.subheader("Generated Emails:")
+ for email in emails:
+ st.write(email)
+ st.markdown("---")
+
+ else:
+ st.error("Please enter a keyword.")
diff --git a/lib/ai_web_researcher/.gpt_online_researcher.py.swp b/lib/ai_web_researcher/.gpt_online_researcher.py.swp
new file mode 100644
index 00000000..1dd76695
Binary files /dev/null and b/lib/ai_web_researcher/.gpt_online_researcher.py.swp differ
diff --git a/lib/ai_writers/data_img_slides_analyst.py b/lib/ai_writers/data_img_slides_analyst.py
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/utils/alwrity_utils.py b/lib/utils/alwrity_utils.py
index cdeab67e..1b1cba85 100644
--- a/lib/utils/alwrity_utils.py
+++ b/lib/utils/alwrity_utils.py
@@ -23,15 +23,6 @@ import PyPDF2
import tiktoken
import openai
from lib.gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
-from lib.ai_seo_tools.seo_structured_data import ai_structured_data
-from lib.ai_seo_tools.content_title_generator import ai_title_generator
-from lib.ai_seo_tools.meta_desc_generator import metadesc_generator_main
-from lib.ai_seo_tools.image_alt_text_generator import alt_text_gen
-from lib.ai_seo_tools.opengraph_generator import og_tag_generator
-from lib.ai_seo_tools.optimize_images_for_upload import main_img_optimizer
-from lib.ai_seo_tools.google_pagespeed_insights import google_pagespeed_insights
-from lib.ai_seo_tools.on_page_seo_analyzer import analyze_onpage_seo
-from lib.ai_seo_tools.weburl_seo_checker import url_seo_checker
from lib.utils.voice_processing import record_voice
from lib.content_planning_calender.content_planning_agents_alwrity_crew import ai_agents_content_planner
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
@@ -87,44 +78,6 @@ def process_input(input_text, uploaded_file):
return None
-def ai_seo_tools():
- """ Collection SEO tools for content creators. """
- options = [
- "Generate Structured Data - Rich Snippet",
- "Generate SEO optimized Blog Titles",
- "Generate Meta Description for SEO",
- "Generate Image Alt Text",
- "Generate OpenGraph Tags",
- "Optimize/Resize Image",
- "Run Google PageSpeed Insights",
- "Analyze On Page SEO",
- "URL SEO Checker"
- ]
-
- # Using st.radio instead of st.selectbox
- choice = st.radio("**๐ Select AI SEO Tool:**", options, index=0, format_func=lambda x: f"๐ {x}")
-
- # Handle choices based on the selected option
- if choice == "Generate Structured Data - Rich Snippet":
- ai_structured_data()
- elif choice == "Generate Meta Description for SEO":
- metadesc_generator_main()
- elif choice == "Generate SEO optimized Blog Titles":
- ai_title_generator()
- elif choice == "Generate Image Alt Text":
- alt_text_gen()
- elif choice == "Generate OpenGraph Tags":
- og_tag_generator()
- elif choice == "Optimize/Resize Image":
- main_img_optimizer()
- elif choice == "Run Google PageSpeed Insights":
- google_pagespeed_insights()
- elif choice == "Analyze On Page SEO":
- analyze_onpage_seo()
- elif choice == "URL SEO Checker":
- url_seo_checker()
-
-
def blog_from_keyword():
""" Input blog keywords, research and write a factual blog."""
st.header("Blog Content Writer")
diff --git a/lib/utils/api_key_manager.py b/lib/utils/api_key_manager.py
index 8af8243d..43b0fa54 100644
--- a/lib/utils/api_key_manager.py
+++ b/lib/utils/api_key_manager.py
@@ -34,6 +34,8 @@ def check_api_keys():
return False
return True
+
+
@st.cache_data
def check_llm_environs():
"""
diff --git a/lib/utils/content_generators.py b/lib/utils/content_generators.py
index 91954d2d..c26ccf6b 100644
--- a/lib/utils/content_generators.py
+++ b/lib/utils/content_generators.py
@@ -1,11 +1,13 @@
import streamlit as st
from lib.utils.alwrity_utils import (
- blog_from_keyword, ai_agents_team, essay_writer, ai_news_writer, ai_seo_tools,
+ blog_from_keyword, ai_agents_team, essay_writer, ai_news_writer,
ai_finance_ta_writer, ai_social_writer, do_web_research, competitor_analysis
)
from lib.ai_writers.ai_story_writer.story_writer import story_input_section
from lib.ai_writers.ai_product_description_writer import write_ai_prod_desc
from lib.content_planning_calender.content_planning_agents_alwrity_crew import ai_agents_content_planner
+from lib.utils.seo_tools import ai_seo_tools
+
def ai_writers():
options = [
diff --git a/lib/utils/seo_tools.py b/lib/utils/seo_tools.py
index a2337eac..daa36980 100644
--- a/lib/utils/seo_tools.py
+++ b/lib/utils/seo_tools.py
@@ -8,40 +8,80 @@ from lib.ai_seo_tools.optimize_images_for_upload import main_img_optimizer
from lib.ai_seo_tools.google_pagespeed_insights import google_pagespeed_insights
from lib.ai_seo_tools.on_page_seo_analyzer import analyze_onpage_seo
from lib.ai_seo_tools.weburl_seo_checker import url_seo_checker
+from lib.ai_marketing_tools.backlinking_ui_streamlit import backlinking_ui
+
def ai_seo_tools():
- """ Collection SEO tools for content creators. """
+ """
+ A collection of AI-powered SEO tools for content creators, providing various options
+ such as generating structured data, optimizing images, checking page speed,
+ and analyzing on-page SEO.
+ """
+ st.markdown(
+ """
+ Welcome to your one-stop solution for AI-driven SEO optimization. Select a tool from the options below
+ to improve your websiteโs SEO with cutting-edge AI technology.
+ """
+ )
+ # List of SEO tools with unique emojis for each option
options = [
- "Generate Structured Data - Rich Snippet",
- "Generate SEO optimized Blog Titles",
- "Generate Meta Description for SEO",
- "Generate Image Alt Text",
- "Generate OpenGraph Tags",
- "Optimize/Resize Image",
- "Run Google PageSpeed Insights",
- "Analyze On Page SEO",
- "URL SEO Checker"
+ "๐ Generate Structured Data - Rich Snippet",
+ "โ๏ธ Generate SEO Optimized Blog Titles",
+ "๐ Generate Meta Description for SEO",
+ "๐ผ๏ธ Generate Image Alt Text",
+ "๐ Generate OpenGraph Tags",
+ "๐ Optimize/Resize Image",
+ "โก Run Google PageSpeed Insights",
+ "๐ Analyze On-Page SEO",
+ "๐ URL SEO Checker",
+ "๐ AI Backlinking Tool"
]
- # Using st.radio instead of st.selectbox
- choice = st.radio("**๐ Select AI SEO Tool:**", options, index=0, format_func=lambda x: f"๐ {x}")
+ # User selection of SEO tools using radio buttons
+ choice = st.radio(
+ "**๐ Select an AI SEO Tool:**",
+ options,
+ index=0,
+ format_func=lambda x: x
+ )
- # Handle choices based on the selected option
- if choice == "Generate Structured Data - Rich Snippet":
+ # Call the respective functions based on the user selection
+ if choice == "๐ Generate Structured Data - Rich Snippet":
+ # Generate Structured Data for Rich Snippets
ai_structured_data()
- elif choice == "Generate Meta Description for SEO":
+
+ elif choice == "๐ Generate Meta Description for SEO":
+ # Generate SEO-optimized meta descriptions
metadesc_generator_main()
- elif choice == "Generate SEO optimized Blog Titles":
+
+ elif choice == "โ๏ธ Generate SEO Optimized Blog Titles":
+ # Generate SEO-friendly blog titles
ai_title_generator()
- elif choice == "Generate Image Alt Text":
+
+ elif choice == "๐ผ๏ธ Generate Image Alt Text":
+ # Generate alternative text for images
alt_text_gen()
- elif choice == "Generate OpenGraph Tags":
+
+ elif choice == "๐ Generate OpenGraph Tags":
+ # Generate OpenGraph tags for social media sharing
og_tag_generator()
- elif choice == "Optimize/Resize Image":
+
+ elif choice == "๐ Optimize/Resize Image":
+ # Optimize images by resizing or compressing them
main_img_optimizer()
- elif choice == "Run Google PageSpeed Insights":
+
+ elif choice == "โก Run Google PageSpeed Insights":
+ # Run Google PageSpeed Insights for performance analysis
google_pagespeed_insights()
- elif choice == "Analyze On Page SEO":
+
+ elif choice == "๐ Analyze On-Page SEO":
+ # Analyze on-page SEO elements
analyze_onpage_seo()
- elif choice == "URL SEO Checker":
+
+ elif choice == "๐ URL SEO Checker":
+ # Check SEO health of a specific URL
url_seo_checker()
+
+ elif choice == "๐ AI Backlinking Tool":
+ # Run AI Backlinking tool for link-building opportunities
+ backlinking_ui()
diff --git a/lib/utils/ui_setup.py b/lib/utils/ui_setup.py
index bddbdf3b..799dde53 100644
--- a/lib/utils/ui_setup.py
+++ b/lib/utils/ui_setup.py
@@ -2,7 +2,9 @@ import os
import streamlit as st
from .file_processor import load_image
from .content_generators import content_planning_tools, ai_writers
-from .alwrity_utils import ai_agents_team, ai_seo_tools, ai_social_writer
+from .alwrity_utils import ai_agents_team, ai_social_writer
+from .seo_tools import ai_seo_tools
+
def setup_ui():
"""Sets up the Streamlit UI with custom CSS and logo."""
@@ -23,6 +25,7 @@ def setup_ui():
""", unsafe_allow_html=True)
+
def setup_tabs():
"""Sets up the main tabs in the Streamlit app."""
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(
diff --git a/requirements.txt b/requirements.txt
index 67533ac9..7c3b7c21 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -38,3 +38,4 @@ streamlit-mic-recorder
tinify
cloudscraper
xmlschema
+googlesearch-python