Resolved merge conflicts in LinkedIn README and Twitter dashboard

This commit is contained in:
ajaysi
2025-04-16 18:32:43 +05:30
14 changed files with 790 additions and 1089 deletions

View File

@@ -333,7 +333,7 @@ To use the LinkedIn AI Writer:
## Requirements
- Python 3.11
- Python 3.8+
- Streamlit
- OpenAI API key (for GPT models)
- Optional: LinkedIn API credentials (for future integration)

View File

@@ -29,10 +29,24 @@ from .modules.article_generator.linkedin_article_generator import linkedin_artic
from .modules.carousel_generator.linkedin_carousel_generator import linkedin_carousel_generator_ui
from .modules.video_script_generator.linkedin_video_script_generator import linkedin_video_script_generator_ui
from .modules.comment_response_generator.linkedin_comment_response_generator_ui import linkedin_comment_response_generator_ui
from .modules.profile_optimizer.linkedin_profile_optimizer_ui import linkedin_profile_optimizer_ui
from .modules.poll_generator import linkedin_poll_generator_ui
from .modules.company_page_generator import linkedin_company_page_generator_ui
# Import image generation
from ...gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
# Create a wrapper for the async profile optimizer UI
def linkedin_profile_optimizer_ui_wrapper():
"""Wrapper function to call the async LinkedIn Profile Optimizer UI."""
import asyncio
asyncio.run(linkedin_profile_optimizer_ui())
# Create a wrapper for the async company page generator UI
def linkedin_company_page_generator_ui_wrapper():
"""Wrapper function to call the async LinkedIn Company Page Generator UI."""
import asyncio
asyncio.run(linkedin_company_page_generator_ui())
def linkedin_main_menu():
"""Main function for the LinkedIn AI Writer."""
@@ -161,8 +175,8 @@ def linkedin_main_menu():
"description": "Enhance LinkedIn profiles to improve visibility and professional appeal.",
"color": "#0A66C2",
"category": "Profile & Personal Branding",
"function": None,
"status": "coming_soon",
"function": linkedin_profile_optimizer_ui_wrapper,
"status": "active",
"features": [
"Headline optimization",
"About section generation",
@@ -182,8 +196,8 @@ def linkedin_main_menu():
"description": "Create engaging polls that drive interaction and gather insights.",
"color": "#0A66C2",
"category": "Profile & Personal Branding",
"function": None,
"status": "coming_soon",
"function": linkedin_poll_generator_ui,
"status": "active",
"features": [
"Question formulation optimization",
"Option generation based on topic",
@@ -205,8 +219,8 @@ def linkedin_main_menu():
"description": "Create content for company pages that builds brand awareness and engagement.",
"color": "#0A66C2",
"category": "Business & Marketing",
"function": None,
"status": "coming_soon",
"function": linkedin_company_page_generator_ui_wrapper,
"status": "active",
"features": [
"Company culture post generation",
"Product/service announcement templates",
@@ -516,7 +530,7 @@ def linkedin_main_menu():
""", unsafe_allow_html=True)
# Add a button to access the tool
if st.button(f"Use {tool['name']}", key=f"btn_{tool['name']}"):
if st.button(f"Use {tool['name']}", key=f"btn_{tool['category']}_{tool['name']}"):
# Store the selected tool in session state
st.session_state.selected_tool = tool
st.rerun()

View File

@@ -31,31 +31,32 @@ async def linkedin_profile_optimizer_ui():
st.info("Upload your profile information for a comprehensive analysis")
# Profile Data Input
with st.expander("Enter Profile Information", expanded=True):
profile_data = {
"headline": st.text_input("Current Headline"),
"about": st.text_area("About Section"),
"industry": st.text_input("Industry"),
"current_role": st.text_input("Current Role"),
"experience": [],
"skills": st.text_area("Current Skills (one per line)").split("\n"),
"education": st.text_area("Education (one per line)").split("\n")
}
# Experience Input
st.subheader("Work Experience")
num_experiences = st.number_input("Number of experiences to add", min_value=0, max_value=10, value=1)
for i in range(num_experiences):
with st.expander(f"Experience {i+1}"):
exp = {
"role": st.text_input(f"Role {i+1}"),
"company": st.text_input(f"Company {i+1}"),
"description": st.text_area(f"Description {i+1}")
}
profile_data["experience"].append(exp)
st.subheader("Enter Profile Information")
profile_data = {
"headline": st.text_input("Current Headline", key="profile_headline"),
"about": st.text_area("About Section", key="profile_about"),
"industry": st.text_input("Industry", key="profile_industry"),
"current_role": st.text_input("Current Role", key="profile_role"),
"experience": [],
"skills": st.text_area("Current Skills (one per line)", key="profile_skills").split("\n"),
"education": st.text_area("Education (one per line)", key="profile_education").split("\n")
}
if st.button("Analyze Profile"):
# Experience Input
st.subheader("Work Experience")
num_experiences = st.number_input("Number of experiences to add", min_value=0, max_value=10, value=1, key="profile_num_exp")
for i in range(num_experiences):
st.markdown(f"**Experience {i+1}**")
exp = {
"role": st.text_input(f"Role {i+1}", key=f"profile_role_{i}"),
"company": st.text_input(f"Company {i+1}", key=f"profile_company_{i}"),
"description": st.text_area(f"Description {i+1}", key=f"profile_desc_{i}")
}
profile_data["experience"].append(exp)
st.divider()
if st.button("Analyze Profile", key="profile_analyze_btn"):
with st.spinner("Analyzing your profile..."):
analysis = await optimizer.analyze_profile_strength(profile_data)
@@ -83,11 +84,11 @@ async def linkedin_profile_optimizer_ui():
st.header("Headline Optimizer")
st.info("Optimize your headline for better visibility and impact")
current_headline = st.text_input("Current Headline")
industry = st.text_input("Industry")
role = st.text_input("Current/Target Role")
current_headline = st.text_input("Current Headline", key="headline_current")
industry = st.text_input("Industry", key="headline_industry")
role = st.text_input("Current/Target Role", key="headline_role")
if st.button("Optimize Headline"):
if st.button("Optimize Headline", key="headline_optimize_btn"):
with st.spinner("Generating optimized headline..."):
headline_optimization = await optimizer.optimize_headline(
current_headline,
@@ -110,11 +111,11 @@ async def linkedin_profile_optimizer_ui():
st.header("About Section Generator")
st.info("Create an engaging and professional About section")
current_about = st.text_area("Current About Section")
achievements = st.text_area("Key Achievements (one per line)").split("\n")
target_audience = st.text_input("Target Audience")
current_about = st.text_area("Current About Section", key="about_current")
achievements = st.text_area("Key Achievements (one per line)", key="about_achievements").split("\n")
target_audience = st.text_input("Target Audience", key="about_audience")
if st.button("Generate About Section"):
if st.button("Generate About Section", key="about_generate_btn"):
with st.spinner("Generating optimized About section..."):
about_optimization = await optimizer.generate_about_section(
current_about,
@@ -128,8 +129,9 @@ async def linkedin_profile_optimizer_ui():
st.subheader("Section Structure")
for section, explanation in about_optimization['structure_explanation'].items():
with st.expander(section):
st.write(explanation)
st.markdown(f"**{section}**")
st.write(explanation)
st.divider()
st.subheader("Impact Factors")
for factor in about_optimization['impact_factors']:
@@ -141,44 +143,47 @@ async def linkedin_profile_optimizer_ui():
st.info("Enhance your work experience descriptions for maximum impact")
experiences = []
num_exp = st.number_input("Number of experiences to enhance", min_value=1, max_value=10, value=1)
num_exp = st.number_input("Number of experiences to enhance", min_value=1, max_value=10, value=1, key="exp_num")
for i in range(num_exp):
with st.expander(f"Experience {i+1}"):
exp = {
"role": st.text_input(f"Role {i+1}"),
"company": st.text_input(f"Company {i+1}"),
"description": st.text_area(f"Current Description {i+1}")
}
experiences.append(exp)
st.markdown(f"**Experience {i+1}**")
exp = {
"role": st.text_input(f"Role {i+1}", key=f"exp_role_{i}"),
"company": st.text_input(f"Company {i+1}", key=f"exp_company_{i}"),
"description": st.text_area(f"Current Description {i+1}", key=f"exp_desc_{i}")
}
experiences.append(exp)
st.divider()
if st.button("Enhance Experiences"):
if st.button("Enhance Experiences", key="exp_enhance_btn"):
with st.spinner("Enhancing experience descriptions..."):
enhanced_experiences = await optimizer.enhance_experience_descriptions(experiences)
for i, exp in enumerate(enhanced_experiences):
with st.expander(f"Enhanced Experience {i+1}"):
st.subheader(f"{exp['role']} at {exp['company']}")
st.markdown(exp['enhanced_description'])
st.subheader("Key Achievements")
for achievement in exp['achievements']:
st.success(achievement)
st.subheader("Keywords Used")
for keyword in exp['keywords']:
st.info(keyword)
st.markdown(f"**Enhanced Experience {i+1}**")
st.subheader(f"{exp['role']} at {exp['company']}")
st.markdown(exp['enhanced_description'])
st.subheader("Key Achievements")
for achievement in exp['achievements']:
st.success(achievement)
st.subheader("Keywords Used")
for keyword in exp['keywords']:
st.info(keyword)
st.divider()
# Skills Recommender Tab
with tabs[4]:
st.header("Skills Recommender")
st.info("Get personalized skill recommendations for your profile")
current_skills = st.text_area("Current Skills (one per line)").split("\n")
industry = st.text_input("Industry (for skills)")
role = st.text_input("Role (for skills)")
current_skills = st.text_area("Current Skills (one per line)", key="skills_current").split("\n")
industry = st.text_input("Industry (for skills)", key="skills_industry")
role = st.text_input("Role (for skills)", key="skills_role")
if st.button("Get Skill Recommendations"):
if st.button("Get Skill Recommendations", key="skills_recommend_btn"):
with st.spinner("Analyzing and recommending skills..."):
skill_recommendations = await optimizer.recommend_skills(
current_skills,
@@ -204,6 +209,7 @@ async def linkedin_profile_optimizer_ui():
st.subheader("Skill Categories")
for category, skills in skill_recommendations['skill_categories'].items():
with st.expander(category):
for skill in skills:
st.write(f"- {skill}")
st.markdown(f"**{category}**")
for skill in skills:
st.write(f"- {skill}")
st.divider()

View File

@@ -1,100 +0,0 @@
import time #Iwish
import os
import json
import requests
import streamlit as st
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
def tweet_writer():
""" AI Tweet Generator """
with st.expander("**PRO-TIP** - Read the instructions below.", expanded=True):
col1, col2 = st.columns([5, 5])
with col1:
hook = st.text_input(
label="**What's the tweet about? (Hook)**",
placeholder="e.g., Discover the future of tech today!",
help="Provide a compelling opening statement or question to grab attention."
)
with col2:
target_audience = st.text_input(
label="**Target Audience**",
placeholder="e.g., technology enthusiasts, travel lovers",
help="Describe the audience you want to target with this tweet."
)
col3, col4 = st.columns([5, 5])
with col3:
tweet_tone = st.selectbox(
label="**Tweet Tone**",
options=["Humorous", "Informative", "Inspirational", "Serious", "Casual"],
help="Choose the tone you'd like the tweet to have."
)
with col4:
cta = st.text_input(
label="**Call to Action (Optional)**",
placeholder="e.g., Retweet this if you agree! (Leave blank if not applicable)",
help="Provide a call to action if you'd like to include one."
)
col5, col6 = st.columns([5, 5])
with col5:
keywords_hashtags = st.text_input(
label="**Keywords/Hashtags**",
placeholder="e.g., #AI #Innovation",
help="Provide 2-3 relevant keywords or hashtags."
)
with col6:
tweet_length = st.selectbox(
"Tweet Length (Optional)",
options=["Short (under 100 characters)", "Medium (100-200 characters)", "Long (200+ characters)"],
help="Choose the desired tweet length.",
)
if st.button('**Write Tweets**'):
if not target_audience or not hook:
st.error("🚫 Please provide all required inputs.")
else:
with st.status("Assigning AI professional to write your tweets...", expanded=True) as status:
response = tweet_generator(target_audience, hook, tweet_tone, cta, keywords_hashtags, tweet_length)
if response:
st.subheader(f'**🧕👩: Your Tweets!**')
st.markdown(response)
else:
st.error("💥**Failed to generate tweets. Please try again!**")
def tweet_generator(target_audience, hook, tone_style, cta, keywords_hashtags, tweet_length):
""" Tweet Generator """
prompt = f"""
You are a social media expert creating tweets for an audience interested in {target_audience}.
Write 5 engaging, concise, and visually appealing tweets that each:
1. Start with a compelling hook based on the following input: "{hook}"
2. Include the following call to action: "{cta}"
3. Use 2-3 relevant keywords/hashtags, including: "{keywords_hashtags}"
4. Adopt the following tone/style: "{tone_style}"
5. Adhere to the following length requirement: {tweet_length}
Make sure to keep the tone consistent with the selected style and platform context.
Here are some examples of call-to-actions to include (if no specific CTA was provided):
- Retweet this if you agree!
- Share your thoughts in the comments!
- Learn more at [link]
- Follow for more {target_audience} content.
Output each tweet separated by a newline.
"""
try:
response = llm_text_gen(prompt)
return response
except Exception as err:
st.error(f"Exit: Failed to get response from LLM: {err}")
exit(1)

View File

@@ -0,0 +1,9 @@
"""
Twitter Tweet Generator Module
A comprehensive suite of tools for generating and optimizing tweets.
"""
from .smart_tweet_generator import smart_tweet_generator
__all__ = ['smart_tweet_generator']

View File

@@ -339,4 +339,4 @@ def smart_tweet_generator():
st.code(tweet_texts)
if __name__ == "__main__":
smart_tweet_generator()
smart_tweet_generator()