Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -48,7 +48,7 @@ def save_theme_to_dataset(xml_file):
|
|
| 48 |
token=HF_TOKEN,
|
| 49 |
commit_message="Updated website theme XML"
|
| 50 |
)
|
| 51 |
-
return "✅ Theme successfully pushed to your private dataset!"
|
| 52 |
|
| 53 |
except Exception as e:
|
| 54 |
return f"❌ Error saving theme to dataset: {e}"
|
|
@@ -129,22 +129,12 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
|
|
| 129 |
}
|
| 130 |
schema_script = f'<script type="application/ld+json">\n[{json.dumps(schema_app)}, {json.dumps(schema_faq)}, {json.dumps(schema_sysreq)}]\n</script>'
|
| 131 |
|
| 132 |
-
# Fetch
|
| 133 |
-
|
| 134 |
-
downloaded_theme_path = hf_hub_download(repo_id=DATASET_REPO, filename=THEME_FILE_NAME, repo_type="dataset", token=HF_TOKEN)
|
| 135 |
-
theme_background = "#0f172a"
|
| 136 |
-
except Exception:
|
| 137 |
-
theme_background = "#0f172a"
|
| 138 |
|
| 139 |
-
# Final Base HTML Template Construction
|
| 140 |
html_template = f"""
|
| 141 |
{schema_script}
|
| 142 |
-
<style>
|
| 143 |
-
@keyframes pulse {{ 0% {{ transform: scale(1); }} 50% {{ transform: scale(1.02); box-shadow: 0 0 30px {theme_color}80; }} 100% {{ transform: scale(1); }} }}
|
| 144 |
-
.lex-btn:hover {{ filter: brightness(1.2); }}
|
| 145 |
-
.app-post-wrapper * {{ box-sizing: border-box; }}
|
| 146 |
-
</style>
|
| 147 |
-
|
| 148 |
<div style="display: none;">
|
| 149 |
<img src="{icon_url}" alt="Download {title} Mod APK" />
|
| 150 |
</div>
|
|
@@ -165,7 +155,7 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
|
|
| 165 |
</div>
|
| 166 |
|
| 167 |
<div style="text-align: center; margin-bottom: 35px; background: #020617; padding: 25px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.02);">
|
| 168 |
-
<a href="{custom_link}" target="_blank" rel="nofollow noopener" class="lex-btn" style="display: inline-block; width: 100%; max-width: 400px; background: {theme_color}; color: #fff; text-decoration: none; padding: 16px; border-radius: 50px; font-weight: 800; font-size: 1.15rem; box-shadow: 0 0 25px {theme_color}80; transition: transform 0.3s ease;
|
| 169 |
<i class="fa-solid fa-cloud-arrow-down" style="margin-right: 8px;"></i> Download APK via Secure Link
|
| 170 |
</a>
|
| 171 |
<p style="font-size: 0.8rem; color: #64748b; margin-top: 15px; margin-bottom: 0;">
|
|
@@ -207,7 +197,7 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
|
|
| 207 |
</div>
|
| 208 |
"""
|
| 209 |
word_count = str(len(html_template.split()))
|
| 210 |
-
keyword_density = str(html_template.lower().count(title.lower()[:10]))
|
| 211 |
|
| 212 |
with open("latest_draft.txt", "w", encoding="utf-8") as f:
|
| 213 |
f.write(html_template)
|
|
@@ -218,10 +208,10 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
|
|
| 218 |
return f"Error generating HTML: {str(e)}", f"<b>Error occurred: {str(e)}</b>", "0", "0"
|
| 219 |
|
| 220 |
# -----------------------------
|
| 221 |
-
# GEMINI AI ENHANCER
|
| 222 |
# -----------------------------
|
| 223 |
def enhance_with_gemini(raw_html, style_name, state):
|
| 224 |
-
"""
|
| 225 |
if not state.get("logged_in") or (time.time() - state.get("login_time", 0) > 1800):
|
| 226 |
return "Session expired.", "Session Expired.", "0", "0", gr.update(visible=False)
|
| 227 |
|
|
@@ -231,14 +221,39 @@ def enhance_with_gemini(raw_html, style_name, state):
|
|
| 231 |
if not raw_html or raw_html.startswith("Error"):
|
| 232 |
return raw_html, "<b>Please generate Base HTML first before enhancing.</b>", "0", "0", gr.update(visible=False)
|
| 233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
try:
|
| 235 |
genai.configure(api_key=GEMINI_API_KEY)
|
| 236 |
-
|
|
|
|
| 237 |
|
| 238 |
prompt = f"""
|
| 239 |
You are the lead front-end developer for the 'Lexical Space' blog.
|
| 240 |
-
|
| 241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
|
| 243 |
STRICT RULES:
|
| 244 |
1. CRITICAL: DO NOT remove or alter the `<script type="application/ld+json">` blocks. They are critical for SEO.
|
|
@@ -246,11 +261,6 @@ def enhance_with_gemini(raw_html, style_name, state):
|
|
| 246 |
3. DO NOT hallucinate or change the factual data (file size, version, rating, text content).
|
| 247 |
4. ONLY output raw HTML. Do not wrap your response in ```html blocks. Do not add conversational intro/outro text.
|
| 248 |
|
| 249 |
-
Theme Guidelines for '{style_name}':
|
| 250 |
-
- If 'Lexical Standard': Deep space background (#0f172a), neon accents, glassmorphism filters, glowing borders, and pulse animations.
|
| 251 |
-
- If 'Lexical Minimalist': Cleaner, fewer borders, flat white/light-gray or pure black backgrounds, high readability, subtle drop shadows instead of neon glow.
|
| 252 |
-
- If 'Lexical Max Store': Replicate a premium mobile app store UI (like Google Play / App Store). Use grid layouts, highly rounded corners (24px), large action buttons, and emphasize the app icon and download statistics.
|
| 253 |
-
|
| 254 |
Base HTML Code to Enhance:
|
| 255 |
{raw_html}
|
| 256 |
"""
|
|
@@ -293,7 +303,7 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
|
|
| 293 |
# --- MAIN APPLICATION DASHBOARD ---
|
| 294 |
with gr.Group(visible=False) as main_app:
|
| 295 |
gr.Markdown("# 🚀 Lexical Space V2 Post Generator")
|
| 296 |
-
gr.Markdown("Search the Play Store, inject mods, and generate SEO-optimized HTML
|
| 297 |
|
| 298 |
with gr.Row():
|
| 299 |
# --- LEFT COLUMN: SETTINGS ---
|
|
@@ -303,21 +313,22 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
|
|
| 303 |
link_input = gr.Textbox(label="Your Download Link (Mega, PixelDrain, etc.)", placeholder="https://...")
|
| 304 |
features_input = gr.Textbox(label="Mod Features (Comma separated)", placeholder="Premium Unlocked, No Ads", value="Premium Unlocked, No Ads, Analytics Removed")
|
| 305 |
|
| 306 |
-
with gr.Accordion("Theme & XML Upload
|
| 307 |
-
|
|
|
|
| 308 |
save_theme_btn = gr.Button("Save Theme to Dataset")
|
| 309 |
theme_status_out = gr.Textbox(label="Theme Status", interactive=False)
|
| 310 |
|
| 311 |
-
with gr.Accordion("Advanced SEO
|
| 312 |
-
theme_color = gr.ColorPicker(label="
|
| 313 |
-
telegram_link = gr.Textbox(label="Your Telegram Channel Link", value="https://t.me/lexicalspace")
|
| 314 |
custom_size = gr.Textbox(label="Custom File Size Override (e.g. 150 MB)", placeholder="Optional Override...")
|
| 315 |
custom_date = gr.Textbox(label="Custom Updated Date Override (e.g. January 15, 2026)", placeholder="Optional Override...")
|
| 316 |
|
| 317 |
generate_btn = gr.Button("⚙️ Generate Base HTML", variant="primary")
|
| 318 |
|
| 319 |
gr.Markdown("<hr>")
|
| 320 |
-
gr.Markdown("### 2. AI Style Enhancer (Gemini)")
|
| 321 |
with gr.Row():
|
| 322 |
style_dropdown = gr.Dropdown(
|
| 323 |
choices=["Lexical Standard", "Lexical Minimalist", "Lexical Max Store"],
|
|
@@ -325,7 +336,7 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
|
|
| 325 |
value="Lexical Standard",
|
| 326 |
scale=2
|
| 327 |
)
|
| 328 |
-
enhance_btn = gr.Button("✨ Enhance
|
| 329 |
|
| 330 |
gr.Markdown("<hr>")
|
| 331 |
gr.Markdown("### Post Statistics")
|
|
|
|
| 48 |
token=HF_TOKEN,
|
| 49 |
commit_message="Updated website theme XML"
|
| 50 |
)
|
| 51 |
+
return "✅ Theme successfully pushed to your private dataset! Gemini will now use this for styling."
|
| 52 |
|
| 53 |
except Exception as e:
|
| 54 |
return f"❌ Error saving theme to dataset: {e}"
|
|
|
|
| 129 |
}
|
| 130 |
schema_script = f'<script type="application/ld+json">\n[{json.dumps(schema_app)}, {json.dumps(schema_faq)}, {json.dumps(schema_sysreq)}]\n</script>'
|
| 131 |
|
| 132 |
+
# Fetch basic background color if we want a baseline, AI will handle the rest later
|
| 133 |
+
theme_background = "#0f172a"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
+
# Final Base HTML Template Construction (Fallback style before AI applies XML exact styles)
|
| 136 |
html_template = f"""
|
| 137 |
{schema_script}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
<div style="display: none;">
|
| 139 |
<img src="{icon_url}" alt="Download {title} Mod APK" />
|
| 140 |
</div>
|
|
|
|
| 155 |
</div>
|
| 156 |
|
| 157 |
<div style="text-align: center; margin-bottom: 35px; background: #020617; padding: 25px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.02);">
|
| 158 |
+
<a href="{custom_link}" target="_blank" rel="nofollow noopener" class="lex-btn" style="display: inline-block; width: 100%; max-width: 400px; background: {theme_color}; color: #fff; text-decoration: none; padding: 16px; border-radius: 50px; font-weight: 800; font-size: 1.15rem; box-shadow: 0 0 25px {theme_color}80; transition: transform 0.3s ease;">
|
| 159 |
<i class="fa-solid fa-cloud-arrow-down" style="margin-right: 8px;"></i> Download APK via Secure Link
|
| 160 |
</a>
|
| 161 |
<p style="font-size: 0.8rem; color: #64748b; margin-top: 15px; margin-bottom: 0;">
|
|
|
|
| 197 |
</div>
|
| 198 |
"""
|
| 199 |
word_count = str(len(html_template.split()))
|
| 200 |
+
keyword_density = str(html_template.lower().count(title.lower()[:10]))
|
| 201 |
|
| 202 |
with open("latest_draft.txt", "w", encoding="utf-8") as f:
|
| 203 |
f.write(html_template)
|
|
|
|
| 208 |
return f"Error generating HTML: {str(e)}", f"<b>Error occurred: {str(e)}</b>", "0", "0"
|
| 209 |
|
| 210 |
# -----------------------------
|
| 211 |
+
# GEMINI AI ENHANCER (PRO MODEL + XML FETCH)
|
| 212 |
# -----------------------------
|
| 213 |
def enhance_with_gemini(raw_html, style_name, state):
|
| 214 |
+
"""Downloads XML from Dataset, reads it, and uses Gemini 1.5 Pro to exact-match the styles."""
|
| 215 |
if not state.get("logged_in") or (time.time() - state.get("login_time", 0) > 1800):
|
| 216 |
return "Session expired.", "Session Expired.", "0", "0", gr.update(visible=False)
|
| 217 |
|
|
|
|
| 221 |
if not raw_html or raw_html.startswith("Error"):
|
| 222 |
return raw_html, "<b>Please generate Base HTML first before enhancing.</b>", "0", "0", gr.update(visible=False)
|
| 223 |
|
| 224 |
+
# 1. Fetch the exact XML file from Hugging Face Dataset
|
| 225 |
+
xml_content = ""
|
| 226 |
+
try:
|
| 227 |
+
downloaded_theme_path = hf_hub_download(
|
| 228 |
+
repo_id=DATASET_REPO,
|
| 229 |
+
filename=THEME_FILE_NAME,
|
| 230 |
+
repo_type="dataset",
|
| 231 |
+
token=HF_TOKEN
|
| 232 |
+
)
|
| 233 |
+
with open(downloaded_theme_path, "r", encoding="utf-8") as f:
|
| 234 |
+
xml_content = f.read()
|
| 235 |
+
except Exception as e:
|
| 236 |
+
print(f"Failed to fetch XML: {e}")
|
| 237 |
+
xml_content = "WARNING: Could not fetch website_theme.xml from dataset. Please apply generic high-quality styles based on the name."
|
| 238 |
+
|
| 239 |
+
# 2. Configure Gemini Pro (Best for massive context like full XML files)
|
| 240 |
try:
|
| 241 |
genai.configure(api_key=GEMINI_API_KEY)
|
| 242 |
+
# Using Gemini 1.5 Pro because it excels at parsing massive context (XML files) and strict coding rules.
|
| 243 |
+
model = genai.GenerativeModel('gemini-1.5-pro')
|
| 244 |
|
| 245 |
prompt = f"""
|
| 246 |
You are the lead front-end developer for the 'Lexical Space' blog.
|
| 247 |
+
Your task is to restyle a raw HTML app post to EXACTLY match the design system of the website.
|
| 248 |
+
|
| 249 |
+
Below is the raw source code of the website's theme XML. It contains the exact CSS definitions, classes, ID's, CSS variables (like colors, fonts), and HTML structures used for the site.
|
| 250 |
+
|
| 251 |
+
<WEBSITE_THEME_XML>
|
| 252 |
+
{xml_content}
|
| 253 |
+
</WEBSITE_THEME_XML>
|
| 254 |
+
|
| 255 |
+
I want you to format the following Base HTML App Post to match the style known as: '{style_name}'.
|
| 256 |
+
Look through the <WEBSITE_THEME_XML> provided above. Find the CSS classes, inline styles, or component structures that correspond to '{style_name}'. Apply those exact classes, color hexes, and layout structures to the Base HTML. DO NOT invent styles—extract them from the XML.
|
| 257 |
|
| 258 |
STRICT RULES:
|
| 259 |
1. CRITICAL: DO NOT remove or alter the `<script type="application/ld+json">` blocks. They are critical for SEO.
|
|
|
|
| 261 |
3. DO NOT hallucinate or change the factual data (file size, version, rating, text content).
|
| 262 |
4. ONLY output raw HTML. Do not wrap your response in ```html blocks. Do not add conversational intro/outro text.
|
| 263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
Base HTML Code to Enhance:
|
| 265 |
{raw_html}
|
| 266 |
"""
|
|
|
|
| 303 |
# --- MAIN APPLICATION DASHBOARD ---
|
| 304 |
with gr.Group(visible=False) as main_app:
|
| 305 |
gr.Markdown("# 🚀 Lexical Space V2 Post Generator")
|
| 306 |
+
gr.Markdown("Search the Play Store, inject mods, and generate SEO-optimized HTML matching your XML theme.")
|
| 307 |
|
| 308 |
with gr.Row():
|
| 309 |
# --- LEFT COLUMN: SETTINGS ---
|
|
|
|
| 313 |
link_input = gr.Textbox(label="Your Download Link (Mega, PixelDrain, etc.)", placeholder="https://...")
|
| 314 |
features_input = gr.Textbox(label="Mod Features (Comma separated)", placeholder="Premium Unlocked, No Ads", value="Premium Unlocked, No Ads, Analytics Removed")
|
| 315 |
|
| 316 |
+
with gr.Accordion("Theme & XML Upload", open=False):
|
| 317 |
+
gr.Markdown("*Upload your Blogger XML theme here. It is saved to your private Hugging Face Dataset and read by Gemini for exact styling.*")
|
| 318 |
+
xml_theme_input = gr.File(label="Upload website_theme.xml")
|
| 319 |
save_theme_btn = gr.Button("Save Theme to Dataset")
|
| 320 |
theme_status_out = gr.Textbox(label="Theme Status", interactive=False)
|
| 321 |
|
| 322 |
+
with gr.Accordion("Advanced SEO Settings", open=False):
|
| 323 |
+
theme_color = gr.ColorPicker(label="Fallback Accent Color", value="#3b82f6")
|
| 324 |
+
telegram_link = gr.Textbox(label="Your Telegram Channel Link", value="https://t.me/lexicalspace")
|
| 325 |
custom_size = gr.Textbox(label="Custom File Size Override (e.g. 150 MB)", placeholder="Optional Override...")
|
| 326 |
custom_date = gr.Textbox(label="Custom Updated Date Override (e.g. January 15, 2026)", placeholder="Optional Override...")
|
| 327 |
|
| 328 |
generate_btn = gr.Button("⚙️ Generate Base HTML", variant="primary")
|
| 329 |
|
| 330 |
gr.Markdown("<hr>")
|
| 331 |
+
gr.Markdown("### 2. AI Style Enhancer (Gemini Pro)")
|
| 332 |
with gr.Row():
|
| 333 |
style_dropdown = gr.Dropdown(
|
| 334 |
choices=["Lexical Standard", "Lexical Minimalist", "Lexical Max Store"],
|
|
|
|
| 336 |
value="Lexical Standard",
|
| 337 |
scale=2
|
| 338 |
)
|
| 339 |
+
enhance_btn = gr.Button("✨ Enhance with XML Styles", variant="secondary", scale=1)
|
| 340 |
|
| 341 |
gr.Markdown("<hr>")
|
| 342 |
gr.Markdown("### Post Statistics")
|