Liori25 commited on
Commit
a67040e
·
verified ·
1 Parent(s): 0d5f120

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -9
app.py CHANGED
@@ -39,10 +39,12 @@ except Exception as e:
39
  # ==========================================
40
  def image_to_base64(image_path):
41
  if not os.path.exists(image_path):
 
42
  return "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
43
  with open(image_path, "rb") as img_file:
44
  return base64.b64encode(img_file.read()).decode('utf-8')
45
 
 
46
  logo_b64 = image_to_base64("logo.jpg")
47
  profile_b64 = image_to_base64("232px-Tv_the_muppet_show_bein_green.jpg")
48
 
@@ -101,8 +103,10 @@ theme = gr.themes.Soft(
101
 
102
  modern_css = """
103
  body, .gradio-container { background-color: #f0f2f5; }
 
 
104
  .custom-header {
105
- background: rgba(255, 255, 255, 0.9);
106
  backdrop-filter: blur(10px);
107
  border-bottom: 1px solid #e4e6eb;
108
  padding: 10px 20px;
@@ -114,9 +118,18 @@ body, .gradio-container { background-color: #f0f2f5; }
114
  z-index: 1000;
115
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
116
  }
 
117
  .logo-area { display: flex; align-items: center; gap: 15px; }
118
- .logo-img { height: 40px; width: 40px; border-radius: 50%; }
119
- .app-name { font-weight: 800; font-size: 24px; background: -webkit-linear-gradient(45deg, #1877f2, #6b21a8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
 
 
 
 
 
 
 
 
120
  .nav-btn {
121
  text-align: left !important;
122
  justify-content: flex-start !important;
@@ -132,6 +145,8 @@ body, .gradio-container { background-color: #f0f2f5; }
132
  }
133
  .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
134
  .nav-btn.selected { background-color: #e7f3ff !important; color: #1877f2 !important; }
 
 
135
  .content-card {
136
  background: white;
137
  border-radius: 12px;
@@ -141,12 +156,16 @@ body, .gradio-container { background-color: #f0f2f5; }
141
  margin-bottom: 20px;
142
  transition: transform 0.2s;
143
  }
144
- .content-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
 
 
145
  .feed-user-row { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
146
  .feed-avatar { width: 40px; height: 40px; background: #e4e6eb; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; }
147
  .feed-meta { display: flex; flex-direction: column; }
148
  .feed-name { font-weight: 700; color: #050505; font-size: 15px; }
149
  .feed-time { font-size: 12px; color: #65676b; }
 
 
150
  .digitalizer-container {
151
  background: linear-gradient(135deg, #ffffff 0%, #f0f7ff 100%);
152
  border: 1px solid #1877f2;
@@ -156,9 +175,9 @@ body, .gradio-container { background-color: #f0f2f5; }
156
  # ==========================================
157
  # 5. LAYOUT CONSTRUCTION
158
  # ==========================================
159
- # FIX 1: Removed theme and css from here
160
  with gr.Blocks(title="Legacy Kitchen") as demo:
161
 
 
162
  gr.HTML(f"""
163
  <div class="custom-header">
164
  <div class="logo-area">
@@ -170,31 +189,40 @@ with gr.Blocks(title="Legacy Kitchen") as demo:
170
  """)
171
 
172
  with gr.Row():
 
 
173
  with gr.Column(scale=1, min_width=200):
174
  gr.HTML(f"""
175
  <div style="display:flex; align-items:center; padding: 10px; margin-bottom: 10px;">
176
- <img src="data:image/jpeg;base64,{profile_b64}" style="width:36px; height:36px; border-radius:50%; margin-right:10px;">
177
  <b style="font-size: 15px;">My Profile</b>
178
  </div>
179
  """)
 
180
  nav_feed = gr.Button("📰 News Feed", elem_classes=["nav-btn", "selected"])
181
  nav_digital = gr.Button("✨ AI Digitizer", elem_classes=["nav-btn"])
182
  nav_about = gr.Button("ℹ️ About", elem_classes=["nav-btn"])
183
 
 
184
  with gr.Column(scale=3):
185
- # FEED VIEW
 
186
  with gr.Group(visible=True) as feed_view:
 
187
  with gr.Group(elem_classes=["content-card"]):
188
  with gr.Row():
189
- gr.HTML(f'<img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%;">')
190
  gr.Textbox(placeholder=f"What recipe are you cooking today?", show_label=False, container=False, scale=10)
191
 
 
192
  if not df_recipes.empty:
193
  feed_samples = df_recipes.sample(10)
194
  for index, row in feed_samples.iterrows():
195
  user_name = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
196
  emoji = random.choice(["🥘", "🥗", "🍰", "🌮"])
 
197
  with gr.Group(elem_classes=["content-card"]):
 
198
  gr.HTML(f"""
199
  <div class="feed-user-row">
200
  <div class="feed-avatar">{emoji}</div>
@@ -204,8 +232,76 @@ with gr.Blocks(title="Legacy Kitchen") as demo:
204
  </div>
205
  </div>
206
  """)
 
 
207
  gr.Markdown(f"### {row['Title']}")
208
  gr.Markdown(f"{str(row['Raw_Output'])[:250]}...")
209
  gr.Markdown(f"*[Click to see full recipe...]*")
 
 
210
  with gr.Row():
211
- gr.Button("👍 Like", size="sm", variant="
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # ==========================================
40
  def image_to_base64(image_path):
41
  if not os.path.exists(image_path):
42
+ # Returns a 1x1 transparent pixel if image is missing to avoid errors
43
  return "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
44
  with open(image_path, "rb") as img_file:
45
  return base64.b64encode(img_file.read()).decode('utf-8')
46
 
47
+ # Ensure these files are in your Spaces "Files" tab
48
  logo_b64 = image_to_base64("logo.jpg")
49
  profile_b64 = image_to_base64("232px-Tv_the_muppet_show_bein_green.jpg")
50
 
 
103
 
104
  modern_css = """
105
  body, .gradio-container { background-color: #f0f2f5; }
106
+
107
+ /* Sticky Header */
108
  .custom-header {
109
+ background: rgba(255, 255, 255, 0.95);
110
  backdrop-filter: blur(10px);
111
  border-bottom: 1px solid #e4e6eb;
112
  padding: 10px 20px;
 
118
  z-index: 1000;
119
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
120
  }
121
+
122
  .logo-area { display: flex; align-items: center; gap: 15px; }
123
+ .logo-img { height: 40px; width: 40px; border-radius: 50%; object-fit: cover; }
124
+ .app-name {
125
+ font-weight: 800;
126
+ font-size: 24px;
127
+ background: -webkit-linear-gradient(45deg, #1877f2, #6b21a8);
128
+ -webkit-background-clip: text;
129
+ -webkit-text-fill-color: transparent;
130
+ }
131
+
132
+ /* Sidebar Navigation */
133
  .nav-btn {
134
  text-align: left !important;
135
  justify-content: flex-start !important;
 
145
  }
146
  .nav-btn:hover { background-color: #e4e6eb !important; color: #050505 !important; }
147
  .nav-btn.selected { background-color: #e7f3ff !important; color: #1877f2 !important; }
148
+
149
+ /* Feed Cards */
150
  .content-card {
151
  background: white;
152
  border-radius: 12px;
 
156
  margin-bottom: 20px;
157
  transition: transform 0.2s;
158
  }
159
+ .content-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); transform: translateY(-2px); }
160
+
161
+ /* Feed User Info */
162
  .feed-user-row { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
163
  .feed-avatar { width: 40px; height: 40px; background: #e4e6eb; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; }
164
  .feed-meta { display: flex; flex-direction: column; }
165
  .feed-name { font-weight: 700; color: #050505; font-size: 15px; }
166
  .feed-time { font-size: 12px; color: #65676b; }
167
+
168
+ /* Innovation/Digitalizer Styling */
169
  .digitalizer-container {
170
  background: linear-gradient(135deg, #ffffff 0%, #f0f7ff 100%);
171
  border: 1px solid #1877f2;
 
175
  # ==========================================
176
  # 5. LAYOUT CONSTRUCTION
177
  # ==========================================
 
178
  with gr.Blocks(title="Legacy Kitchen") as demo:
179
 
180
+ # --- HEADER ---
181
  gr.HTML(f"""
182
  <div class="custom-header">
183
  <div class="logo-area">
 
189
  """)
190
 
191
  with gr.Row():
192
+
193
+ # --- LEFT SIDEBAR (Navigation) ---
194
  with gr.Column(scale=1, min_width=200):
195
  gr.HTML(f"""
196
  <div style="display:flex; align-items:center; padding: 10px; margin-bottom: 10px;">
197
+ <img src="data:image/jpeg;base64,{profile_b64}" style="width:36px; height:36px; border-radius:50%; margin-right:10px; object-fit:cover;">
198
  <b style="font-size: 15px;">My Profile</b>
199
  </div>
200
  """)
201
+
202
  nav_feed = gr.Button("📰 News Feed", elem_classes=["nav-btn", "selected"])
203
  nav_digital = gr.Button("✨ AI Digitizer", elem_classes=["nav-btn"])
204
  nav_about = gr.Button("ℹ️ About", elem_classes=["nav-btn"])
205
 
206
+ # --- CENTER CONTENT ---
207
  with gr.Column(scale=3):
208
+
209
+ # === VIEW 1: FEED ===
210
  with gr.Group(visible=True) as feed_view:
211
+ # "What's on your mind" Box
212
  with gr.Group(elem_classes=["content-card"]):
213
  with gr.Row():
214
+ gr.HTML(f'<img src="data:image/jpeg;base64,{profile_b64}" style="width:40px; height:40px; border-radius:50%; object-fit:cover;">')
215
  gr.Textbox(placeholder=f"What recipe are you cooking today?", show_label=False, container=False, scale=10)
216
 
217
+ # Dynamic Feed Generation
218
  if not df_recipes.empty:
219
  feed_samples = df_recipes.sample(10)
220
  for index, row in feed_samples.iterrows():
221
  user_name = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
222
  emoji = random.choice(["🥘", "🥗", "🍰", "🌮"])
223
+
224
  with gr.Group(elem_classes=["content-card"]):
225
+ # Header of the Post
226
  gr.HTML(f"""
227
  <div class="feed-user-row">
228
  <div class="feed-avatar">{emoji}</div>
 
232
  </div>
233
  </div>
234
  """)
235
+
236
+ # Content
237
  gr.Markdown(f"### {row['Title']}")
238
  gr.Markdown(f"{str(row['Raw_Output'])[:250]}...")
239
  gr.Markdown(f"*[Click to see full recipe...]*")
240
+
241
+ # Action Buttons
242
  with gr.Row():
243
+ gr.Button("👍 Like", size="sm", variant="secondary")
244
+ gr.Button("💬 Comment", size="sm", variant="secondary")
245
+ gr.Button("↗️ Share", size="sm", variant="secondary")
246
+ else:
247
+ gr.Markdown("⚠️ Database is empty. Please check your CSV file.")
248
+
249
+ # === VIEW 2: AI DIGITALIZER ===
250
+ with gr.Group(visible=False) as digitalizer_view:
251
+ gr.Markdown("## 📸 Recipe Digitalizer", elem_classes=["content-card"])
252
+
253
+ with gr.Row():
254
+ with gr.Column(elem_classes=["content-card", "digitalizer-container"]):
255
+ input_img = gr.Image(type="filepath", label="Upload Handwritten Note", height=300)
256
+ magic_btn = gr.Button("✨ Convert to Text", variant="primary", size="lg")
257
+
258
+ with gr.Column(elem_classes=["content-card"]):
259
+ out_text = gr.Textbox(label="Digitized Text", lines=6, interactive=False)
260
+ out_sim = gr.Textbox(label="Similar Recipes in Database", lines=6)
261
+
262
+ magic_btn.click(magic_pipeline, input_img, [out_text, out_sim])
263
+
264
+ # === VIEW 3: ABOUT ===
265
+ with gr.Group(visible=False) as about_view:
266
+ with gr.Group(elem_classes=["content-card"]):
267
+ gr.Markdown("""
268
+ # ℹ️ About Legacy Kitchen
269
+
270
+ **Preserving Heritage through AI.**
271
+
272
+ Legacy Kitchen allows you to upload photos of your grandmother's handwritten recipe cards and instantly converts them into digital text using OCR and AI models.
273
+
274
+ ### Tech Stack
275
+ * **Hugging Face Spaces** for hosting
276
+ * **Gradio** for the UI
277
+ * **Transformers** for embeddings
278
+ """)
279
+
280
+ # --- RIGHT COLUMN (Trending) ---
281
+ with gr.Column(scale=1, min_width=200):
282
+ gr.Markdown("### Trending Recipes")
283
+ gr.HTML("""
284
+ <div style="background:white; padding:10px; border-radius:8px; margin-bottom:10px; box-shadow:0 1px 2px rgba(0,0,0,0.1);">
285
+ <b>🍜 Ramen Hack</b><br>
286
+ <span style="color:gray; font-size:12px;">12k likes</span>
287
+ </div>
288
+ <div style="background:white; padding:10px; border-radius:8px; box-shadow:0 1px 2px rgba(0,0,0,0.1);">
289
+ <b>🍪 Best Cookies</b><br>
290
+ <span style="color:gray; font-size:12px;">8k likes</span>
291
+ </div>
292
+ """)
293
+
294
+ # ==========================================
295
+ # 6. JAVASCRIPT LOGIC (Client Side)
296
+ # ==========================================
297
+ def go_feed(): return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)
298
+ def go_digi(): return gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
299
+ def go_about(): return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
300
+
301
+ nav_feed.click(go_feed, None, [feed_view, digitalizer_view, about_view])
302
+ nav_digital.click(go_digi, None, [feed_view, digitalizer_view, about_view])
303
+ nav_about.click(go_about, None, [feed_view, digitalizer_view, about_view])
304
+
305
+ if __name__ == "__main__":
306
+ # Theme and CSS injected here to avoid Warnings
307
+ demo.launch(theme=theme, css=modern_css)