|
import gradio as gr |
|
import torch |
|
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline |
|
import nltk |
|
from datetime import datetime, timedelta |
|
import requests |
|
from bs4 import BeautifulSoup |
|
|
|
|
|
try: |
|
nltk.data.find('tokenizers/punkt') |
|
except LookupError: |
|
nltk.download('punkt') |
|
|
|
|
|
CACHED_MODELS = {} |
|
|
|
|
|
def load_models(): |
|
global CACHED_MODELS |
|
|
|
if CACHED_MODELS: |
|
return ( |
|
CACHED_MODELS['generator_tokenizer'], |
|
CACHED_MODELS['generator'], |
|
CACHED_MODELS['sentiment_analyzer'], |
|
CACHED_MODELS['content_checker'] |
|
) |
|
|
|
try: |
|
|
|
generator_model = "gpt2" |
|
generator_tokenizer = AutoTokenizer.from_pretrained(generator_model) |
|
generator = AutoModelForCausalLM.from_pretrained(generator_model) |
|
|
|
|
|
sentiment_analyzer = pipeline( |
|
"sentiment-analysis", |
|
model="finiteautomata/bertweet-base-sentiment-analysis" |
|
) |
|
|
|
|
|
content_checker = pipeline( |
|
"text-classification", |
|
model="facebook/roberta-hate-speech-dynabench-r4-target" |
|
) |
|
|
|
|
|
CACHED_MODELS['generator_tokenizer'] = generator_tokenizer |
|
CACHED_MODELS['generator'] = generator |
|
CACHED_MODELS['sentiment_analyzer'] = sentiment_analyzer |
|
CACHED_MODELS['content_checker'] = content_checker |
|
|
|
return generator_tokenizer, generator, sentiment_analyzer, content_checker |
|
except Exception as e: |
|
print(f"Error loading models: {str(e)}") |
|
raise |
|
|
|
def generate_content( |
|
product_name, |
|
product_description, |
|
target_audience, |
|
key_features, |
|
unique_benefits, |
|
platform, |
|
tone, |
|
generator_tokenizer, |
|
generator, |
|
sentiment_analyzer, |
|
content_checker |
|
): |
|
char_limit = 280 if platform == "Twitter" else 500 |
|
|
|
|
|
features = [f.strip() for f in key_features.split(',')] |
|
benefits = [b.strip() for b in unique_benefits.split(',')] |
|
|
|
|
|
intro_phrases = { |
|
'professional': [ |
|
f"Introducing {product_name}:", |
|
f"Discover {product_name}:", |
|
f"Meet {product_name}:", |
|
f"Presenting {product_name}:", |
|
f"Announcing {product_name}:", |
|
f"Experience {product_name}:", |
|
f"Elevate your life with {product_name}:", |
|
], |
|
'casual': [ |
|
f"Check out {product_name}!", |
|
f"Say hello to {product_name}!", |
|
f"Get ready for {product_name}!", |
|
f"You'll love {product_name}!", |
|
f"Looking for something special? Try {product_name}!", |
|
f"Meet your new favorite: {product_name}!", |
|
f"Game-changer alert: {product_name} is here!", |
|
], |
|
'friendly': [ |
|
f"We're excited to share {product_name} with you!", |
|
f"You'll love what {product_name} can do!", |
|
f"Let {product_name} transform your day!", |
|
f"Ready to discover {product_name}?", |
|
f"Here's why you'll love {product_name}:", |
|
f"Make every day better with {product_name}!", |
|
f"Transform your experience with {product_name}!", |
|
] |
|
} |
|
|
|
|
|
description_connectors = [ |
|
f" - {product_description}", |
|
f": {product_description}", |
|
f"! {product_description}", |
|
f", {product_description}", |
|
f". {product_description}", |
|
] |
|
|
|
|
|
feature_intros = [ |
|
"Featuring", |
|
"With", |
|
"Including", |
|
"Equipped with", |
|
"Powered by", |
|
"Designed with", |
|
"Built with", |
|
"Offering", |
|
] |
|
|
|
|
|
benefit_connectors = [ |
|
"Experience", |
|
"Enjoy", |
|
"Benefit from", |
|
"Take advantage of", |
|
"Discover", |
|
"Appreciate", |
|
"Make the most of", |
|
] |
|
|
|
|
|
audience_phrases = [ |
|
f"Perfect for {target_audience}", |
|
f"Ideal for {target_audience}", |
|
f"Designed for {target_audience}", |
|
f"Made specially for {target_audience}", |
|
f"Tailored for {target_audience}", |
|
f"Created with {target_audience} in mind", |
|
] |
|
|
|
|
|
cta_phrases = { |
|
'Twitter': [ |
|
"Learn more today!", |
|
"Discover more β", |
|
"Get yours now!", |
|
"Visit our website!", |
|
"Join us today!", |
|
"Transform your life today!", |
|
"Start your journey!", |
|
], |
|
'Instagram': [ |
|
f"\n\n#{product_name.replace(' ', '')}", |
|
f"\n\nLearn more - Link in bio! #{product_name.replace(' ', '')}", |
|
f"\n\nDiscover more βοΈ #{product_name.replace(' ', '')}", |
|
f"\n\nTap link to learn more! #{product_name.replace(' ', '')}", |
|
] |
|
} |
|
|
|
import random |
|
|
|
def create_post(): |
|
|
|
selected_tone = tone.lower() if tone.lower() in intro_phrases else 'professional' |
|
|
|
|
|
structure = random.randint(1, 4) |
|
|
|
if structure == 1: |
|
|
|
post = random.choice(intro_phrases[selected_tone]) |
|
post += random.choice(description_connectors) |
|
feature = random.choice(features) |
|
benefit = random.choice(benefits) |
|
|
|
if len(post) + len(feature) + len(benefit) + 20 < char_limit: |
|
post += f" {random.choice(feature_intros)} {feature}." |
|
post += f" {random.choice(benefit_connectors)} {benefit}." |
|
|
|
elif structure == 2: |
|
|
|
benefit = random.choice(benefits) |
|
post = f"Ready to {benefit.lower()}? " |
|
post += random.choice(intro_phrases[selected_tone]) |
|
post += random.choice(description_connectors) |
|
|
|
if len(post) + 30 < char_limit: |
|
feature = random.choice(features) |
|
post += f" {random.choice(feature_intros)} {feature}." |
|
|
|
elif structure == 3: |
|
|
|
post = f"Looking for {product_description.lower()}? " |
|
post += random.choice(intro_phrases[selected_tone]).replace(':', '!') |
|
feature = random.choice(features) |
|
benefit = random.choice(benefits) |
|
|
|
if len(post) + len(feature) + len(benefit) + 20 < char_limit: |
|
post += f" {random.choice(feature_intros)} {feature}." |
|
post += f" {benefit}." |
|
|
|
else: |
|
|
|
feature = random.choice(features) |
|
post = f"From {feature} to {random.choice(benefits).lower()}, " |
|
post += f"{product_name} has it all! " |
|
post += product_description |
|
|
|
|
|
if len(post) + 50 < char_limit: |
|
post += f" {random.choice(audience_phrases)}." |
|
|
|
|
|
if platform == "Twitter": |
|
if len(post) + 30 < char_limit: |
|
post += f" {random.choice(cta_phrases['Twitter'])}" |
|
else: |
|
if len(post) + 50 < char_limit: |
|
post += random.choice(cta_phrases['Instagram']) |
|
|
|
return post.strip() |
|
|
|
try: |
|
|
|
posts = [create_post() for _ in range(2)] |
|
filtered_content = [] |
|
|
|
for post in posts: |
|
|
|
if len(post) > char_limit: |
|
post = post[:char_limit-3] + "..." |
|
|
|
|
|
try: |
|
sentiment = sentiment_analyzer(post)[0] |
|
safety_check = content_checker(post)[0] |
|
|
|
filtered_content.append({ |
|
'text': post, |
|
'sentiment': sentiment['label'], |
|
'safety_score': f"{float(safety_check.get('score', 0)):.2f}" |
|
}) |
|
except Exception as e: |
|
print(f"Error in content analysis: {str(e)}") |
|
continue |
|
|
|
return filtered_content if filtered_content else [{ |
|
'text': create_post(), |
|
'sentiment': 'positive', |
|
'safety_score': '1.00' |
|
}] |
|
|
|
except Exception as e: |
|
print(f"Error in content generation: {str(e)}") |
|
return [{ |
|
'text': f"Introducing {product_name}: {product_description[:100]}... Learn more!", |
|
'sentiment': 'neutral', |
|
'safety_score': '1.00' |
|
}] |
|
|
|
def create_interface(): |
|
print("Loading models...") |
|
generator_tokenizer, generator, sentiment_analyzer, content_checker = load_models() |
|
print("Models loaded successfully!") |
|
|
|
def fill_sample_data(): |
|
return [ |
|
"EcoBottle", |
|
"Sustainable water bottle made from recycled ocean plastic", |
|
"Environmentally conscious young professionals", |
|
"100% recycled materials, Insulated design, Leak-proof", |
|
"Helps clean oceans, Keeps drinks cold for 24 hours", |
|
"Twitter", |
|
"professional" |
|
] |
|
|
|
def clear_form(): |
|
return [""] * 7 |
|
|
|
import time |
|
|
|
def process_input_with_loading( |
|
product_name, |
|
product_description, |
|
target_audience, |
|
key_features, |
|
unique_benefits, |
|
platform, |
|
tone, |
|
progress=gr.Progress() |
|
): |
|
|
|
features_list = """β‘ While I generate your content, here's what I can do: |
|
|
|
π Generate multiple unique marketing messages |
|
π― Adapt content for different platforms |
|
π Ensure ethical content generation |
|
π Analyze sentiment and safety |
|
β¨ Create platform-specific formatting |
|
|
|
Processing your request...""" |
|
|
|
yield features_list + "\n\nβ³ Starting generation..." |
|
time.sleep(1) |
|
|
|
|
|
steps = [ |
|
"Loading language models...", |
|
"Analyzing product information...", |
|
"Generating content variations...", |
|
"Checking content safety...", |
|
"Finalizing output..." |
|
] |
|
|
|
for i, step in enumerate(steps, 1): |
|
progress(i/len(steps)) |
|
yield features_list + f"\n\nβ³ {step}" |
|
time.sleep(1) |
|
|
|
|
|
try: |
|
results = generate_content( |
|
product_name, |
|
product_description, |
|
target_audience, |
|
key_features, |
|
unique_benefits, |
|
platform, |
|
tone, |
|
generator_tokenizer, |
|
generator, |
|
sentiment_analyzer, |
|
content_checker |
|
) |
|
|
|
output = "π― Generated Marketing Content:\n\n" |
|
for i, content in enumerate(results, 1): |
|
output += f"Version {i}:\n" |
|
output += f"π Content: {content['text']}\n" |
|
output += f"π Sentiment: {content['sentiment']}\n" |
|
output += f"β
Safety Score: {content['safety_score']}\n" |
|
output += "-" * 50 + "\n" |
|
|
|
yield output |
|
except Exception as e: |
|
yield f"An error occurred: {str(e)}" |
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Default()) as demo: |
|
gr.Markdown("# Ethimar - AI Marketing Content Generator") |
|
gr.Markdown("Generate ethical marketing content with AI-powered insights.\nβ³ Note: First generation might take 3-5 minutes due to model loading. Subsequent generations will be faster!") |
|
|
|
|
|
with gr.Row(): |
|
fill_button = gr.Button( |
|
"Fill the form with sample data", |
|
variant="primary", |
|
size="sm", |
|
scale=0.2 |
|
) |
|
|
|
|
|
with gr.Row(): |
|
|
|
with gr.Column(scale=1): |
|
product_name = gr.Textbox(label="Product Name", placeholder="Enter product name") |
|
product_description = gr.Textbox(label="Product Description", lines=3, placeholder="Brief description of your product") |
|
target_audience = gr.Textbox(label="Target Audience", placeholder="Who is this product for?") |
|
key_features = gr.Textbox(label="Key Features", lines=2, placeholder="Main features of your product") |
|
unique_benefits = gr.Textbox(label="Unique Benefits", lines=2, placeholder="What makes your product special?") |
|
platform = gr.Radio( |
|
choices=["Twitter", "Instagram"], |
|
label="Platform", |
|
value="Twitter" |
|
) |
|
tone = gr.Textbox(label="Tone", placeholder="e.g., professional, casual, friendly") |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(scale=2): |
|
submit_button = gr.Button("Generate Content", variant="primary", scale=1) |
|
with gr.Column(scale=1): |
|
clear_button = gr.Button("Clear Form", variant="secondary", scale=1) |
|
|
|
|
|
with gr.Column(scale=1): |
|
output = gr.Textbox( |
|
label="Generated Content", |
|
lines=12, |
|
value="β¨ Enter your product details and click 'Generate Content' to start!" |
|
) |
|
|
|
|
|
input_components = [ |
|
product_name, |
|
product_description, |
|
target_audience, |
|
key_features, |
|
unique_benefits, |
|
platform, |
|
tone |
|
] |
|
|
|
fill_button.click( |
|
fn=fill_sample_data, |
|
outputs=input_components |
|
) |
|
|
|
submit_button.click( |
|
fn=process_input_with_loading, |
|
inputs=input_components, |
|
outputs=output |
|
) |
|
|
|
clear_button.click( |
|
fn=clear_form, |
|
outputs=input_components |
|
) |
|
|
|
return demo |
|
|
|
|
|
if __name__ == "__main__": |
|
demo = create_interface() |
|
demo.launch() |