mroccuper commited on
Commit
8012318
·
verified ·
1 Parent(s): 86f6c8a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +560 -55
app.py CHANGED
@@ -1,14 +1,564 @@
1
- import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import google.generativeai as genai
3
  import os
4
  from dotenv import load_dotenv
5
  import time
 
 
 
 
6
 
7
  # Load environment variables from .env file if it exists
8
  load_dotenv()
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  # Function to generate SEO plan with proper error handling
11
- def generate_seo_plan(topic, api_key, temperature=0.7, max_tokens=4000):
12
  # Input validation
13
  if not topic.strip():
14
  return "⚠️ Please enter a fermentation topic to generate an SEO plan."
@@ -34,10 +584,10 @@ def generate_seo_plan(topic, api_key, temperature=0.7, max_tokens=4000):
34
  )
35
 
36
  # Update status
37
- yield "🧠 Building SEO prompt for your fermentation topic..."
38
 
39
- # Build the prompt
40
- prompt = build_prompt(topic)
41
 
42
  # Update status
43
  yield "🚀 Generating SEO plan with Gemini 1.5 Pro..."
@@ -62,50 +612,9 @@ def generate_seo_plan(topic, api_key, temperature=0.7, max_tokens=4000):
62
  else:
63
  yield f"⚠️ Error: {error_message}"
64
 
65
- # Build enhanced SEO prompt for fermentation blog
66
- def build_prompt(topic):
67
- return f"""
68
- Act as an elite-level SEO strategist and content creator with deep expertise in food blogs, particularly fermentation. I run a blog about fermentation, and my primary goal is to increase organic traffic, educate beginners, and establish thought leadership. My target audience is beginners curious about home fermentation and health-conscious individuals.
69
-
70
- For the specific topic: '{topic}'
71
-
72
- Analyze and generate a comprehensive SEO content plan designed to rank highly on Google and provide exceptional user value. Ensure all outputs adhere to E-E-A-T principles.
73
-
74
- I require the following, formatted in clean markdown:
75
-
76
- 1. **Strategic Keyword Analysis:**
77
- * **Primary Target Keyword:**
78
- * **Secondary Keywords:** 2-3 closely related, high-intent keywords.
79
- * **Long-Tail Keywords & User Questions:** 5-7 specific user-searched phrases.
80
- * **Semantic/LSI Keywords:** 5-7 contextually related terms.
81
- * **Search Intent Analysis:** (Informational, Commercial, etc.)
82
-
83
- 2. **Competitive Landscape Overview (Top 3-5 Competitors):**
84
- * For each:
85
- * URL
86
- * Strengths
87
- * Weaknesses
88
- * Content angle/hook
89
-
90
- 3. **Content Gaps & Unique Value Proposition:**
91
- * Missing topics or angles
92
- * Unique insights or differentiators for *my* blog
93
-
94
- 4. **Optimized Blog Post Outline:**
95
- * **H1 Title:**
96
- * **Meta Description:** (under 160 characters)
97
- * **Full H2/H3 outline:**
98
- * **Suggested Visuals:** Where applicable
99
-
100
- 5. **User-Focused FAQ Section:** 3–5 related to '{topic}'
101
-
102
- 6. **Internal & External Linking Plan:**
103
- * **Internal:** 2-3 relevant articles with anchor suggestions
104
- * **External:** 1-2 reputable sources (.edu, .org, studies)
105
-
106
- 7. **E-E-A-T Enhancements:**
107
- * 1-2 ways to show experience, trust, and authority in the content
108
- """
109
 
110
  # Save API key to user's preferences
111
  def save_api_key(api_key):
@@ -115,10 +624,6 @@ def save_api_key(api_key):
115
  return "✅ API key saved successfully!"
116
  return "⚠️ Please enter an API key to save"
117
 
118
- # Function to clear outputs
119
- def clear_outputs():
120
- return "", gr.update(value="")
121
-
122
  # Define theme for better visual experience
123
  custom_theme = gr.themes.Soft(
124
  primary_hue="green",
@@ -141,14 +646,14 @@ with gr.Blocks(title="Fermentation SEO Assistant", theme=custom_theme, css="""
141
  overflow-y: auto;
142
  border-left: 4px solid #84cc16;
143
  padding-left: 15px;
144
- #background-color: #f8fafc;
145
  border-radius: 6px;
146
  transition: all 0.3s ease;
147
  }
148
 
149
  #seo-output-container:empty {
150
  border-left-color: #e5e7eb;
151
- #background-color: #ffffff;
152
  }
153
 
154
  .loading-spinner {
 
1
+ # Main Gradio app
2
+ with gr.Blocks(title="Fermentation SEO Assistant", theme=custom_theme, css="""
3
+ #seo-output-container {
4
+ min-height: 300px;
5
+ max-height: 800px;
6
+ overflow-y: auto;
7
+ border-left: 4px solid #84cc16;
8
+ padding-left: 15px;
9
+ background-color: #f8fafc;
10
+ border-radius: 6px;
11
+ transition: all 0.3s ease;
12
+ }
13
+
14
+ #seo-output-container:empty {
15
+ border-left-color: #e5e7eb;
16
+ background-color: #ffffff;
17
+ }
18
+
19
+ .loading-spinner {
20
+ display: inline-block;
21
+ width: 50px;
22
+ height: 50px;
23
+ border: 3px solid rgba(0,0,0,.3);
24
+ border-radius: 50%;
25
+ border-top-color: #84cc16;
26
+ animation: spin 1s ease-in-out infinite;
27
+ }
28
+
29
+ @keyframes spin {
30
+ to { transform: rotate(360deg); }
31
+ }
32
+
33
+ .tab-selected {
34
+ border-bottom: 3px solid #84cc16 !important;
35
+ font-weight: bold;
36
+ }
37
+ """) as app:
38
+ # Header
39
+ gr.Markdown("""
40
+ # 🌱 Advanced Food Blog SEO Content Planner
41
+
42
+ Generate comprehensive SEO plans for your food blog posts using Google's Gemini 1.5 Pro.
43
+ """)
44
+
45
+ # Create tabs for different sections
46
+ with gr.Tabs() as tabs:
47
+ # Main Generator Tab
48
+ with gr.TabItem("SEO Generator", id="generator_tab"):
49
+ # API Key & Configuration Section
50
+ with gr.Accordion("API Key & Settings", open=False):
51
+ with gr.Row():
52
+ api_key_input = gr.Textbox(
53
+ label="Gemini API Key",
54
+ placeholder="Enter your Google Gemini API key",
55
+ value=os.getenv("GEMINI_API_KEY", ""),
56
+ type="password"
57
+ )
58
+ save_btn = gr.Button("💾 Save Key")
59
+
60
+ with gr.Row():
61
+ temperature = gr.Slider(
62
+ minimum=0.0,
63
+ maximum=1.0,
64
+ value=0.7,
65
+ step=0.1,
66
+ label="Temperature (Creativity)",
67
+ info="Higher values = more creative, Lower values = more focused"
68
+ )
69
+ max_tokens = gr.Slider(
70
+ minimum=1000,
71
+ maximum=8000,
72
+ value=4000,
73
+ step=500,
74
+ label="Max Output Length",
75
+ info="Maximum number of tokens in the response"
76
+ )
77
+
78
+ save_btn.click(fn=save_api_key, inputs=api_key_input, outputs=gr.Textbox(label="Status"))
79
+
80
+ # Main content
81
+ with gr.Row():
82
+ with gr.Column(scale=1):
83
+ # Input section
84
+ topic_input = gr.Textbox(
85
+ label="🌶️ Your Food Topic",
86
+ placeholder="e.g., How to Make Kimchi at Home",
87
+ lines=2
88
+ )
89
+
90
+ # Template and language selectors
91
+ template_dropdown = gr.Dropdown(
92
+ choices=list(TEMPLATES.keys()),
93
+ value="fermentation",
94
+ label="Content Template",
95
+ info="Choose a specialized template for your food niche"
96
+ )
97
+
98
+ language_dropdown = gr.Dropdown(
99
+ choices=list(LANGUAGES.keys()),
100
+ value="English",
101
+ label="Target Language",
102
+ info="Optimize keywords for a specific language"
103
+ )
104
+
105
+ with gr.Row():
106
+ generate_btn = gr.Button("✨ Generate SEO Plan", variant="primary")
107
+ clear_btn = gr.Button("🔄 Clear", variant="secondary")
108
+
109
+ # Example topics for quick selection
110
+ gr.Examples(
111
+ examples=[
112
+ "Beginner's Guide to Fermenting Vegetables",
113
+ "How to Make Kombucha at Home",
114
+ "The Health Benefits of Fermented Foods",
115
+ "Wild Fermentation: Using Natural Yeasts and Bacteria",
116
+ "Troubleshooting Common Fermentation Problems"
117
+ ],
118
+ inputs=topic_input,
119
+ label="Example Topics"
120
+ )
121
+
122
+ with gr.Column(scale=2):
123
+ # Output section with a visually appealing container
124
+ with gr.Group():
125
+ output_header = gr.Markdown("### Your SEO Plan Will Appear Here")
126
+ # Add progress indicator
127
+ progress_bar = gr.Progress(track_tqdm=True)
128
+ seo_output = gr.Markdown(elem_id="seo-output-container")
129
+
130
+ # Export button
131
+ with gr.Row():
132
+ export_html_btn = gr.Button("📄 Export as HTML", variant="secondary")
133
+ export_status = gr.Textbox(label="Export Status", interactive=False)
134
+
135
+ # Button actions for main tab
136
+ generate_btn.click(
137
+ fn=generate_seo_plan,
138
+ inputs=[topic_input, api_key_input, template_dropdown, language_dropdown, temperature, max_tokens],
139
+ outputs=seo_output,
140
+ api_name="generate",
141
+ show_progress="full"
142
+ )
143
+
144
+ clear_btn.click(
145
+ fn=clear_outputs,
146
+ inputs=None,
147
+ outputs=[topic_input, seo_output]
148
+ )
149
+
150
+ export_html_btn.click(
151
+ fn=export_html,
152
+ inputs=[seo_output, topic_input],
153
+ outputs=export_status
154
+ )
155
+
156
+ # Template Manager Tab
157
+ with gr.TabItem("Template Manager", id="template_tab"):
158
+ gr.Markdown("## Create and Manage Content Templates")
159
+
160
+ with gr.Row():
161
+ with gr.Column(scale=1):
162
+ template_name_input = gr.Textbox(
163
+ label="Template Name",
164
+ placeholder="e.g., baking, vegan, desserts",
165
+ lines=1
166
+ )
167
+
168
+ template_selector = gr.Dropdown(
169
+ choices=list(TEMPLATES.keys()),
170
+ label="Load Existing Template",
171
+ info="Select a template to view or edit"
172
+ )
173
+
174
+ with gr.Column(scale=2):
175
+ template_content = gr.Textbox(
176
+ labelimport gradio as gr
177
  import google.generativeai as genai
178
  import os
179
  from dotenv import load_dotenv
180
  import time
181
+ import json
182
+ import markdown
183
+ import base64
184
+ from datetime import datetime
185
 
186
  # Load environment variables from .env file if it exists
187
  load_dotenv()
188
 
189
+ # Default templates
190
+ DEFAULT_TEMPLATES = {
191
+ "fermentation": """
192
+ Act as an elite-level SEO strategist and content creator with deep expertise in food blogs, particularly fermentation. I run a blog about fermentation, and my primary goal is to increase organic traffic, educate beginners, and establish thought leadership. My target audience is beginners curious about home fermentation and health-conscious individuals.
193
+
194
+ For the specific topic: '{topic}'
195
+
196
+ Analyze and generate a comprehensive SEO content plan designed to rank highly on Google and provide exceptional user value. Ensure all outputs adhere to E-E-A-T principles.
197
+
198
+ I require the following, formatted in clean markdown:
199
+
200
+ 1. **Strategic Keyword Analysis:**
201
+ * **Primary Target Keyword:**
202
+ * **Secondary Keywords:** 2-3 closely related, high-intent keywords.
203
+ * **Long-Tail Keywords & User Questions:** 5-7 specific user-searched phrases.
204
+ * **Semantic/LSI Keywords:** 5-7 contextually related terms.
205
+ * **Search Intent Analysis:** (Informational, Commercial, etc.)
206
+
207
+ 2. **Competitive Landscape Overview (Top 3-5 Competitors):**
208
+ * For each:
209
+ * URL
210
+ * Strengths
211
+ * Weaknesses
212
+ * Content angle/hook
213
+
214
+ 3. **Content Gaps & Unique Value Proposition:**
215
+ * Missing topics or angles
216
+ * Unique insights or differentiators for *my* blog
217
+
218
+ 4. **Optimized Blog Post Outline:**
219
+ * **H1 Title:**
220
+ * **Meta Description:** (under 160 characters)
221
+ * **Full H2/H3 outline:**
222
+ * **Suggested Visuals:** Where applicable
223
+
224
+ 5. **User-Focused FAQ Section:** 3–5 related to '{topic}'
225
+
226
+ 6. **Internal & External Linking Plan:**
227
+ * **Internal:** 2-3 relevant articles with anchor suggestions
228
+ * **External:** 1-2 reputable sources (.edu, .org, studies)
229
+
230
+ 7. **E-E-A-T Enhancements:**
231
+ * 1-2 ways to show experience, trust, and authority in the content
232
+ """,
233
+ "baking": """
234
+ Act as an elite-level SEO strategist and content creator with deep expertise in food blogs, particularly baking and pastry. I run a blog about baking, and my primary goal is to increase organic traffic, help home bakers improve their skills, and showcase unique recipes. My target audience is home bakers of all skill levels looking for reliable recipes and techniques.
235
+
236
+ For the specific topic: '{topic}'
237
+
238
+ Analyze and generate a comprehensive SEO content plan designed to rank highly on Google and provide exceptional user value. Ensure all outputs adhere to E-E-A-T principles.
239
+
240
+ I require the following, formatted in clean markdown:
241
+
242
+ 1. **Strategic Keyword Analysis:**
243
+ * **Primary Target Keyword:**
244
+ * **Secondary Keywords:** 2-3 closely related, high-intent keywords.
245
+ * **Long-Tail Keywords & User Questions:** 5-7 specific user-searched phrases.
246
+ * **Seasonal/Holiday Keywords:** 2-3 if applicable
247
+ * **Search Intent Analysis:** (Recipe-seeking, Technique-learning, Equipment-buying, etc.)
248
+
249
+ 2. **Competitive Landscape Overview (Top 3-5 Competitors):**
250
+ * For each:
251
+ * URL
252
+ * Recipe uniqueness/approach
253
+ * Visual presentation
254
+ * User engagement factors
255
+
256
+ 3. **Recipe Uniqueness & Value Proposition:**
257
+ * Distinctive ingredients or techniques
258
+ * How my recipe differs from competitors
259
+ * Troubleshooting common issues other recipes don't address
260
+
261
+ 4. **Optimized Blog Post Outline:**
262
+ * **H1 Title:**
263
+ * **Meta Description:** (under 160 characters)
264
+ * **Full H2/H3 outline** (including "Why This Recipe Works", "Ingredients", "Step-by-Step Instructions", "Storage & Make-Ahead Tips")
265
+ * **Recipe Schema Markup Elements:**
266
+ * **Required Photo/Video Content:**
267
+
268
+ 5. **User-Focused FAQ Section:** 3–5 related to '{topic}'
269
+
270
+ 6. **Internal & External Linking Plan:**
271
+ * **Internal:** 2-3 relevant recipes with anchor suggestions
272
+ * **External:** 1-2 reputable sources for techniques or ingredient information
273
+
274
+ 7. **E-E-A-T Enhancements:**
275
+ * Recipe testing notes to include
276
+ * Personal experience elements to highlight
277
+ * Scientific explanation opportunities
278
+ """,
279
+ "plant_based": """
280
+ Act as an elite-level SEO strategist and content creator with deep expertise in plant-based and vegan food blogs. I run a blog about plant-based cooking, and my primary goal is to increase organic traffic, help people transition to more plant-based eating, and provide delicious alternatives to animal products. My target audience includes vegans, vegetarians, flexitarians, and the plant-curious.
281
+
282
+ For the specific topic: '{topic}'
283
+
284
+ Analyze and generate a comprehensive SEO content plan designed to rank highly on Google and provide exceptional user value. Ensure all outputs adhere to E-E-A-T principles.
285
+
286
+ I require the following, formatted in clean markdown:
287
+
288
+ 1. **Strategic Keyword Analysis:**
289
+ * **Primary Target Keyword:**
290
+ * **Secondary Keywords:** 2-3 closely related, high-intent keywords.
291
+ * **Long-Tail Keywords & User Questions:** 5-7 specific user-searched phrases.
292
+ * **Dietary Restriction Related Keywords:** (gluten-free, nut-free, soy-free, etc.)
293
+ * **Search Intent Analysis:** (Recipe-seeking, Nutrition information, Substitution help, etc.)
294
+
295
+ 2. **Competitive Landscape Overview (Top 3-5 Competitors):**
296
+ * For each:
297
+ * URL
298
+ * Ingredient approach (whole foods vs. processed substitutes)
299
+ * Nutritional information provided
300
+ * User engagement factors
301
+
302
+ 3. **Plant-Based Value Proposition:**
303
+ * Health/nutritional benefits to highlight
304
+ * Environmental/ethical angle if applicable
305
+ * Taste/texture comparisons to non-vegan alternatives
306
+ * Accessibility of ingredients
307
+
308
+ 4. **Optimized Blog Post Outline:**
309
+ * **H1 Title:**
310
+ * **Meta Description:** (under 160 characters)
311
+ * **Full H2/H3 outline** (including "Why Choose Plant-Based", "Ingredients & Substitutions", "Step-by-Step Instructions", "Nutritional Information")
312
+ * **Recipe Schema Markup Elements:**
313
+ * **Required Photo Content:**
314
+
315
+ 5. **User-Focused FAQ Section:** 3–5 related to '{topic}' (focusing on common substitution questions)
316
+
317
+ 6. **Internal & External Linking Plan:**
318
+ * **Internal:** 2-3 relevant recipes with anchor suggestions
319
+ * **External:** 1-2 reputable sources for nutritional information
320
+
321
+ 7. **E-E-A-T Enhancements:**
322
+ * Nutritional expertise to highlight
323
+ * Personal experience with plant-based eating
324
+ * Scientific/research citations to include
325
+ """
326
+ }
327
+
328
+ # Default language settings
329
+ LANGUAGE_SETTINGS = {
330
+ "English": {
331
+ "search_engines": ["Google", "Bing", "DuckDuckGo"],
332
+ "localization_tips": "Focus on English-speaking markets (US, UK, Canada, Australia)",
333
+ "keyword_examples": ["recipe", "how to", "benefits of", "best", "easy", "homemade"]
334
+ },
335
+ "Spanish": {
336
+ "search_engines": ["Google", "Bing", "Yahoo"],
337
+ "localization_tips": "Target Spain and Latin American markets with regional variants",
338
+ "keyword_examples": ["receta", "cómo hacer", "beneficios de", "mejor", "fácil", "casero"]
339
+ },
340
+ "French": {
341
+ "search_engines": ["Google", "Qwant", "Bing"],
342
+ "localization_tips": "Focus on France, Belgium, Canada (Quebec), Switzerland",
343
+ "keyword_examples": ["recette", "comment faire", "avantages de", "meilleur", "facile", "fait maison"]
344
+ },
345
+ "German": {
346
+ "search_engines": ["Google", "Bing", "Yahoo"],
347
+ "localization_tips": "Target Germany, Austria, Switzerland with appropriate dialect considerations",
348
+ "keyword_examples": ["rezept", "wie man", "vorteile von", "beste", "einfach", "hausgemacht"]
349
+ }
350
+ }
351
+
352
+ # Function to save templates to file
353
+ def save_templates():
354
+ with open("templates.json", "w") as f:
355
+ json.dump(DEFAULT_TEMPLATES, f, indent=4)
356
+
357
+ with open("languages.json", "w") as f:
358
+ json.dump(LANGUAGE_SETTINGS, f, indent=4)
359
+
360
+ # Load templates if they exist, otherwise use defaults
361
+ def load_templates():
362
+ templates = DEFAULT_TEMPLATES.copy()
363
+ languages = LANGUAGE_SETTINGS.copy()
364
+
365
+ try:
366
+ if os.path.exists("templates.json"):
367
+ with open("templates.json", "r") as f:
368
+ templates = json.load(f)
369
+ except Exception as e:
370
+ print(f"Error loading templates: {e}")
371
+
372
+ try:
373
+ if os.path.exists("languages.json"):
374
+ with open("languages.json", "r") as f:
375
+ languages = json.load(f)
376
+ except Exception as e:
377
+ print(f"Error loading languages: {e}")
378
+
379
+ return templates, languages
380
+
381
+ # Initialize templates
382
+ TEMPLATES, LANGUAGES = load_templates()
383
+
384
+ # Generate HTML for export
385
+ def generate_html_export(content, title):
386
+ html_template = f"""<!DOCTYPE html>
387
+ <html lang="en">
388
+ <head>
389
+ <meta charset="UTF-8">
390
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
391
+ <title>{title} - SEO Plan</title>
392
+ <style>
393
+ body {{
394
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
395
+ line-height: 1.6;
396
+ color: #333;
397
+ max-width: 900px;
398
+ margin: 0 auto;
399
+ padding: 20px;
400
+ background-color: #f9f9f9;
401
+ }}
402
+ header {{
403
+ background-color: #84cc16;
404
+ color: white;
405
+ padding: 20px;
406
+ text-align: center;
407
+ border-radius: 8px;
408
+ margin-bottom: 30px;
409
+ }}
410
+ h1 {{
411
+ margin: 0;
412
+ font-size: 2em;
413
+ }}
414
+ h2 {{
415
+ border-bottom: 2px solid #84cc16;
416
+ padding-bottom: 10px;
417
+ color: #2f855a;
418
+ }}
419
+ h3 {{
420
+ color: #3f6212;
421
+ }}
422
+ .content {{
423
+ background-color: white;
424
+ padding: 25px;
425
+ border-radius: 8px;
426
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
427
+ }}
428
+ footer {{
429
+ margin-top: 30px;
430
+ text-align: center;
431
+ color: #666;
432
+ font-size: 0.9em;
433
+ }}
434
+ ul {{
435
+ margin-left: 20px;
436
+ }}
437
+ code {{
438
+ background-color: #f0f0f0;
439
+ padding: 2px 5px;
440
+ border-radius: 3px;
441
+ font-family: monospace;
442
+ }}
443
+ blockquote {{
444
+ border-left: 4px solid #84cc16;
445
+ margin-left: 0;
446
+ padding-left: 15px;
447
+ color: #555;
448
+ }}
449
+ li {{
450
+ margin-bottom: 10px;
451
+ }}
452
+ </style>
453
+ </head>
454
+ <body>
455
+ <header>
456
+ <h1>{title} - SEO Plan</h1>
457
+ <p>Generated on {datetime.now().strftime("%B %d, %Y at %H:%M")}</p>
458
+ </header>
459
+ <div class="content">
460
+ {markdown.markdown(content)}
461
+ </div>
462
+ <footer>
463
+ <p>Generated using Fermentation SEO Assistant</p>
464
+ </footer>
465
+ </body>
466
+ </html>
467
+ """
468
+ return html_template
469
+
470
+ # Export the SEO plan as HTML and create download link
471
+ def export_html(content, topic):
472
+ if not content or content.startswith("⚠️") or content.startswith("🔄"):
473
+ return "Please generate an SEO plan first."
474
+
475
+ title = topic.strip().title()
476
+ html_content = generate_html_export(content, title)
477
+
478
+ # Create a safe filename
479
+ safe_filename = "".join([c if c.isalnum() or c in " -_" else "_" for c in title])
480
+ safe_filename = safe_filename.replace(" ", "_") + "_SEO_Plan.html"
481
+
482
+ # Write to file
483
+ with open(safe_filename, "w", encoding="utf-8") as f:
484
+ f.write(html_content)
485
+
486
+ return f"✅ HTML export saved as '{safe_filename}'"
487
+
488
+ # Function to update template
489
+ def save_custom_template(template_name, template_content):
490
+ if not template_name or not template_content:
491
+ return "⚠️ Please provide both a template name and content."
492
+
493
+ # Add to templates
494
+ TEMPLATES[template_name.lower()] = template_content
495
+
496
+ # Save to file
497
+ save_templates()
498
+
499
+ return f"✅ Template '{template_name}' saved successfully!"
500
+
501
+ # Function to update language settings
502
+ def save_language_settings(language_name, search_engines, localization_tips, keyword_examples):
503
+ if not language_name:
504
+ return "⚠️ Please provide a language name."
505
+
506
+ # Process keyword examples
507
+ if isinstance(keyword_examples, str):
508
+ keyword_list = [k.strip() for k in keyword_examples.split(",")]
509
+ else:
510
+ keyword_list = keyword_examples
511
+
512
+ # Add to languages
513
+ LANGUAGES[language_name] = {
514
+ "search_engines": search_engines.split(",") if isinstance(search_engines, str) else search_engines,
515
+ "localization_tips": localization_tips,
516
+ "keyword_examples": keyword_list
517
+ }
518
+
519
+ # Save to file
520
+ save_templates()
521
+
522
+ return f"✅ Language settings for '{language_name}' saved successfully!"
523
+
524
+ # Function to load template content
525
+ def load_template_content(template_name):
526
+ if template_name in TEMPLATES:
527
+ return TEMPLATES[template_name]
528
+ return ""
529
+
530
+ # Function to build prompt with language optimization
531
+ def build_prompt(topic, template_key="fermentation", language="English"):
532
+ # Get base template
533
+ if template_key in TEMPLATES:
534
+ template = TEMPLATES[template_key]
535
+ else:
536
+ template = TEMPLATES["fermentation"] # Default to fermentation
537
+
538
+ # Get language settings
539
+ lang_settings = LANGUAGES.get(language, LANGUAGES["English"])
540
+
541
+ # Add language-specific instructions
542
+ language_instructions = f"""
543
+ Additionally, optimize the SEO plan for {language} language users with these considerations:
544
+
545
+ 1. **Target Search Engines:** {', '.join(lang_settings['search_engines'])}
546
+ 2. **Localization Tips:** {lang_settings['localization_tips']}
547
+ 3. **Keyword Patterns:** Consider these {language} keyword patterns: {', '.join(lang_settings['keyword_examples'])}
548
+ 4. **Language-Specific SEO:** Adjust title length, meta description, and keyword density for {language} search engines
549
+ """
550
+
551
+ # If not English, add language-specific instructions
552
+ if language != "English":
553
+ full_template = template + language_instructions
554
+ else:
555
+ full_template = template
556
+
557
+ # Format with the topic
558
+ return full_template.format(topic=topic)
559
+
560
  # Function to generate SEO plan with proper error handling
561
+ def generate_seo_plan(topic, api_key, template_key="fermentation", language="English", temperature=0.7, max_tokens=4000):
562
  # Input validation
563
  if not topic.strip():
564
  return "⚠️ Please enter a fermentation topic to generate an SEO plan."
 
584
  )
585
 
586
  # Update status
587
+ yield f"🧠 Building SEO prompt for your {template_key} topic in {language}..."
588
 
589
+ # Build the prompt with template and language
590
+ prompt = build_prompt(topic, template_key, language)
591
 
592
  # Update status
593
  yield "🚀 Generating SEO plan with Gemini 1.5 Pro..."
 
612
  else:
613
  yield f"⚠️ Error: {error_message}"
614
 
615
+ # Function to clear outputs
616
+ def clear_outputs():
617
+ return "", gr.update(value="")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618
 
619
  # Save API key to user's preferences
620
  def save_api_key(api_key):
 
624
  return "✅ API key saved successfully!"
625
  return "⚠️ Please enter an API key to save"
626
 
 
 
 
 
627
  # Define theme for better visual experience
628
  custom_theme = gr.themes.Soft(
629
  primary_hue="green",
 
646
  overflow-y: auto;
647
  border-left: 4px solid #84cc16;
648
  padding-left: 15px;
649
+ background-color: #f8fafc;
650
  border-radius: 6px;
651
  transition: all 0.3s ease;
652
  }
653
 
654
  #seo-output-container:empty {
655
  border-left-color: #e5e7eb;
656
+ background-color: #ffffff;
657
  }
658
 
659
  .loading-spinner {