Spaces:
Sleeping
Sleeping
File size: 5,421 Bytes
3d2214e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
import os
import openai
import gradio as gr
from bs4 import BeautifulSoup
import requests
import nest_asyncio
import asyncio
from playwright.sync_api import sync_playwright
nest_asyncio.apply()
openai.api_key = os.getenv("OPENAI_API_KEY")
# Synchronous version for HF Spaces compatibility
def extract_text_from_url(url):
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url, timeout=60000)
page.wait_for_load_state('networkidle')
content = page.content()
browser.close()
soup = BeautifulSoup(content, "html.parser")
text = ' '.join(p.get_text(strip=True) for p in soup.find_all(['p', 'span', 'h1', 'h2', 'li']))
return text[:4000] # limit to 4000 characters
def extract_keywords(text):
prompt = f"""
Extract up to 10 concise, relevant SEO keywords suitable for an automotive advertisement from the following content:
{text}
Keywords:
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.6,
max_tokens=100
)
keywords = response.choices[0].message.content.strip().split(',')
return [kw.strip() for kw in keywords]
def generate_ad_copy(platform, keywords):
prompt = f"""
Create a compelling, SEO-optimized {platform} ad using these keywords: {', '.join(keywords)}.
Include a clear and enticing call-to-action.
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
max_tokens=300
)
return response.choices[0].message.content.strip()
def generate_ad_image(keywords):
kw_str = ", ".join(keywords)
image_prompt = f"Professional automotive social media ad featuring: {kw_str}. Bright visuals, luxury theme, with text overlay space."
response = openai.Image.create(
prompt=image_prompt,
n=1,
size="512x512"
)
image_url = response["data"][0]["url"]
img_data = requests.get(image_url).content
img_file = "generated_ad_image.png"
with open(img_file, "wb") as f:
f.write(img_data)
return img_file
def main_workflow(input_mode, url_or_keywords):
error = None
# Step 1: Get keywords
if input_mode == "URL":
try:
text = extract_text_from_url(url_or_keywords)
keywords = extract_keywords(text)
except Exception as e:
return None, None, None, f"URL extraction error: {e}"
else:
keywords = [kw.strip() for kw in url_or_keywords.split(",") if kw.strip()]
if not keywords:
return None, None, None, "Please provide at least one keyword."
# Step 2: Generate ad copies
platforms = ["Facebook", "Instagram", "X (Twitter)", "Google Search"]
ad_copies = {}
for platform in platforms:
ad_copies[platform] = generate_ad_copy(platform, keywords)
# Step 3: Generate ad image
try:
image_path = generate_ad_image(keywords)
except Exception as e:
image_path = None
error = f"Image generation error: {e}"
# Step 4: Save ad copies to txt
output_txt = "generated_ads.txt"
with open(output_txt, "w", encoding="utf-8") as f:
for platform, content in ad_copies.items():
f.write(f"--- {platform} Ad Copy ---\n{content}\n\n")
return keywords, ad_copies, image_path, error
def run_space(input_mode, url, keywords):
url_or_keywords = url if input_mode == "URL" else keywords
keywords, ad_copies, image_path, error = main_workflow(input_mode, url_or_keywords)
ad_previews = ""
if ad_copies:
for platform, ad in ad_copies.items():
ad_previews += f"### {platform}\n{ad}\n\n"
return (
keywords,
ad_previews,
image_path,
"generated_ads.txt" if ad_copies else None,
error
)
with gr.Blocks() as demo:
gr.Markdown("# 🚗 Auto Ad Generator\nPaste a car listing URL **or** enter your own keywords, then preview AI-generated ads for each social media platform, plus an auto-generated image!")
input_mode = gr.Radio(["URL", "Keywords"], value="URL", label="Input Type")
url_input = gr.Textbox(label="Listing URL", placeholder="https://www.cars.com/listing/...", visible=True)
kw_input = gr.Textbox(label="Manual Keywords (comma separated)", placeholder="e.g. BMW, used car, sunroof", visible=False)
submit_btn = gr.Button("Generate Ads")
gr.Markdown("## Keywords")
kw_out = gr.JSON(label="Extracted/Provided Keywords")
gr.Markdown("## Ad Copy Previews")
ad_out = gr.Markdown(label="Ad Copy Preview")
gr.Markdown("## Generated Ad Image")
img_out = gr.Image(label="Generated Ad Image", type="filepath")
gr.Markdown("## Download Ad Copies")
file_out = gr.File(label="Download TXT")
err_out = gr.Textbox(label="Errors", interactive=False)
def show_hide_fields(choice):
return (
gr.update(visible=choice == "URL"),
gr.update(visible=choice == "Keywords"),
)
input_mode.change(show_hide_fields, input_mode, [url_input, kw_input])
submit_btn.click(
run_space,
inputs=[input_mode, url_input, kw_input],
outputs=[kw_out, ad_out, img_out, file_out, err_out]
)
demo.launch()
|