Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -7,13 +7,11 @@ import requests
|
|
7 |
openai.api_key = os.getenv("OPENAI_API_KEY")
|
8 |
|
9 |
def extract_text_from_url(url):
|
10 |
-
"""Extracts text from HTML for static pages. Warns if content is very thin."""
|
11 |
try:
|
12 |
resp = requests.get(url, timeout=30, headers={
|
13 |
"User-Agent": "Mozilla/5.0 (compatible; Bot/1.0)"
|
14 |
})
|
15 |
soup = BeautifulSoup(resp.content, "html.parser")
|
16 |
-
# Try to get rich descriptive content
|
17 |
candidates = soup.find_all(['h1','h2','h3','h4','p','span','li'])
|
18 |
text = ' '.join([c.get_text(strip=True) for c in candidates])
|
19 |
text = text[:4000]
|
@@ -35,7 +33,6 @@ def extract_keywords(text):
|
|
35 |
temperature=0.6,
|
36 |
max_tokens=100
|
37 |
)
|
38 |
-
# Handles both comma or newline separation
|
39 |
output = response.choices[0].message.content.strip()
|
40 |
if ',' in output:
|
41 |
keywords = output.split(',')
|
@@ -58,7 +55,12 @@ def generate_ad_copy(platform, keywords):
|
|
58 |
|
59 |
def generate_ad_image(keywords):
|
60 |
kw_str = ", ".join(keywords)
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
62 |
response = openai.Image.create(
|
63 |
prompt=image_prompt,
|
64 |
n=1,
|
@@ -71,6 +73,41 @@ def generate_ad_image(keywords):
|
|
71 |
f.write(img_data)
|
72 |
return img_file
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
def main_workflow(input_mode, url_or_keywords):
|
75 |
error = None
|
76 |
keywords = []
|
@@ -110,7 +147,7 @@ def run_space(input_mode, url, keywords):
|
|
110 |
ad_previews = ""
|
111 |
if ad_copies:
|
112 |
for platform, ad in ad_copies.items():
|
113 |
-
ad_previews +=
|
114 |
return (
|
115 |
keywords,
|
116 |
ad_previews,
|
@@ -130,7 +167,7 @@ with gr.Blocks() as demo:
|
|
130 |
kw_out = gr.JSON(label="Extracted/Provided Keywords")
|
131 |
|
132 |
gr.Markdown("## Ad Copy Previews")
|
133 |
-
ad_out = gr.
|
134 |
|
135 |
gr.Markdown("## Generated Ad Image")
|
136 |
img_out = gr.Image(label="Generated Ad Image", type="filepath")
|
|
|
7 |
openai.api_key = os.getenv("OPENAI_API_KEY")
|
8 |
|
9 |
def extract_text_from_url(url):
|
|
|
10 |
try:
|
11 |
resp = requests.get(url, timeout=30, headers={
|
12 |
"User-Agent": "Mozilla/5.0 (compatible; Bot/1.0)"
|
13 |
})
|
14 |
soup = BeautifulSoup(resp.content, "html.parser")
|
|
|
15 |
candidates = soup.find_all(['h1','h2','h3','h4','p','span','li'])
|
16 |
text = ' '.join([c.get_text(strip=True) for c in candidates])
|
17 |
text = text[:4000]
|
|
|
33 |
temperature=0.6,
|
34 |
max_tokens=100
|
35 |
)
|
|
|
36 |
output = response.choices[0].message.content.strip()
|
37 |
if ',' in output:
|
38 |
keywords = output.split(',')
|
|
|
55 |
|
56 |
def generate_ad_image(keywords):
|
57 |
kw_str = ", ".join(keywords)
|
58 |
+
# Enhanced prompt for better visuals
|
59 |
+
image_prompt = (
|
60 |
+
f"High-quality, photorealistic automotive ad photo of a luxury car. "
|
61 |
+
f"Clean background, professional lighting, stylish dealership setting. "
|
62 |
+
f"Keywords: {kw_str}. Room for text overlay, wide format, visually appealing."
|
63 |
+
)
|
64 |
response = openai.Image.create(
|
65 |
prompt=image_prompt,
|
66 |
n=1,
|
|
|
73 |
f.write(img_data)
|
74 |
return img_file
|
75 |
|
76 |
+
def platform_html(platform, ad_text):
|
77 |
+
# Platform-specific color and icons
|
78 |
+
if platform == "Facebook":
|
79 |
+
color = "#1877F2"
|
80 |
+
icon = "🌐"
|
81 |
+
elif platform == "Instagram":
|
82 |
+
# Instagram gradient
|
83 |
+
color = "linear-gradient(90deg, #f58529 0%, #dd2a7b 50%, #8134af 100%)"
|
84 |
+
icon = "📸"
|
85 |
+
elif platform == "X (Twitter)":
|
86 |
+
color = "#14171A"
|
87 |
+
icon = "🐦"
|
88 |
+
else: # Google Search
|
89 |
+
color = "#4285F4"
|
90 |
+
icon = "🔍"
|
91 |
+
|
92 |
+
if platform == "Instagram":
|
93 |
+
# Gradient needs to be on a child div (not background-color)
|
94 |
+
content = f"""
|
95 |
+
<div style="background: {color}; padding: 2px; border-radius: 12px; margin-bottom:16px;">
|
96 |
+
<div style="background: white; color: #333; padding: 18px 20px; border-radius: 10px;">
|
97 |
+
<span style="font-size: 1.5em;">{icon} <b>{platform}</b></span>
|
98 |
+
<div style="margin-top: 12px; font-size: 1.1em; line-height:1.6;">{ad_text}</div>
|
99 |
+
</div>
|
100 |
+
</div>
|
101 |
+
"""
|
102 |
+
else:
|
103 |
+
content = f"""
|
104 |
+
<div style="background: {color}; color: white; padding: 18px 20px; border-radius: 12px; margin-bottom:16px; min-height: 120px;">
|
105 |
+
<span style="font-size: 1.5em;">{icon} <b>{platform}</b></span>
|
106 |
+
<div style="margin-top: 12px; font-size: 1.1em; line-height:1.6;">{ad_text}</div>
|
107 |
+
</div>
|
108 |
+
"""
|
109 |
+
return content
|
110 |
+
|
111 |
def main_workflow(input_mode, url_or_keywords):
|
112 |
error = None
|
113 |
keywords = []
|
|
|
147 |
ad_previews = ""
|
148 |
if ad_copies:
|
149 |
for platform, ad in ad_copies.items():
|
150 |
+
ad_previews += platform_html(platform, ad)
|
151 |
return (
|
152 |
keywords,
|
153 |
ad_previews,
|
|
|
167 |
kw_out = gr.JSON(label="Extracted/Provided Keywords")
|
168 |
|
169 |
gr.Markdown("## Ad Copy Previews")
|
170 |
+
ad_out = gr.HTML(label="Ad Copy Preview") # Now HTML, not Markdown
|
171 |
|
172 |
gr.Markdown("## Generated Ad Image")
|
173 |
img_out = gr.Image(label="Generated Ad Image", type="filepath")
|