Liori25 commited on
Commit
0a1f097
·
verified ·
1 Parent(s): 9a1f40d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +11 -135
app.py CHANGED
@@ -47,14 +47,13 @@ logo_b64 = image_to_base64("logo.jpg")
47
  profile_b64 = image_to_base64("232px-Tv_the_muppet_show_bein_green.jpg")
48
 
49
  # ==========================================
50
- # 3. BACKEND LOGIC (UPDATED FOR 3 SEPARATE OUTPUTS)
51
  # ==========================================
52
  def get_embedding_via_api(text):
53
  if not client: raise ValueError("HF_TOKEN missing")
54
  response = client.feature_extraction(text, model=API_MODEL)
55
  return np.array(response)
56
 
57
- # UPDATED: Returns a LIST of 3 strings instead of one big string
58
  def find_similar_recipes_list(query_text):
59
  if stored_embeddings is None: return ["Database error."] * 3
60
  query_vec = get_embedding_via_api("Represent this recipe for retrieving similar dishes: " + query_text)
@@ -67,15 +66,12 @@ def find_similar_recipes_list(query_text):
67
  for idx in top_indices:
68
  row = df_recipes.iloc[idx]
69
  title = row['Title']
70
- desc = str(row['Raw_Output'])[:200] + "..." # Truncate for UI card
71
-
72
- # Markdown format for individual card
73
  card_content = f"### 🏆 {title}\n\n{desc}"
74
  results_list.append(card_content)
75
 
76
- # Ensure we always return exactly 3 items (pad if fewer matches found)
77
  while len(results_list) < 3:
78
- results_list.append("No match found.")
79
 
80
  return results_list
81
 
@@ -87,7 +83,6 @@ def format_recipe(json_data):
87
  text = f"🍽️ {title}\n\n🛒 INGREDIENTS:\n{ing}\n\n🍳 INSTRUCTIONS:\n{inst}"
88
  return text, f"{title} {ing} {inst}"
89
 
90
- # UPDATED: Returns 4 outputs (1 text + 3 similar cards)
91
  def magic_pipeline(image_path):
92
  if not hf_token: return "Error: HF_TOKEN missing", "", "", ""
93
  try:
@@ -162,8 +157,6 @@ body, .gradio-container { background-color: #f0f2f5; }
162
  transition: all 0.2s ease;
163
  }
164
  .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
165
-
166
- /* Selected State */
167
  .nav-btn.selected {
168
  background-color: #e7f3ff !important;
169
  color: #1877f2 !important;
@@ -180,14 +173,14 @@ body, .gradio-container { background-color: #f0f2f5; }
180
  margin-bottom: 20px;
181
  }
182
 
183
- /* Similar Recipe Cards (Special Look) */
184
  .sim-card {
185
  background: #fff;
186
  border: 1px solid #eee;
187
  border-radius: 8px;
188
  padding: 15px;
189
  height: 100%;
190
- border-top: 4px solid #1877f2; /* Blue accent top */
191
  }
192
 
193
  /* Right Side Trending Box */
@@ -200,6 +193,11 @@ body, .gradio-container { background-color: #f0f2f5; }
200
  transition: background 0.2s;
201
  }
202
  .trend-box:hover { background: #f0f2f5; cursor: pointer; }
 
 
 
 
 
203
  """
204
 
205
  # ==========================================
@@ -208,126 +206,4 @@ body, .gradio-container { background-color: #f0f2f5; }
208
  with gr.Blocks(title="Legacy Kitchen") as demo:
209
 
210
  # --- HEADER ---
211
- gr.HTML(f"""
212
- <div class="custom-header">
213
- <div class="logo-area">
214
- <img src="data:image/jpeg;base64,{logo_b64}" class="logo-img">
215
- <div class="text-area">
216
- <span class="app-name">Legacy Kitchen</span>
217
- <span class="app-slogan">Turning Handwritten Notes into a Digital Cookbook.</span>
218
- </div>
219
- </div>
220
- <div style="color: #65676b; font-weight: 600;">v3.0</div>
221
- </div>
222
- """)
223
-
224
- with gr.Row():
225
-
226
- # --- LEFT SIDEBAR ---
227
- with gr.Column(scale=1, min_width=200):
228
- gr.HTML(f"""
229
- <div style="display:flex; align-items:center; padding: 10px 10px 5px 10px;">
230
- <img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; margin-right:10px; object-fit:cover;">
231
- <b style="font-size: 16px;">My Profile</b>
232
- </div>
233
- """)
234
- gr.HTML("<hr style='border: 0; border-top: 1px solid #e4e6eb; margin: 10px 0 20px 0;'>")
235
-
236
- nav_digital = gr.Button("✨ AI Digitizer", elem_classes=["nav-btn", "selected"])
237
- nav_feed = gr.Button("📰 News Feed", elem_classes=["nav-btn"])
238
- nav_about = gr.Button("ℹ️ About", elem_classes=["nav-btn"])
239
-
240
- # --- CENTER CONTENT ---
241
- with gr.Column(scale=3):
242
-
243
- # === VIEW 1: AI DIGITALIZER (Default) ===
244
- with gr.Group(visible=True) as digitalizer_view:
245
-
246
- # SECTION 1: UPLOAD & TEXT (Side by Side)
247
- with gr.Row():
248
- # Left: Upload & Button
249
- with gr.Column(scale=1):
250
- gr.Markdown("### 1. Upload Note", elem_classes=["content-card"])
251
- with gr.Group(elem_classes=["content-card"]):
252
- input_img = gr.Image(type="filepath", label="Upload", height=300)
253
- magic_btn = gr.Button("✨ Convert to Digital", variant="primary", size="lg")
254
-
255
- # Right: Digitized Text Result
256
- with gr.Column(scale=1):
257
- gr.Markdown("### 2. Digital Text", elem_classes=["content-card"])
258
- with gr.Group(elem_classes=["content-card"]):
259
- out_text = gr.Textbox(label="Result", lines=12, interactive=False, show_label=False)
260
-
261
- # SECTION 2: SIMILAR RECIPES (Below, 3 distinct cards)
262
- gr.Markdown("### 3. Similar Recipes from Database")
263
- with gr.Row():
264
- with gr.Column(elem_classes=["sim-card"]):
265
- sim1 = gr.Markdown("Match #1 will appear here...")
266
- with gr.Column(elem_classes=["sim-card"]):
267
- sim2 = gr.Markdown("Match #2 will appear here...")
268
- with gr.Column(elem_classes=["sim-card"]):
269
- sim3 = gr.Markdown("Match #3 will appear here...")
270
-
271
- # UPDATED CLICK EVENT: Returns 4 outputs
272
- magic_btn.click(magic_pipeline, input_img, [out_text, sim1, sim2, sim3])
273
-
274
- # === VIEW 2: FEED (Hidden) ===
275
- with gr.Group(visible=False) as feed_view:
276
- with gr.Group(elem_classes=["content-card"]):
277
- with gr.Row():
278
- gr.HTML(f'<img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; object-fit:cover;">')
279
- gr.Textbox(placeholder=f"What recipe are you cooking today?", show_label=False, container=False, scale=10)
280
-
281
- if not df_recipes.empty:
282
- feed_samples = df_recipes.sample(10)
283
- for index, row in feed_samples.iterrows():
284
- user_name = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
285
- emoji = random.choice(["🥘", "🥗", "🍰", "🌮"])
286
-
287
- with gr.Group(elem_classes=["content-card"]):
288
- gr.HTML(f"""
289
- <div style="display:flex; gap:10px; align-items:center; margin-bottom:12px;">
290
- <div style="width:40px; height:40px; background:#e4e6eb; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:20px;">{emoji}</div>
291
- <div><b>{user_name}</b><br><span style="color:gray; font-size:12px;">2h · 🌍 Public</span></div>
292
- </div>
293
- """)
294
- gr.Markdown(f"### {row['Title']}")
295
- gr.Markdown(f"{str(row['Raw_Output'])[:250]}...")
296
- with gr.Row():
297
- gr.Button("👍 Like", size="sm", variant="secondary")
298
- gr.Button("💬 Comment", size="sm", variant="secondary")
299
- gr.Button("↗️ Share", size="sm", variant="secondary")
300
- else:
301
- gr.Markdown("⚠️ Database is empty.")
302
-
303
- # === VIEW 3: ABOUT (Hidden) ===
304
- with gr.Group(visible=False) as about_view:
305
- with gr.Group(elem_classes=["content-card"]):
306
- gr.Markdown("# ℹ️ About Legacy Kitchen\n\n**Turning Handwritten Notes into a Digital Cookbook.**")
307
-
308
- # --- RIGHT COLUMN (Trending) ---
309
- with gr.Column(scale=1, min_width=200):
310
- gr.Markdown("### Trending Recipes")
311
- def trend_box(title, likes):
312
- return f"<div class='trend-box'><b>{title}</b><br><span style='color:gray; font-size:12px;'>{likes} likes</span></div>"
313
- gr.HTML(trend_box("🍜 Ramen Hack", "12k") + trend_box("🍪 Best Cookies", "8k") + trend_box("🍰 Cheese Cake", "15k") + trend_box("🍪 Nana's Tahini Cookies", "9k"))
314
-
315
- # ==========================================
316
- # 6. JAVASCRIPT LOGIC
317
- # ==========================================
318
- def go_digi():
319
- return (gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(elem_classes=["nav-btn", "selected"]), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn"]))
320
-
321
- def go_feed():
322
- return (gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn", "selected"]), gr.update(elem_classes=["nav-btn"]))
323
-
324
- def go_about():
325
- return (gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn"]), gr.update(elem_classes=["nav-btn", "selected"]))
326
-
327
- outputs_ui = [digitalizer_view, feed_view, about_view, nav_digital, nav_feed, nav_about]
328
- nav_digital.click(go_digi, None, outputs_ui)
329
- nav_feed.click(go_feed, None, outputs_ui)
330
- nav_about.click(go_about, None, outputs_ui)
331
-
332
- if __name__ == "__main__":
333
- demo.launch(theme=theme, css=modern_css)
 
47
  profile_b64 = image_to_base64("232px-Tv_the_muppet_show_bein_green.jpg")
48
 
49
  # ==========================================
50
+ # 3. BACKEND LOGIC
51
  # ==========================================
52
  def get_embedding_via_api(text):
53
  if not client: raise ValueError("HF_TOKEN missing")
54
  response = client.feature_extraction(text, model=API_MODEL)
55
  return np.array(response)
56
 
 
57
  def find_similar_recipes_list(query_text):
58
  if stored_embeddings is None: return ["Database error."] * 3
59
  query_vec = get_embedding_via_api("Represent this recipe for retrieving similar dishes: " + query_text)
 
66
  for idx in top_indices:
67
  row = df_recipes.iloc[idx]
68
  title = row['Title']
69
+ desc = str(row['Raw_Output'])[:200] + "..."
 
 
70
  card_content = f"### 🏆 {title}\n\n{desc}"
71
  results_list.append(card_content)
72
 
 
73
  while len(results_list) < 3:
74
+ results_list.append("")
75
 
76
  return results_list
77
 
 
83
  text = f"🍽️ {title}\n\n🛒 INGREDIENTS:\n{ing}\n\n🍳 INSTRUCTIONS:\n{inst}"
84
  return text, f"{title} {ing} {inst}"
85
 
 
86
  def magic_pipeline(image_path):
87
  if not hf_token: return "Error: HF_TOKEN missing", "", "", ""
88
  try:
 
157
  transition: all 0.2s ease;
158
  }
159
  .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
 
 
160
  .nav-btn.selected {
161
  background-color: #e7f3ff !important;
162
  color: #1877f2 !important;
 
173
  margin-bottom: 20px;
174
  }
175
 
176
+ /* Similar Recipe Cards */
177
  .sim-card {
178
  background: #fff;
179
  border: 1px solid #eee;
180
  border-radius: 8px;
181
  padding: 15px;
182
  height: 100%;
183
+ border-top: 4px solid #1877f2;
184
  }
185
 
186
  /* Right Side Trending Box */
 
193
  transition: background 0.2s;
194
  }
195
  .trend-box:hover { background: #f0f2f5; cursor: pointer; }
196
+
197
+ /* FIX: Force Gap in the Upload Row */
198
+ .gap-fix {
199
+ gap: 25px !important;
200
+ }
201
  """
202
 
203
  # ==========================================
 
206
  with gr.Blocks(title="Legacy Kitchen") as demo:
207
 
208
  # --- HEADER ---
209
+ gr.