kacapower commited on
Commit
8e5fe2a
·
verified ·
1 Parent(s): ccbdf08

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -160
app.py CHANGED
@@ -54,8 +54,7 @@ def save_theme_to_dataset(xml_file):
54
  return f"❌ Error saving theme to dataset: {e}"
55
 
56
 
57
- def generate_blogger_html(app_query, custom_link, mod_features, theme_color, telegram_link, custom_size, custom_date, req_name, req_link, tutorial_link):
58
- """Scrapes Google Play and generates the base SEO-optimized Blogger HTML."""
59
  try:
60
  search_results = search(app_query, lang='en', country='us')
61
  if not search_results:
@@ -64,200 +63,164 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
64
  app_id = search_results[0]['appId']
65
  app_details = play_app(app_id, lang='en', country='us')
66
 
67
- # Data Extraction
68
  title = app_details.get('title', app_query)
69
  icon_url = app_details.get('icon', '')
70
  rating = round(app_details.get('score', 4.5), 1)
71
  reviews_count = app_details.get('ratings', 1000)
72
  category = app_details.get('genre', 'Utility')
73
  developer = app_details.get('developer', 'Unknown Developer')
74
-
75
- # --- INSTALL FORMATTER (10,000,000,000+ to 10B+) ---
76
- raw_installs = app_details.get('installs', '10,000+')
77
- clean_num = raw_installs.replace(',', '').replace('+', '')
78
- if clean_num.isdigit():
79
- num = int(clean_num)
80
- if num >= 1_000_000_000:
81
- installs = f"{num // 1_000_000_000}B+"
82
- elif num >= 1_000_000:
83
- installs = f"{num // 1_000_000}M+"
84
- elif num >= 1_000:
85
- installs = f"{num // 1_000}K+"
86
- else:
87
- installs = f"{num}+"
88
- else:
89
- installs = raw_installs
90
- # ---------------------------------------------------
91
-
92
  version = app_details.get('version', 'Varies with device')
 
93
 
94
- scraped_size = app_details.get('size', 'Varies')
95
- final_size = custom_size.strip() if custom_size else scraped_size
96
-
97
  updated_ts = app_details.get('updated', 0)
98
- scraped_date = datetime.fromtimestamp(updated_ts).strftime('%B %d, %Y') if updated_ts else "Recently"
99
- updated_date = custom_date.strip() if custom_date else scraped_date
100
-
101
- description = app_details.get('summary', 'Premium application with enhanced features.')
102
- full_description = app_details.get('descriptionHTML', description)
103
-
104
- # Media Extraction
105
  screenshots = app_details.get('screenshots', [])[:4]
106
  video_url = app_details.get('video', None)
107
 
108
- # Mod Features Formatting
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- features_list = ""
111
- for feature in mod_features.split(','):
112
- if feature.strip():
113
- features_list += f'<li style="margin-bottom: 10px;"><i class="fa-solid fa-check" style="color: {theme_color}; margin-right: 12px; font-size: 1.1rem;"></i> {feature.strip()}</li>\n'
114
-
115
- # Screenshot HTML Generation
116
- screenshots_html = ""
117
- if screenshots:
118
- screenshots_html = f'<h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-top: 35px; font-size: 1.4rem;">App Screenshots</h2><div style="display: flex; gap: 15px; overflow-x: auto; padding-bottom: 15px; scroll-snap-type: x mandatory; margin-bottom: 35px;">'
119
- for snap in screenshots:
120
- screenshots_html += f'<img src="{snap}" style="height: 300px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1); scroll-snap-align: start; box-shadow: 0 5px 15px rgba(0,0,0,0.3);">'
121
- screenshots_html += '</div>'
122
-
123
- # Video HTML Generation
124
- video_html = ""
125
- if video_url:
126
- embed_url = video_url.replace("watch?v=", "embed/")
127
- video_html = f'<h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-top: 35px; font-size: 1.4rem;">Official Trailer</h2><div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: 16px; box-shadow: 0 10px 25px rgba(0,0,0,0.4); margin-bottom: 35px;"><iframe src="{embed_url}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" allowfullscreen></iframe></div>'
128
-
129
- # SEO Schemas (App, FAQ, System Requirements)
130
- schema_app = {
131
- "@context": "https://schema.org", "@type": "SoftwareApplication", "name": title, "operatingSystem": "ANDROID", "applicationCategory": category, "image": icon_url,
132
- "author": { "@type": "Organization", "name": developer },
133
- "aggregateRating": { "@type": "AggregateRating", "ratingValue": str(rating), "ratingCount": str(reviews_count) },
134
- "offers": { "@type": "Offer", "price": "0.00", "priceCurrency": "USD" }
135
- }
136
- schema_faq = {
137
- "@context": "https://schema.org", "@type": "FAQPage",
138
- "mainEntity": [
139
- {"@type": "Question", "name": f"Is {title} Mod APK safe?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, our mods are thoroughly scanned and tested."}},
140
- {"@type": "Question", "name": f"Does {title} require root access?", "acceptedAnswer": {"@type": "Answer", "text": "No, it works on any non-rooted Android device."}}
141
- ]
142
- }
143
- schema_sysreq = {
144
- "@context": "https://schema.org", "@type": "SoftwareApplication", "name": title, "operatingSystem": "ANDROID", "applicationCategory": category,
145
- "author": { "@type": "Organization", "name": developer },
146
- "requirements": { "@type": "SoftwareApplicationRequirements", "name": "Minimum System Requirements", "operatingSystem": "Android 9.0 (Pie)+", "ram": "4 GB+", "storage": "100 MB+" }
147
- }
148
- schema_script = f'<script type="application/ld+json">\n[{json.dumps(schema_app)}, {json.dumps(schema_faq)}, {json.dumps(schema_sysreq)}]\n</script>'
149
-
150
- # Final Base HTML Template Construction
151
- # Required App HTML Generation
152
 
153
- required_app_html = ""
154
- if req_name and req_link:
155
- required_app_html = f"""
156
- <h2 style="border-left: 5px solid #ef4444; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Additional Requirements</h2>
157
- <div style="background: rgba(239, 68, 68, 0.05); border: 1px solid rgba(239, 68, 68, 0.2); padding: 20px; border-radius: 16px; display: flex; align-items: center; gap: 15px; margin-bottom: 35px; flex-wrap: wrap;">
158
- <div style="width: 50px; height: 50px; background: rgba(239, 68, 68, 0.1); border-radius: 12px; display: flex; align-items: center; justify-content: center; color: #ef4444; font-size: 1.5rem; flex-shrink: 0;">
159
- <i class="fa-solid fa-puzzle-piece"></i>
160
- </div>
161
- <div style="flex: 1; min-width: 200px;">
162
- <h3 style="margin: 0 0 5px 0; font-size: 1.1rem; color: #fff;">{req_name.strip()}</h3>
163
- <p style="margin: 0; font-size: 0.85rem; color: #94a3b8;">This application requires a companion app to function properly.</p>
164
- </div>
165
- <a href="{req_link.strip()}" target="_blank" rel="nofollow noopener" style="background: #ef4444; color: #fff; padding: 10px 20px; border-radius: 50px; text-decoration: none; font-weight: 700; font-size: 0.9rem; transition: 0.3s; white-space: nowrap; box-shadow: 0 5px 15px rgba(239, 68, 68, 0.3);">
166
- Get Companion <i class="fa-solid fa-download" style="margin-left: 5px;"></i>
167
- </a>
168
- </div>
169
- """
170
 
171
- # Tutorial Button HTML Generation
172
- tutorial_html = ""
173
- if tutorial_link:
174
- tutorial_html = f'<a href="{tutorial_link.strip()}" target="_blank" style="color: #a855f7; text-decoration: none; transition: 0.2s;"><i class="fa-solid fa-book-open"></i> View Tutorial</a>'
175
 
176
- # Final Base HTML Template Construction
 
 
 
 
 
177
  html_template = f"""
178
  {schema_script}
179
-
180
- <div style="display: none;">
181
- <img src="{icon_url}" alt="Download {title} Mod APK" />
182
- </div>
183
 
184
  <div class="app-post-wrapper" style="background: #0f172a; width: 100%; min-height: 100vh; margin: 0; padding: 40px 5%; box-sizing: border-box; color: #fff; font-family: 'Plus Jakarta Sans', sans-serif;">
185
 
186
  <div style="display: flex; gap: 20px; align-items: center; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 25px; margin-bottom: 25px; flex-wrap: wrap;">
187
  <img src="{icon_url}" alt="{title} Premium" style="width: 110px; height: 110px; border-radius: 28px; box-shadow: 0 10px 20px rgba(0,0,0,0.5); flex-shrink: 0;">
188
  <div style="flex: 1; min-width: 250px;">
189
- <h1 style="margin: 0 0 10px 0; font-size: 2.3rem; font-weight: 800; line-height: 1.1;">{title} <span style="font-size: 0.85rem; background: {theme_color}; padding: 5px 12px; border-radius: 12px; vertical-align: middle; margin-left: 10px; letter-spacing: 1px;">MOD</span></h1>
190
- <p style="margin: 0 0 15px 0; color: #94a3b8; font-weight: 600; font-size: 1.05rem;"><i class="fa-solid fa-layer-group"></i> {category} • Max Store Verified</p>
191
- <div style="display: flex; flex-wrap: wrap; gap: 20px; font-size: 0.95rem; color: #cbd5e1; font-weight: 700;">
192
- <span><i class="fa-solid fa-star" style="color:#f59e0b;"></i> {rating}</span>
193
  <span><i class="fa-solid fa-download" style="color: #38bdf8;"></i> {installs}</span>
194
- <span><i class="fa-brands fa-android" style="color: #10b981;"></i> Android 9.0+</span>
195
  </div>
196
  </div>
197
  </div>
198
 
199
  <div style="text-align: center; margin-bottom: 35px; background: #020617; padding: 30px 15px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.03);">
200
- <div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 15px; margin-bottom: 15px;">
201
- <a href="{custom_link}" target="_blank" rel="nofollow noopener" class="lex-btn" style="flex: 1; min-width: 260px; max-width: 400px; background: {theme_color}; color: #fff; text-decoration: none; padding: 16px 20px; border-radius: 50px; font-weight: 800; font-size: 1.1rem; box-shadow: 0 0 25px {theme_color}80; transition: transform 0.3s ease; box-sizing: border-box;">
202
- <i class="fa-solid fa-cloud-arrow-down" style="margin-right: 8px;"></i> Secure APK Download
203
- </a>
204
-
205
- <a href="https://play.google.com/store/apps/details?id={app_id}" target="_blank" rel="nofollow noopener" style="flex: 1; min-width: 260px; max-width: 400px; background: #10b981; color: #fff; text-decoration: none; padding: 16px 20px; border-radius: 50px; font-weight: 800; font-size: 1.1rem; box-shadow: 0 0 25px rgba(16, 185, 129, 0.4); transition: transform 0.3s ease; box-sizing: border-box;">
206
- <i class="fa-brands fa-google-play" style="margin-right: 8px;"></i> Get it on Play Store
207
- </a>
208
  </div>
209
- <p style="font-size: 0.85rem; color: #64748b; margin: 0;">
210
- <i class="fa-solid fa-shield-halved" style="color: #10b981;"></i> Links encrypted. VirusTotal checked.
211
- </p>
212
 
213
  <div style="display: flex; justify-content: center; flex-wrap: wrap; gap: 20px; margin-top: 20px; font-size: 0.9rem; font-weight: 600;">
214
- {tutorial_html}
215
- <a href="mailto:admin@lexicalspace.com?subject=Broken Link Report: {title}" style="color: #ef4444; text-decoration: none; transition: 0.2s;"><i class="fa-solid fa-link-slash"></i> Link not working?</a>
216
- <a href="mailto:admin@lexicalspace.com?subject=App Issue Report: {title}" style="color: #f59e0b; text-decoration: none; transition: 0.2s;"><i class="fa-solid fa-flag"></i> Report Issue</a>
217
  </div>
218
  </div>
219
 
220
- <div style="background: rgba(56, 189, 248, 0.1); border: 1px solid rgba(56, 189, 248, 0.2); padding: 15px; border-radius: 16px; text-align: center; margin-bottom: 35px;">
221
- <strong style="color: #e2e8f0; margin-right: 15px; font-size: 1.05rem;">Join Lexical Space Community:</strong>
222
- <a href="{telegram_link}" target="_blank" style="display: inline-block; background: #0088cc; color: white; padding: 8px 20px; border-radius: 25px; text-decoration: none; font-weight: bold; font-size: 0.95rem; transition: 0.2s; margin-top: 10px;">✈️ Telegram</a>
 
 
 
223
  </div>
224
 
225
- {required_app_html}
 
226
 
227
  <h2 style="border-left: 5px solid #38bdf8; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">App Information</h2>
228
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; margin-bottom: 35px; background: rgba(255,255,255,0.02); padding: 20px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.05); box-shadow: inset 0 0 15px rgba(0,0,0,0.3);">
229
- <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.8rem; color: #94a3b8; text-transform: uppercase; margin-bottom: 5px;">Developer</span><strong style="font-size: 1.05rem;">{developer}</strong></div>
230
- <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.8rem; color: #94a3b8; text-transform: uppercase; margin-bottom: 5px;">Version</span><strong style="font-size: 1.05rem;">{version}</strong></div>
231
- <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.8rem; color: #94a3b8; text-transform: uppercase; margin-bottom: 5px;">Updated</span><strong style="font-size: 1.05rem;">{updated_date}</strong></div>
232
- <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.8rem; color: #94a3b8; text-transform: uppercase; margin-bottom: 5px;">File Size</span><strong style="font-size: 1.05rem;">{final_size}</strong></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  </div>
234
 
235
  {video_html}
236
  {screenshots_html}
237
 
238
- <h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Max Store Modifications</h2>
239
- <div style="background: rgba(16, 185, 129, 0.05); border: 1px solid rgba(16, 185, 129, 0.2); padding: 25px; border-radius: 16px; margin-bottom: 40px; box-shadow: 0 5px 20px rgba(16, 185, 129, 0.1);">
240
- <ul style="color: #f1f5f9; line-height: 2; list-style-type: none; padding-left: 0; margin: 0; font-weight: 700; font-size: 1.05rem;">
241
- {features_list}
242
- </ul>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  </div>
244
 
245
- <h2 style="border-left: 5px solid #f59e0b; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">About {title}</h2>
246
- <div style="color: #cbd5e1; line-height: 1.8; font-size: 1rem; overflow: hidden;">
 
 
247
  {full_description}
248
  </div>
249
 
250
- <div style="margin-top: 40px; padding-top: 25px; border-top: 1px solid rgba(255,255,255,0.1); font-size: 0.85rem; color: #64748b; text-align: center;">
251
- DMCA: Lexical Space complies with 17 U.S.C. § 512 and the Digital Millennium Copyright Act. All apps are property of their respective owners.
252
  </div>
253
  </div>
254
  """
255
-
256
-
257
-
258
-
259
  word_count = str(len(html_template.split()))
260
-
261
  keyword_density = str(html_template.lower().count(title.lower()[:10]))
262
 
263
  with open("latest_draft.txt", "w", encoding="utf-8") as f:
@@ -267,7 +230,6 @@ def generate_blogger_html(app_query, custom_link, mod_features, theme_color, tel
267
 
268
  except Exception as e:
269
  return f"Error generating HTML: {str(e)}", f"<b>Error occurred: {str(e)}</b>", "0", "0"
270
-
271
  # -----------------------------
272
  # OPENROUTER AI ENHANCER (XML FETCH + CLAUDE/GPT/GEMINI)
273
  # -----------------------------
@@ -396,27 +358,41 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
396
 
397
  with gr.Row():
398
  # --- LEFT COLUMN: SETTINGS ---
 
399
  with gr.Column(scale=1):
400
  gr.Markdown("### 1. App Parameters")
401
- app_input = gr.Textbox(label="App Name (e.g., TeraBox, YouTube ReVanced)", placeholder="Search query for Play Store...")
402
- link_input = gr.Textbox(label="Your Download Link (Mega, PixelDrain, etc.)", placeholder="https://...")
403
- features_input = gr.Textbox(label="Mod Features (Comma separated)", placeholder="Premium Unlocked, No Ads", value="Premium Unlocked, No Ads, Analytics Removed")
 
 
404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  with gr.Accordion("Theme & XML Upload", open=False):
406
- gr.Markdown("*Upload your Blogger XML theme here. It is saved to your private Hugging Face Dataset and read by the AI for exact styling.*")
407
  xml_theme_input = gr.File(label="Upload website_theme.xml")
408
  save_theme_btn = gr.Button("Save Theme to Dataset")
409
  theme_status_out = gr.Textbox(label="Theme Status", interactive=False)
410
- with gr.Accordion("Companion/Required App (Optional)", open=False):
411
- req_app_name = gr.Textbox(label="Companion App Name (e.g., MicroG)", placeholder="Leave blank if none...")
412
- req_app_link = gr.Textbox(label="Companion App Download Link", placeholder="https://...")
413
- tutorial_link = gr.Textbox(label="Tutorial/Guide Link (YouTube or Blog)", placeholder="https://...")
414
-
415
- with gr.Accordion("Advanced SEO Settings", open=False):
416
- theme_color = gr.ColorPicker(label="Fallback Accent Color", value="#3b82f6")
417
- telegram_link = gr.Textbox(label="Your Telegram Channel Link", value="https://t.me/lexicalspace")
418
- custom_size = gr.Textbox(label="Custom File Size Override (e.g. 150 MB)", placeholder="Optional Override...")
419
- custom_date = gr.Textbox(label="Custom Updated Date Override (e.g. January 15, 2026)", placeholder="Optional Override...")
420
 
421
  generate_btn = gr.Button("⚙️ Generate Base HTML", variant="primary")
422
 
@@ -469,12 +445,16 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
469
  else:
470
  return state, gr.update(visible=True), gr.update(visible=False), gr.update(value="❌ Incorrect password.", visible=True)
471
 
472
- def secure_generate(app_query, custom_link, mod_features, t_color, t_link, c_size, c_date, req_name, req_link, tutorial_link, state):
473
  if not state.get("logged_in") or (time.time() - state.get("login_time", 0) > 1800):
474
  state["logged_in"] = False
475
  return ("Session expired.", "Session expired.", "0", "0", gr.update(visible=True), gr.update(visible=False), state, gr.update(visible=False))
476
 
477
- code, preview, words, keywords = generate_blogger_html(app_query, custom_link, mod_features, t_color, t_link, c_size, c_date, req_name, req_link, tutorial_link)
 
 
 
 
478
 
479
  if os.path.exists("latest_draft.txt") and not code.startswith("Error"):
480
  file_update = gr.update(value="latest_draft.txt", visible=True)
@@ -498,7 +478,7 @@ with gr.Blocks(title="Lexical Space Internal Tool", theme=gr.themes.Monochrome(p
498
 
499
  generate_btn.click(
500
  fn=secure_generate,
501
- inputs=[app_input, link_input, features_input, theme_color, telegram_link, custom_size, custom_date, req_app_name, req_app_link, tutorial_link, session_state],
502
  outputs=[html_output, preview_output, word_count_out, kw_density_out, login_screen, main_app, session_state, file_download]
503
  )
504
 
 
54
  return f"❌ Error saving theme to dataset: {e}"
55
 
56
 
57
+ def generate_blogger_html(app_query, custom_link, mirror_1, mirror_2, mod_features, theme_color, telegram_link, custom_size, custom_date, req_name, req_link, tutorial_link, root_req, arch_input, lexical_score, pros_input, cons_input, vt_link, related_name, related_link, coffee_link):
 
58
  try:
59
  search_results = search(app_query, lang='en', country='us')
60
  if not search_results:
 
63
  app_id = search_results[0]['appId']
64
  app_details = play_app(app_id, lang='en', country='us')
65
 
66
+ # Base Extractions
67
  title = app_details.get('title', app_query)
68
  icon_url = app_details.get('icon', '')
69
  rating = round(app_details.get('score', 4.5), 1)
70
  reviews_count = app_details.get('ratings', 1000)
71
  category = app_details.get('genre', 'Utility')
72
  developer = app_details.get('developer', 'Unknown Developer')
73
+ installs = app_details.get('installs', '10,000+')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  version = app_details.get('version', 'Varies with device')
75
+ recent_changes = app_details.get('recentChanges', '')
76
 
77
+ final_size = custom_size.strip() if custom_size else app_details.get('size', 'Varies')
 
 
78
  updated_ts = app_details.get('updated', 0)
79
+ final_date = custom_date.strip() if custom_date else (datetime.fromtimestamp(updated_ts).strftime('%B %d, %Y') if updated_ts else "Recently")
80
+ full_description = app_details.get('descriptionHTML', app_details.get('summary', 'Premium app.'))
 
 
 
 
 
81
  screenshots = app_details.get('screenshots', [])[:4]
82
  video_url = app_details.get('video', None)
83
 
84
+ # 1. Mod Features
85
+ features_list = "".join([f'<li style="margin-bottom: 10px;"><i class="fa-solid fa-check" style="color: {theme_color}; margin-right: 12px; font-size: 1.1rem;"></i> {f.strip()}</li>\n' for f in mod_features.split(',') if f.strip()])
86
+
87
+ # 2. Pros & Cons
88
+ pros_html = "".join([f'<li style="margin-bottom: 6px;"><i class="fa-solid fa-plus" style="color: #10b981; margin-right: 8px;"></i> {p.strip()}</li>' for p in pros_input.split(',') if p.strip()])
89
+ cons_html = "".join([f'<li style="margin-bottom: 6px;"><i class="fa-solid fa-minus" style="color: #ef4444; margin-right: 8px;"></i> {c.strip()}</li>' for c in cons_input.split(',') if c.strip()])
90
+
91
+ # 3. Dynamic Links (Mirrors, VT, Coffee)
92
+ mirror1_html = f'<a href="{mirror_1.strip()}" target="_blank" style="flex: 1; min-width: 150px; background: rgba(255,255,255,0.1); color: #fff; text-decoration: none; padding: 12px 15px; border-radius: 50px; font-weight: 700; border: 1px solid rgba(255,255,255,0.2);"><i class="fa-solid fa-server"></i> Mirror 1</a>' if mirror_1 else ""
93
+ mirror2_html = f'<a href="{mirror_2.strip()}" target="_blank" style="flex: 1; min-width: 150px; background: rgba(255,255,255,0.1); color: #fff; text-decoration: none; padding: 12px 15px; border-radius: 50px; font-weight: 700; border: 1px solid rgba(255,255,255,0.2);"><i class="fa-solid fa-server"></i> Mirror 2</a>' if mirror_2 else ""
94
+ vt_html = f'<p style="font-size: 0.85rem; color: #10b981; margin-top: 15px;"><a href="{vt_link.strip()}" target="_blank" style="color: #10b981; text-decoration: none;"><i class="fa-solid fa-shield-check"></i> 100% Safe - Verified by VirusTotal Scan</a></p>' if vt_link else '<p style="font-size: 0.85rem; color: #64748b; margin-top: 15px;"><i class="fa-solid fa-shield-halved"></i> Links encrypted. Checked for safety.</p>'
95
+ coffee_html = f'<a href="{coffee_link.strip()}" target="_blank" style="display: inline-block; background: #ffdd00; color: #000; padding: 8px 20px; border-radius: 25px; text-decoration: none; font-weight: bold; font-size: 0.95rem; transition: 0.2s;">☕ Buy Me a Coffee</a>' if coffee_link else ""
96
+
97
+ # 4. Optional Blocks (Changelog, Companion, Related)
98
+ changelog_block = f'<h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-bottom: 15px; font-size: 1.4rem;">What\'s New</h2><div style="background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.05); padding: 15px; border-radius: 12px; font-family: monospace; color: #10b981; margin-bottom: 35px; white-space: pre-wrap; font-size: 0.9rem;">{recent_changes}</div>' if recent_changes else ""
99
 
100
+ related_html = f'<div style="border: 1px dashed {theme_color}; padding: 25px; border-radius: 16px; text-align: center; margin-bottom: 35px;"><h3 style="margin-top:0; color:#fff;">Looking for more?</h3><a href="{related_link.strip()}" style="color: {theme_color}; font-weight: 800; font-size: 1.1rem; text-decoration: none;">Download {related_name.strip()} Mod APK <i class="fa-solid fa-arrow-right"></i></a></div>' if related_name and related_link else ""
101
+
102
+ req_app_html = f'<h2 style="border-left: 5px solid #ef4444; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Requirements</h2><div style="background: rgba(239, 68, 68, 0.05); border: 1px solid rgba(239, 68, 68, 0.2); padding: 20px; border-radius: 16px; display: flex; align-items: center; gap: 15px; margin-bottom: 35px;"><div style="width: 50px; height: 50px; background: rgba(239, 68, 68, 0.1); border-radius: 12px; display: flex; align-items: center; justify-content: center; color: #ef4444; font-size: 1.5rem;"><i class="fa-solid fa-puzzle-piece"></i></div><div style="flex: 1;"><h3 style="margin: 0 0 5px 0; font-size: 1.1rem;">{req_name}</h3><p style="margin: 0; font-size: 0.85rem; color: #94a3b8;">Companion app required.</p></div><a href="{req_link}" target="_blank" style="background: #ef4444; color: #fff; padding: 10px 20px; border-radius: 50px; text-decoration: none; font-weight: 700;">Install</a></div>' if req_name and req_link else ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ tutorial_btn = f'<a href="{tutorial_link.strip()}" target="_blank" style="color: #a855f7; text-decoration: none; transition: 0.2s;"><i class="fa-solid fa-book-open"></i> View Tutorial</a>' if tutorial_link else ""
105
+
106
+ # Media Blocks
107
+ screenshots_html = f'<h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-top: 35px; font-size: 1.4rem;">App Screenshots</h2><div style="display: flex; gap: 15px; overflow-x: auto; padding-bottom: 15px; scroll-snap-type: x mandatory; margin-bottom: 35px;">' + "".join([f'<img src="{s}" style="height: 300px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1); scroll-snap-align: start;">' for s in screenshots]) + '</div>' if screenshots else ""
108
+ video_html = f'<h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-top: 35px; font-size: 1.4rem;">Trailer</h2><div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: 16px; margin-bottom: 35px;"><iframe src="{video_url.replace("watch?v=", "embed/")}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" frameborder="0" allowfullscreen></iframe></div>' if video_url else ""
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
+ root_color = "#10b981" if "No" in root_req else "#ef4444"
 
 
 
111
 
112
+ # Schemas
113
+ schema_app = {"@context": "https://schema.org", "@type": "SoftwareApplication", "name": title, "operatingSystem": "ANDROID", "applicationCategory": category, "image": icon_url, "aggregateRating": {"@type": "AggregateRating", "ratingValue": str(rating), "ratingCount": str(reviews_count)}}
114
+ schema_faq = {"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": f"Is {title} Mod safe?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, verified by Lexical Space."}}]}
115
+ schema_script = f'<script type="application/ld+json">\n[{json.dumps(schema_app)}, {json.dumps(schema_faq)}]\n</script>'
116
+
117
+ # THE FINAL HTML
118
  html_template = f"""
119
  {schema_script}
120
+ <div style="display: none;"><img src="{icon_url}" alt="Download {title} Mod APK" /></div>
 
 
 
121
 
122
  <div class="app-post-wrapper" style="background: #0f172a; width: 100%; min-height: 100vh; margin: 0; padding: 40px 5%; box-sizing: border-box; color: #fff; font-family: 'Plus Jakarta Sans', sans-serif;">
123
 
124
  <div style="display: flex; gap: 20px; align-items: center; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 25px; margin-bottom: 25px; flex-wrap: wrap;">
125
  <img src="{icon_url}" alt="{title} Premium" style="width: 110px; height: 110px; border-radius: 28px; box-shadow: 0 10px 20px rgba(0,0,0,0.5); flex-shrink: 0;">
126
  <div style="flex: 1; min-width: 250px;">
127
+ <h1 style="margin: 0 0 10px 0; font-size: 2.3rem; font-weight: 800; line-height: 1.1;">{title} <span style="font-size: 0.85rem; background: {theme_color}; padding: 5px 12px; border-radius: 12px; vertical-align: middle; margin-left: 10px;">MOD</span></h1>
128
+ <div style="display: flex; flex-wrap: wrap; gap: 20px; font-size: 0.95rem; color: #cbd5e1; font-weight: 700; margin-top: 15px;">
129
+ <span><i class="fa-solid fa-star" style="color:#f59e0b;"></i> {rating} (Play Store)</span>
130
+ <span><i class="fa-solid fa-award" style="color:#a855f7;"></i> {lexical_score}/10 (Lexical Score)</span>
131
  <span><i class="fa-solid fa-download" style="color: #38bdf8;"></i> {installs}</span>
 
132
  </div>
133
  </div>
134
  </div>
135
 
136
  <div style="text-align: center; margin-bottom: 35px; background: #020617; padding: 30px 15px; border-radius: 20px; border: 1px solid rgba(255,255,255,0.03);">
137
+ <div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 15px;">
138
+ <a href="{custom_link}" target="_blank" rel="nofollow noopener" style="flex: 2; min-width: 260px; max-width: 400px; background: {theme_color}; color: #fff; text-decoration: none; padding: 14px 20px; border-radius: 50px; font-weight: 800; font-size: 1.1rem; box-shadow: 0 0 25px {theme_color}80; transition: transform 0.3s ease;"><i class="fa-solid fa-cloud-arrow-down"></i> Download APK</a>
139
+ {mirror1_html}
140
+ {mirror2_html}
 
 
 
 
141
  </div>
142
+ {vt_html}
 
 
143
 
144
  <div style="display: flex; justify-content: center; flex-wrap: wrap; gap: 20px; margin-top: 20px; font-size: 0.9rem; font-weight: 600;">
145
+ {tutorial_btn}
146
+ <a href="mailto:admin@lexicalspace.com?subject=Broken Link Report: {title}" style="color: #ef4444; text-decoration: none;"><i class="fa-solid fa-link-slash"></i> Link not working?</a>
 
147
  </div>
148
  </div>
149
 
150
+ <div style="background: rgba(56, 189, 248, 0.05); border: 1px solid rgba(56, 189, 248, 0.2); padding: 20px; border-radius: 16px; text-align: center; margin-bottom: 35px; display: flex; flex-direction: column; align-items: center;">
151
+ <strong style="color: #e2e8f0; font-size: 1.05rem; margin-bottom: 12px;">Support Lexical Space:</strong>
152
+ <div style="display: flex; gap: 15px; flex-wrap: wrap; justify-content: center;">
153
+ <a href="{telegram_link}" target="_blank" style="background: #0088cc; color: white; padding: 8px 20px; border-radius: 25px; text-decoration: none; font-weight: bold; font-size: 0.95rem;">✈️ Join Telegram</a>
154
+ {coffee_html}
155
+ </div>
156
  </div>
157
 
158
+ {req_app_html}
159
+ {changelog_block}
160
 
161
  <h2 style="border-left: 5px solid #38bdf8; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">App Information</h2>
162
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; margin-bottom: 35px; background: rgba(255,255,255,0.02); padding: 20px; border-radius: 16px; border: 1px solid rgba(255,255,255,0.05);">
163
+ <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.75rem; color: #94a3b8; text-transform: uppercase;">Version</span><strong style="font-size: 1rem;">{version}</strong></div>
164
+ <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.75rem; color: #94a3b8; text-transform: uppercase;">File Size</span><strong style="font-size: 1rem;">{final_size}</strong></div>
165
+ <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.75rem; color: #94a3b8; text-transform: uppercase;">Architecture</span><strong style="font-size: 1rem;">{arch_input}</strong></div>
166
+ <div style="background: rgba(255,255,255,0.03); padding: 15px; border-radius: 10px;"><span style="display: block; font-size: 0.75rem; color: #94a3b8; text-transform: uppercase;">Root Access</span><strong style="font-size: 1rem; color: {root_color};">{root_req}</strong></div>
167
+ </div>
168
+
169
+ <h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Mod Features</h2>
170
+ <div style="background: rgba(16, 185, 129, 0.05); border: 1px solid rgba(16, 185, 129, 0.2); padding: 25px; border-radius: 16px; margin-bottom: 35px;">
171
+ <ul style="color: #f1f5f9; line-height: 2; list-style-type: none; padding-left: 0; margin: 0; font-weight: 700;">{features_list}</ul>
172
+ </div>
173
+
174
+ <h2 style="border-left: 5px solid {theme_color}; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Pros & Cons</h2>
175
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 35px;">
176
+ <div style="background: rgba(16, 185, 129, 0.05); border: 1px solid rgba(16, 185, 129, 0.2); padding: 20px; border-radius: 16px;">
177
+ <h3 style="color: #10b981; margin-top: 0; margin-bottom: 15px;"><i class="fa-solid fa-thumbs-up"></i> Pros</h3>
178
+ <ul style="list-style: none; padding: 0; margin: 0; color: #cbd5e1; line-height: 1.8;">{pros_html}</ul>
179
+ </div>
180
+ <div style="background: rgba(239, 68, 68, 0.05); border: 1px solid rgba(239, 68, 68, 0.2); padding: 20px; border-radius: 16px;">
181
+ <h3 style="color: #ef4444; margin-top: 0; margin-bottom: 15px;"><i class="fa-solid fa-thumbs-down"></i> Cons</h3>
182
+ <ul style="list-style: none; padding: 0; margin: 0; color: #cbd5e1; line-height: 1.8;">{cons_html}</ul>
183
+ </div>
184
  </div>
185
 
186
  {video_html}
187
  {screenshots_html}
188
 
189
+ <h2 style="border-left: 5px solid #f59e0b; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Installation Guide</h2>
190
+ <div style="background: rgba(255,255,255,0.02); padding: 25px; border-radius: 16px; margin-bottom: 35px;">
191
+ <ol style="color: #cbd5e1; line-height: 1.8; margin: 0; padding-left: 20px;">
192
+ <li style="margin-bottom: 10px;">Download the <strong>{title} Mod APK</strong> file from the secure link above.</li>
193
+ <li style="margin-bottom: 10px;">Go to your device <strong>Settings > Security</strong> and enable "Unknown Sources".</li>
194
+ <li style="margin-bottom: 10px;">Open your File Manager, locate the downloaded APK, and install it.</li>
195
+ <li>Launch the app and enjoy all premium features!</li>
196
+ </ol>
197
+ </div>
198
+
199
+ <h2 style="border-left: 5px solid #a855f7; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">Frequently Asked Questions</h2>
200
+ <div style="margin-bottom: 40px;">
201
+ <details style="background: rgba(255,255,255,0.03); padding: 15px 20px; border-radius: 12px; margin-bottom: 10px; cursor: pointer; border: 1px solid rgba(255,255,255,0.05);">
202
+ <summary style="font-weight: 700; color: #fff;">Is {title} Mod safe to use?</summary>
203
+ <p style="margin-top: 15px; margin-bottom: 0; color: #cbd5e1; line-height: 1.6;">Yes! All files on Lexical Space are strictly tested and verified. Always download directly from our site to ensure device security.</p>
204
+ </details>
205
+ <details style="background: rgba(255,255,255,0.03); padding: 15px 20px; border-radius: 12px; margin-bottom: 10px; cursor: pointer; border: 1px solid rgba(255,255,255,0.05);">
206
+ <summary style="font-weight: 700; color: #fff;">Do I need to root my device?</summary>
207
+ <p style="margin-top: 15px; margin-bottom: 0; color: #cbd5e1; line-height: 1.6;">Please refer to the "Root Access" status in the App Information box above. Most of our mods do not require root.</p>
208
+ </details>
209
  </div>
210
 
211
+ {related_html}
212
+
213
+ <h2 style="border-left: 5px solid #f59e0b; padding-left: 12px; margin-bottom: 20px; font-size: 1.4rem;">About Original {title}</h2>
214
+ <div style="color: #cbd5e1; line-height: 1.8; font-size: 1rem; overflow: hidden; margin-bottom: 40px;">
215
  {full_description}
216
  </div>
217
 
218
+ <div style="border-top: 1px solid rgba(255,255,255,0.1); padding-top: 20px; font-size: 0.75rem; color: #64748b; text-align: center;">
219
+ DMCA: Lexical Space complies with 17 U.S.C. § 512 and the Digital Millennium Copyright Act.
220
  </div>
221
  </div>
222
  """
 
 
 
 
223
  word_count = str(len(html_template.split()))
 
224
  keyword_density = str(html_template.lower().count(title.lower()[:10]))
225
 
226
  with open("latest_draft.txt", "w", encoding="utf-8") as f:
 
230
 
231
  except Exception as e:
232
  return f"Error generating HTML: {str(e)}", f"<b>Error occurred: {str(e)}</b>", "0", "0"
 
233
  # -----------------------------
234
  # OPENROUTER AI ENHANCER (XML FETCH + CLAUDE/GPT/GEMINI)
235
  # -----------------------------
 
358
 
359
  with gr.Row():
360
  # --- LEFT COLUMN: SETTINGS ---
361
+
362
  with gr.Column(scale=1):
363
  gr.Markdown("### 1. App Parameters")
364
+ app_input = gr.Textbox(label="App Name (e.g., TeraBox)", placeholder="Search query for Play Store...")
365
+ link_input = gr.Textbox(label="Primary Download Link", placeholder="https://...")
366
+ mirror_1 = gr.Textbox(label="Mirror 1 Link (Optional)", placeholder="https://...")
367
+ mirror_2 = gr.Textbox(label="Mirror 2 Link (Optional)", placeholder="https://...")
368
+ features_input = gr.Textbox(label="Mod Features (Comma separated)", value="Premium Unlocked, No Ads, Analytics Removed")
369
 
370
+ with gr.Accordion("Requirements & Tech Specs", open=False):
371
+ root_req = gr.Radio(choices=["No Root Required", "Root Required"], value="No Root Required", label="Root Status")
372
+ arch_input = gr.Textbox(label="Architecture", value="Universal (ARM64 & ARMv7)")
373
+ custom_size = gr.Textbox(label="Custom File Size Override")
374
+ custom_date = gr.Textbox(label="Custom Updated Date Override")
375
+ req_app_name = gr.Textbox(label="Companion App Name (Optional)")
376
+ req_app_link = gr.Textbox(label="Companion App Link (Optional)")
377
+
378
+ with gr.Accordion("Editorial, Pros & Cons", open=False):
379
+ lexical_score = gr.Slider(minimum=1, maximum=10, step=0.1, value=9.5, label="Lexical Mod Quality Score")
380
+ pros_input = gr.Textbox(label="Pros (Comma separated)", value="Fast performance, No ads, Premium unlocked")
381
+ cons_input = gr.Textbox(label="Cons (Comma separated)", value="Requires manual updates")
382
+ related_name = gr.Textbox(label="Related Mod Name (Optional)")
383
+ related_link = gr.Textbox(label="Related Mod Link (Optional)")
384
+
385
+ with gr.Accordion("Trust, SEO & Links", open=False):
386
+ vt_link = gr.Textbox(label="VirusTotal Scan Link (Optional)")
387
+ tutorial_link = gr.Textbox(label="Tutorial/Guide Link (Optional)")
388
+ coffee_link = gr.Textbox(label="Buy Me a Coffee Link", value="https://buymeacoffee.com/lexicalspace")
389
+ telegram_link = gr.Textbox(label="Telegram Channel", value="https://t.me/lexicalspace")
390
+ theme_color = gr.ColorPicker(label="Fallback Accent Color", value="#3b82f6")
391
+
392
  with gr.Accordion("Theme & XML Upload", open=False):
 
393
  xml_theme_input = gr.File(label="Upload website_theme.xml")
394
  save_theme_btn = gr.Button("Save Theme to Dataset")
395
  theme_status_out = gr.Textbox(label="Theme Status", interactive=False)
 
 
 
 
 
 
 
 
 
 
396
 
397
  generate_btn = gr.Button("⚙️ Generate Base HTML", variant="primary")
398
 
 
445
  else:
446
  return state, gr.update(visible=True), gr.update(visible=False), gr.update(value="❌ Incorrect password.", visible=True)
447
 
448
+ def secure_generate(app_query, custom_link, mirror_1, mirror_2, mod_features, theme_color, telegram_link, custom_size, custom_date, req_name, req_link, tutorial_link, root_req, arch_input, lexical_score, pros_input, cons_input, vt_link, related_name, related_link, coffee_link, state):
449
  if not state.get("logged_in") or (time.time() - state.get("login_time", 0) > 1800):
450
  state["logged_in"] = False
451
  return ("Session expired.", "Session expired.", "0", "0", gr.update(visible=True), gr.update(visible=False), state, gr.update(visible=False))
452
 
453
+ code, preview, words, keywords = generate_blogger_html(
454
+ app_query, custom_link, mirror_1, mirror_2, mod_features, theme_color, telegram_link,
455
+ custom_size, custom_date, req_name, req_link, tutorial_link, root_req, arch_input,
456
+ lexical_score, pros_input, cons_input, vt_link, related_name, related_link, coffee_link
457
+ )
458
 
459
  if os.path.exists("latest_draft.txt") and not code.startswith("Error"):
460
  file_update = gr.update(value="latest_draft.txt", visible=True)
 
478
 
479
  generate_btn.click(
480
  fn=secure_generate,
481
+ inputs=[app_input, link_input, mirror_1, mirror_2, features_input, theme_color, telegram_link, custom_size, custom_date, req_app_name, req_app_link, tutorial_link, root_req, arch_input, lexical_score, pros_input, cons_input, vt_link, related_name, related_link, coffee_link, session_state],
482
  outputs=[html_output, preview_output, word_count_out, kw_density_out, login_screen, main_app, session_state, file_download]
483
  )
484