Liori25 commited on
Commit
b9b8f74
·
verified ·
1 Parent(s): 72ab19b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -270
app.py CHANGED
@@ -66,10 +66,10 @@ def find_similar_recipes_list(query_text):
66
  for idx in top_indices:
67
  row = df_recipes.iloc[idx]
68
  title = row['Title']
69
- # INCREASED TEXT LENGTH to 600 chars to demonstrate scrolling
70
- desc = str(row['Raw_Output'])[:600] + "..."
71
 
72
- # Wrapped description in a div class 'sim-scroll' for CSS styling
73
  card_content = f"### 🏆 {title}\n\n<div class='sim-scroll'>{desc}</div>"
74
  results_list.append(card_content)
75
 
@@ -86,8 +86,11 @@ def format_recipe(json_data):
86
  text = f"🍽️ {title}\n\n🛒 INGREDIENTS:\n{ing}\n\n🍳 INSTRUCTIONS:\n{inst}"
87
  return text, f"{title} {ing} {inst}"
88
 
89
- def magic_pipeline(image_path):
90
- if not hf_token: return "Error: HF_TOKEN missing", "", "", ""
 
 
 
91
  try:
92
  os.environ["HF_TOKEN"] = hf_token
93
  digitizer = RecipeDigitalizerPipeline()
@@ -98,11 +101,24 @@ def magic_pipeline(image_path):
98
  sim_list = find_similar_recipes_list(query)
99
  else:
100
  sim_list = ["No query generated.", "", ""]
101
-
102
- return readable, sim_list[0], sim_list[1], sim_list[2]
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  except Exception as e:
105
- return f"Error: {e}", "Error", "Error", "Error"
106
 
107
  # ==========================================
108
  # 4. MODERN UI THEME & CSS
@@ -132,265 +148,4 @@ body, .gradio-container { background-color: #f0f2f5; }
132
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
133
  }
134
 
135
- .logo-area { display: flex; align-items: center; gap: 20px; }
136
- .logo-img { height: 120px; width: 120px; border-radius: 12px; object-fit: cover; border: 1px solid #ddd; }
137
- .text-area { display: flex; flex-direction: column; }
138
- .app-name {
139
- font-weight: 800;
140
- font-size: 32px;
141
- background: -webkit-linear-gradient(45deg, #1877f2, #6b21a8);
142
- -webkit-background-clip: text;
143
- -webkit-text-fill-color: transparent;
144
- line-height: 1.2;
145
- }
146
- .app-slogan { font-size: 16px; color: #65676b; font-weight: 500; }
147
-
148
- /* Sidebar Navigation */
149
- .nav-btn {
150
- text-align: left !important;
151
- justify-content: flex-start !important;
152
- background: transparent !important;
153
- border: none !important;
154
- box-shadow: none !important;
155
- color: #65676b !important;
156
- font-weight: 600 !important;
157
- font-size: 16px !important;
158
- padding: 12px 16px !important;
159
- border-radius: 10px !important;
160
- transition: all 0.2s ease;
161
- }
162
- .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
163
- .nav-btn.selected {
164
- background-color: #e7f3ff !important;
165
- color: #1877f2 !important;
166
- border-left: 4px solid #1877f2 !important;
167
- }
168
-
169
- /* General Cards */
170
- .content-card {
171
- background: white;
172
- border-radius: 12px;
173
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
174
- border: 1px solid #ddd;
175
- padding: 20px;
176
- margin-bottom: 20px;
177
- height: 100%;
178
- overflow: visible !important; /* Allow pop-ups to be seen */
179
- }
180
-
181
- /* Similar Recipe Cards */
182
- .sim-card {
183
- background: #fff;
184
- border: 1px solid #eee;
185
- border-radius: 8px;
186
- padding: 15px;
187
- height: 100%;
188
- border-top: 4px solid #1877f2;
189
- display: flex;
190
- flex-direction: column;
191
- justify-content: space-between;
192
- }
193
-
194
- /* SCROLLABLE TEXT AREA for Similar Recipes */
195
- .sim-scroll {
196
- height: 150px; /* Fixed height */
197
- overflow-y: auto; /* Enable Vertical Scrolling */
198
- margin-bottom: 10px;
199
- padding-right: 5px; /* Space for scrollbar */
200
- font-size: 14px;
201
- color: #4b4f56;
202
- }
203
-
204
- /* Right Side Trending Box */
205
- .trend-box {
206
- background:white;
207
- padding:10px;
208
- border-radius:8px;
209
- margin-bottom:10px;
210
- box-shadow:0 1px 2px rgba(0,0,0,0.1);
211
- transition: background 0.2s;
212
- }
213
- .trend-box:hover { background: #f0f2f5; cursor: pointer; }
214
-
215
- /* Gap Fix */
216
- .gap-fix {
217
- gap: 25px !important;
218
- }
219
-
220
- /* --- IMAGE POP HOVER EFFECT --- */
221
- /* Targets the buttons inside the Examples component */
222
- button.gallery-item {
223
- transition: transform 0.2s ease, box-shadow 0.2s ease !important;
224
- z-index: 1;
225
- }
226
- button.gallery-item:hover {
227
- transform: scale(2.5) !important; /* Make it BIG */
228
- z-index: 1000 !important; /* Put it on top of everything */
229
- box-shadow: 0 10px 25px rgba(0,0,0,0.3) !important;
230
- border: 2px solid white !important;
231
- border-radius: 8px !important;
232
- }
233
- """
234
-
235
- # ==========================================
236
- # 5. LAYOUT CONSTRUCTION
237
- # ==========================================
238
- with gr.Blocks(title="Legacy Kitchen") as demo:
239
-
240
- # --- HEADER ---
241
- gr.HTML(f"""
242
- <div class="custom-header">
243
- <div class="logo-area">
244
- <img src="data:image/jpeg;base64,{logo_b64}" class="logo-img">
245
- <div class="text-area">
246
- <span class="app-name">Legacy Kitchen</span>
247
- <span class="app-slogan">Turning Handwritten Notes into a Digital Cookbook.</span>
248
- </div>
249
- </div>
250
- <div style="color: #65676b; font-weight: 600;">v3.4</div>
251
- </div>
252
- """)
253
-
254
- with gr.Row():
255
-
256
- # --- LEFT SIDEBAR ---
257
- with gr.Column(scale=1, min_width=200):
258
- gr.HTML(f"""
259
- <div style="display:flex; align-items:center; padding: 10px 10px 5px 10px;">
260
- <img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; margin-right:10px; object-fit:cover;">
261
- <b style="font-size: 16px;">My Profile</b>
262
- </div>
263
- """)
264
- gr.HTML("<hr style='border: 0; border-top: 1px solid #e4e6eb; margin: 10px 0 20px 0;'>")
265
-
266
- nav_digital = gr.Button("✨ AI Digitizer", elem_classes=["nav-btn", "selected"])
267
- nav_feed = gr.Button("📰 News Feed", elem_classes=["nav-btn"])
268
- nav_about = gr.Button("ℹ️ About", elem_classes=["nav-btn"])
269
-
270
- # --- CENTER CONTENT ---
271
- with gr.Column(scale=3):
272
-
273
- # === VIEW 1: AI DIGITALIZER ===
274
- with gr.Group(visible=True) as digitalizer_view:
275
-
276
- # SECTION 1: UPLOAD & TEXT
277
- with gr.Row(elem_classes=["gap-fix"]):
278
-
279
- # Left: Upload & Examples
280
- with gr.Column(scale=1):
281
- with gr.Group(elem_classes=["content-card"]):
282
- input_img = gr.Image(type="filepath", label="Upload", height=300)
283
- magic_btn = gr.Button("✨ Convert to Digital", variant="primary", size="lg")
284
-
285
- # Examples Component (Hover effect added in CSS)
286
- gr.Examples(
287
- examples=[
288
- ["quick_tries_images/applecrisp.jpg"],
289
- ["quick_tries_images/meatballs recipe.jpg"],
290
- ["quick_tries_images/tofu.jfif"]
291
- ],
292
- inputs=input_img,
293
- label="Or try these examples:",
294
- cache_examples=False
295
- )
296
-
297
- # Right: Text
298
- with gr.Column(scale=1):
299
- with gr.Group(elem_classes=["content-card"]):
300
- out_text = gr.Textbox(
301
- label="Result",
302
- value="Here your digitalized recipe will be presented",
303
- lines=20,
304
- interactive=False,
305
- show_label=False
306
- )
307
-
308
- # Spacer
309
- gr.HTML("<div style='height: 35px;'></div>")
310
-
311
- # SECTION 2: SIMILAR RECIPES
312
- gr.Markdown("### 3. Similar Recipes from Database")
313
-
314
- with gr.Row():
315
- # CARD 1
316
- with gr.Column(elem_classes=["sim-card"]):
317
- sim1 = gr.Markdown("Once you will upload your scanned recipe, we will share similar recipes!")
318
- with gr.Row():
319
- gr.Button("👍 Like", size="sm", variant="secondary")
320
- gr.Button("↗️ Share", size="sm", variant="secondary")
321
-
322
- # CARD 2
323
- with gr.Column(elem_classes=["sim-card"]):
324
- sim2 = gr.Markdown("")
325
- with gr.Row():
326
- gr.Button("👍 Like", size="sm", variant="secondary")
327
- gr.Button("↗️ Share", size="sm", variant="secondary")
328
-
329
- # CARD 3
330
- with gr.Column(elem_classes=["sim-card"]):
331
- sim3 = gr.Markdown("")
332
- with gr.Row():
333
- gr.Button("👍 Like", size="sm", variant="secondary")
334
- gr.Button("↗️ Share", size="sm", variant="secondary")
335
-
336
- magic_btn.click(magic_pipeline, input_img, [out_text, sim1, sim2, sim3])
337
-
338
- # === VIEW 2: FEED ===
339
- with gr.Group(visible=False) as feed_view:
340
- with gr.Group(elem_classes=["content-card"]):
341
- with gr.Row():
342
- gr.HTML(f'<img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; object-fit:cover;">')
343
- gr.Textbox(placeholder=f"What recipe are you cooking today?", show_label=False, container=False, scale=10)
344
-
345
- if not df_recipes.empty:
346
- feed_samples = df_recipes.sample(10)
347
- for index, row in feed_samples.iterrows():
348
- user_name = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
349
- emoji = random.choice(["🥘", "🥗", "🍰", "🌮"])
350
- with gr.Group(elem_classes=["content-card"]):
351
- gr.HTML(f"""
352
- <div style="display:flex; gap:10px; align-items:center; margin-bottom:12px;">
353
- <div style="width:40px; height:40px; background:#e4e6eb; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:20px;">{emoji}</div>
354
- <div><b>{user_name}</b><br><span style="color:gray; font-size:12px;">2h · 🌍 Public</span></div>
355
- </div>
356
- """)
357
- gr.Markdown(f"### {row['Title']}")
358
- gr.Markdown(f"{str(row['Raw_Output'])[:250]}...")
359
- with gr.Row():
360
- gr.Button("👍 Like", size="sm", variant="secondary")
361
- gr.Button("💬 Comment", size="sm", variant="secondary")
362
- gr.Button("↗️ Share", size="sm", variant="secondary")
363
- else:
364
- gr.Markdown("⚠️ Database is empty.")
365
-
366
- # === VIEW 3: ABOUT ===
367
- with gr.Group(visible=False) as about_view:
368
- with gr.Group(elem_classes=["content-card"]):
369
- gr.Markdown("# ℹ️ About Legacy Kitchen\n\n**Turning Handwritten Notes into a Digital Cookbook.**")
370
-
371
- # --- RIGHT COLUMN ---
372
- with gr.Column(scale=1, min_width=200):
373
- gr.Markdown("### Trending Recipes")
374
- def trend_box(title, likes):
375
- return f"<div class='trend-box'><b>{title}</b><br><span style='color:gray; font-size:12px;'>{likes} likes</span></div>"
376
- gr.HTML(trend_box("🍜 Ramen Hack", "12k") + trend_box("🍪 Best Cookies", "8k") + trend_box("🍰 Cheese Cake", "15k") + trend_box("🍪 Nana's Tahini Cookies", "9k"))
377
-
378
- # ==========================================
379
- # 6. JAVASCRIPT LOGIC
380
- # ==========================================
381
- def go_digi():
382
- 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"]))
383
-
384
- def go_feed():
385
- 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"]))
386
-
387
- def go_about():
388
- 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"]))
389
-
390
- outputs_ui = [digitalizer_view, feed_view, about_view, nav_digital, nav_feed, nav_about]
391
- nav_digital.click(go_digi, None, outputs_ui)
392
- nav_feed.click(go_feed, None, outputs_ui)
393
- nav_about.click(go_about, None, outputs_ui)
394
-
395
- if __name__ == "__main__":
396
- demo.launch(theme=theme, css=modern_css)
 
66
  for idx in top_indices:
67
  row = df_recipes.iloc[idx]
68
  title = row['Title']
69
+ # Text description for the card
70
+ desc = str(row['Raw_Output'])[:800] + "..." # Increased text limit
71
 
72
+ # Wrapped in sim-scroll for the 400px height
73
  card_content = f"### 🏆 {title}\n\n<div class='sim-scroll'>{desc}</div>"
74
  results_list.append(card_content)
75
 
 
86
  text = f"🍽️ {title}\n\n🛒 INGREDIENTS:\n{ing}\n\n🍳 INSTRUCTIONS:\n{inst}"
87
  return text, f"{title} {ing} {inst}"
88
 
89
+ # --- NEW: PIPELINE WRAPPER TO HANDLE VISIBILITY UPDATES ---
90
+ def ui_update_pipeline(image_path):
91
+ if not hf_token:
92
+ return "Error: HF_TOKEN missing", "", gr.update(), gr.update(), "", gr.update(), ""
93
+
94
  try:
95
  os.environ["HF_TOKEN"] = hf_token
96
  digitizer = RecipeDigitalizerPipeline()
 
101
  sim_list = find_similar_recipes_list(query)
102
  else:
103
  sim_list = ["No query generated.", "", ""]
104
+
105
+ # RETURNS:
106
+ # 1. Digitized Text
107
+ # 2. Sim Card 1 Text
108
+ # 3. Sim Card 1 Buttons (Visible)
109
+ # 4. Sim Card 2 Container (Visible)
110
+ # 5. Sim Card 2 Text
111
+ # 6. Sim Card 3 Container (Visible)
112
+ # 7. Sim Card 3 Text
113
+ return (
114
+ readable,
115
+ sim_list[0], gr.update(visible=True), # Card 1
116
+ gr.update(visible=True), sim_list[1], # Card 2
117
+ gr.update(visible=True), sim_list[2] # Card 3
118
+ )
119
 
120
  except Exception as e:
121
+ return f"Error: {e}", "Error", gr.update(), gr.update(), "", gr.update(), ""
122
 
123
  # ==========================================
124
  # 4. MODERN UI THEME & CSS
 
148
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
149
  }
150
 
151
+ .logo-area { display: flex; align-items: center; gap: