Resolved merge conflicts in LinkedIn README and Twitter dashboard
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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']
|
||||
@@ -339,4 +339,4 @@ def smart_tweet_generator():
|
||||
st.code(tweet_texts)
|
||||
|
||||
if __name__ == "__main__":
|
||||
smart_tweet_generator()
|
||||
smart_tweet_generator()
|
||||
|
||||
Reference in New Issue
Block a user