siddhartharya commited on
Commit
93e2212
Β·
verified Β·
1 Parent(s): 2a1c0da

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -49
app.py CHANGED
@@ -239,7 +239,7 @@ def display_bookmarks():
239
  cards = ''
240
  for i, bookmark in enumerate(bookmarks):
241
  index = i + 1 # Start index at 1
242
- status = "Dead Link" if bookmark.get('dead_link') else "Active"
243
  title = bookmark['title']
244
  url = bookmark['url']
245
  etag = bookmark.get('etag', 'N/A')
@@ -251,16 +251,15 @@ def display_bookmarks():
251
  card_style = "border: 2px solid #D32F2F;"
252
  text_style = "color: #D32F2F;"
253
  else:
254
- card_style = ""
255
- text_style = ""
256
 
257
  card_html = f'''
258
- <div class="card" style="{card_style}">
259
  <div class="card-content">
260
- <h3 style="{text_style}">{index}. {title}</h3>
261
  <p style="{text_style}"><strong>Category:</strong> {category}</p>
262
  <p style="{text_style}"><strong>URL:</strong> <a href="{url}" target="_blank" style="{text_style}">{url}</a></p>
263
- <p style="{text_style}"><strong>Status:</strong> {status}</p>
264
  <p style="{text_style}"><strong>ETag:</strong> {etag}</p>
265
  <p style="{text_style}"><strong>Summary:</strong> {summary}</p>
266
  </div>
@@ -276,29 +275,29 @@ def process_uploaded_file(file):
276
  logger.info("Processing uploaded file")
277
  if file is None:
278
  logger.warning("No file uploaded")
279
- return "Please upload a bookmarks HTML file.", '', gr.update(), ''
280
  try:
281
  file_content = file.decode('utf-8')
282
  except UnicodeDecodeError as e:
283
  logger.error(f"Error decoding the file: {e}")
284
- return "Error decoding the file. Please ensure it's a valid HTML file.", '', gr.update(), ''
285
 
286
  try:
287
  bookmarks = parse_bookmarks(file_content)
288
  except Exception as e:
289
  logger.error(f"Error parsing bookmarks: {e}")
290
- return "Error parsing the bookmarks HTML file.", '', gr.update(), ''
291
 
292
  if not bookmarks:
293
  logger.warning("No bookmarks found in the uploaded file")
294
- return "No bookmarks found in the uploaded file.", '', gr.update(), ''
295
 
296
  # Asynchronously fetch bookmark info
297
  try:
298
  asyncio.run(process_bookmarks_async(bookmarks))
299
  except Exception as e:
300
  logger.error(f"Error processing bookmarks asynchronously: {e}")
301
- return "Error processing bookmarks.", '', gr.update(), ''
302
 
303
  # Generate summaries and assign categories
304
  for bookmark in bookmarks:
@@ -309,9 +308,9 @@ def process_uploaded_file(file):
309
  faiss_index, embeddings = vectorize_and_index(bookmarks)
310
  except Exception as e:
311
  logger.error(f"Error building FAISS index: {e}")
312
- return "Error building search index.", '', gr.update(), ''
313
 
314
- message = f"Successfully processed {len(bookmarks)} bookmarks."
315
  logger.info(message)
316
  bookmark_html = display_bookmarks()
317
 
@@ -328,7 +327,7 @@ def process_uploaded_file(file):
328
  def delete_selected_bookmarks(selected_indices):
329
  global bookmarks, faiss_index
330
  if not selected_indices:
331
- return "No bookmarks selected.", gr.update(), ''
332
  indices = [int(s.split('.')[0])-1 for s in selected_indices]
333
  indices = sorted(indices, reverse=True)
334
  for idx in indices:
@@ -339,7 +338,7 @@ def delete_selected_bookmarks(selected_indices):
339
  faiss_index, embeddings = vectorize_and_index(bookmarks)
340
  else:
341
  faiss_index = None
342
- message = "Selected bookmarks deleted successfully."
343
  logger.info(message)
344
  # Update bookmark_selector choices
345
  choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
@@ -351,14 +350,15 @@ def delete_selected_bookmarks(selected_indices):
351
  # Edit category of selected bookmarks
352
  def edit_selected_bookmarks_category(selected_indices, new_category):
353
  if not selected_indices:
354
- return "No bookmarks selected.", '', gr.update()
355
  if not new_category:
356
- return "No new category selected.", '', gr.update()
357
  indices = [int(s.split('.')[0])-1 for s in selected_indices]
358
  for idx in indices:
359
  if 0 <= idx < len(bookmarks):
360
  bookmarks[idx]['category'] = new_category
361
- message = "Category updated for selected bookmarks."
 
362
  logger.info(message)
363
  # Update bookmark_selector choices
364
  choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
@@ -371,7 +371,7 @@ def edit_selected_bookmarks_category(selected_indices, new_category):
371
  def export_bookmarks():
372
  if not bookmarks:
373
  logger.warning("No bookmarks to export")
374
- return "No bookmarks to export."
375
  try:
376
  logger.info("Exporting bookmarks to HTML")
377
  # Create an HTML content similar to the imported bookmarks file
@@ -389,20 +389,20 @@ def export_bookmarks():
389
  b64 = base64.b64encode(html_content.encode()).decode()
390
  href = f'data:text/html;base64,{b64}'
391
  logger.info("Bookmarks exported successfully")
392
- return f'<a href="{href}" download="bookmarks.html">Download Exported Bookmarks</a>'
393
  except Exception as e:
394
  logger.error(f"Error exporting bookmarks: {e}")
395
- return "Error exporting bookmarks."
396
 
397
  # Chatbot response using Groq Cloud API
398
  def chatbot_response(user_query):
399
  if not GROQ_API_KEY:
400
  logger.warning("GROQ_API_KEY not set.")
401
- return "API key not set. Please set the GROQ_API_KEY environment variable in the Hugging Face Space settings."
402
 
403
  if not bookmarks:
404
  logger.warning("No bookmarks available for chatbot")
405
- return "No bookmarks available. Please upload and process your bookmarks first."
406
 
407
  logger.info(f"Chatbot received query: {user_query}")
408
 
@@ -444,7 +444,7 @@ Please identify the most relevant bookmarks that match the user's query. Provide
444
  return answer
445
 
446
  except Exception as e:
447
- error_message = f"Error processing your query: {str(e)}"
448
  logger.error(error_message)
449
  print(error_message) # Ensure error appears in Hugging Face Spaces logs
450
  return error_message
@@ -453,28 +453,88 @@ Please identify the most relevant bookmarks that match the user's query. Provide
453
  def build_app():
454
  try:
455
  logger.info("Building Gradio app")
456
- with gr.Blocks(css="app.css") as demo:
457
- gr.Markdown("<h1>Bookmark Manager App</h1>")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
 
 
 
 
 
459
  with gr.Tab("Upload and Process Bookmarks"):
460
- upload = gr.File(label="Upload Bookmarks HTML File", type='binary')
461
- process_button = gr.Button("Process Bookmarks")
462
- output_text = gr.Textbox(label="Output")
463
- bookmark_display = gr.HTML(label="Bookmarks")
 
 
 
 
 
 
 
 
464
 
465
- def update_bookmark_display(file):
466
- return process_uploaded_file(file)
 
 
 
 
 
 
 
 
 
 
467
 
468
  process_button.click(
469
  process_uploaded_file,
470
  inputs=upload,
471
- outputs=[output_text, bookmark_display, gr.State(), gr.State()]
472
  )
473
 
 
474
  with gr.Tab("Chat with Bookmarks"):
475
- user_input = gr.Textbox(label="Ask about your bookmarks")
476
- chat_output = gr.Textbox(label="Chatbot Response")
477
- chat_button = gr.Button("Send")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
 
479
  chat_button.click(
480
  chatbot_response,
@@ -482,21 +542,42 @@ def build_app():
482
  outputs=chat_output
483
  )
484
 
 
485
  with gr.Tab("Manage Bookmarks"):
486
- manage_output = gr.Textbox(label="Manage Output", interactive=False)
487
- bookmark_display_manage = gr.HTML(label="Bookmarks")
488
- bookmark_selector = gr.CheckboxGroup(label="Select Bookmarks", choices=[])
489
 
490
- new_category_input = gr.Dropdown(label="New Category", choices=CATEGORIES)
491
- with gr.Row():
492
- delete_button = gr.Button("Delete Selected Bookmarks")
493
- edit_category_button = gr.Button("Edit Category of Selected Bookmarks")
494
- export_button = gr.Button("Export Bookmarks")
495
- download_link = gr.HTML(label="Download Exported Bookmarks")
496
 
497
- # Update the bookmark display and selector when the app loads
498
- bookmark_display_manage.value = display_bookmarks()
499
- bookmark_selector.choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
 
501
  # Define button actions
502
  delete_button.click(
@@ -517,7 +598,7 @@ def build_app():
517
  outputs=download_link
518
  )
519
 
520
- # Update the bookmark display and selector after processing bookmarks
521
  process_button.click(
522
  process_uploaded_file,
523
  inputs=upload,
 
239
  cards = ''
240
  for i, bookmark in enumerate(bookmarks):
241
  index = i + 1 # Start index at 1
242
+ status = "❌ Dead Link" if bookmark.get('dead_link') else "βœ… Active"
243
  title = bookmark['title']
244
  url = bookmark['url']
245
  etag = bookmark.get('etag', 'N/A')
 
251
  card_style = "border: 2px solid #D32F2F;"
252
  text_style = "color: #D32F2F;"
253
  else:
254
+ card_style = "border: 2px solid #4CAF50;"
255
+ text_style = "color: #000000;"
256
 
257
  card_html = f'''
258
+ <div class="card" style="{card_style}; padding: 10px; margin: 10px; border-radius: 5px;">
259
  <div class="card-content">
260
+ <h3 style="{text_style}">{index}. {title} {status}</h3>
261
  <p style="{text_style}"><strong>Category:</strong> {category}</p>
262
  <p style="{text_style}"><strong>URL:</strong> <a href="{url}" target="_blank" style="{text_style}">{url}</a></p>
 
263
  <p style="{text_style}"><strong>ETag:</strong> {etag}</p>
264
  <p style="{text_style}"><strong>Summary:</strong> {summary}</p>
265
  </div>
 
275
  logger.info("Processing uploaded file")
276
  if file is None:
277
  logger.warning("No file uploaded")
278
+ return "Please upload a bookmarks HTML file.", '', gr.update(choices=[]), display_bookmarks()
279
  try:
280
  file_content = file.decode('utf-8')
281
  except UnicodeDecodeError as e:
282
  logger.error(f"Error decoding the file: {e}")
283
+ return "Error decoding the file. Please ensure it's a valid HTML file.", '', gr.update(choices=[]), display_bookmarks()
284
 
285
  try:
286
  bookmarks = parse_bookmarks(file_content)
287
  except Exception as e:
288
  logger.error(f"Error parsing bookmarks: {e}")
289
+ return "Error parsing the bookmarks HTML file.", '', gr.update(choices=[]), display_bookmarks()
290
 
291
  if not bookmarks:
292
  logger.warning("No bookmarks found in the uploaded file")
293
+ return "No bookmarks found in the uploaded file.", '', gr.update(choices=[]), display_bookmarks()
294
 
295
  # Asynchronously fetch bookmark info
296
  try:
297
  asyncio.run(process_bookmarks_async(bookmarks))
298
  except Exception as e:
299
  logger.error(f"Error processing bookmarks asynchronously: {e}")
300
+ return "Error processing bookmarks.", '', gr.update(choices=[]), display_bookmarks()
301
 
302
  # Generate summaries and assign categories
303
  for bookmark in bookmarks:
 
308
  faiss_index, embeddings = vectorize_and_index(bookmarks)
309
  except Exception as e:
310
  logger.error(f"Error building FAISS index: {e}")
311
+ return "Error building search index.", '', gr.update(choices=[]), display_bookmarks()
312
 
313
+ message = f"βœ… Successfully processed {len(bookmarks)} bookmarks."
314
  logger.info(message)
315
  bookmark_html = display_bookmarks()
316
 
 
327
  def delete_selected_bookmarks(selected_indices):
328
  global bookmarks, faiss_index
329
  if not selected_indices:
330
+ return "⚠️ No bookmarks selected.", gr.update(choices=[]), display_bookmarks()
331
  indices = [int(s.split('.')[0])-1 for s in selected_indices]
332
  indices = sorted(indices, reverse=True)
333
  for idx in indices:
 
338
  faiss_index, embeddings = vectorize_and_index(bookmarks)
339
  else:
340
  faiss_index = None
341
+ message = "πŸ—‘οΈ Selected bookmarks deleted successfully."
342
  logger.info(message)
343
  # Update bookmark_selector choices
344
  choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
 
350
  # Edit category of selected bookmarks
351
  def edit_selected_bookmarks_category(selected_indices, new_category):
352
  if not selected_indices:
353
+ return "⚠️ No bookmarks selected.", '', gr.update()
354
  if not new_category:
355
+ return "⚠️ No new category selected.", '', gr.update()
356
  indices = [int(s.split('.')[0])-1 for s in selected_indices]
357
  for idx in indices:
358
  if 0 <= idx < len(bookmarks):
359
  bookmarks[idx]['category'] = new_category
360
+ logger.info(f"Updated category for bookmark {idx + 1} to {new_category}")
361
+ message = "✏️ Category updated for selected bookmarks."
362
  logger.info(message)
363
  # Update bookmark_selector choices
364
  choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
 
371
  def export_bookmarks():
372
  if not bookmarks:
373
  logger.warning("No bookmarks to export")
374
+ return "⚠️ No bookmarks to export."
375
  try:
376
  logger.info("Exporting bookmarks to HTML")
377
  # Create an HTML content similar to the imported bookmarks file
 
389
  b64 = base64.b64encode(html_content.encode()).decode()
390
  href = f'data:text/html;base64,{b64}'
391
  logger.info("Bookmarks exported successfully")
392
+ return f'<a href="{href}" download="bookmarks.html">πŸ’Ύ Download Exported Bookmarks</a>'
393
  except Exception as e:
394
  logger.error(f"Error exporting bookmarks: {e}")
395
+ return "⚠️ Error exporting bookmarks."
396
 
397
  # Chatbot response using Groq Cloud API
398
  def chatbot_response(user_query):
399
  if not GROQ_API_KEY:
400
  logger.warning("GROQ_API_KEY not set.")
401
+ return "⚠️ API key not set. Please set the GROQ_API_KEY environment variable in the Hugging Face Space settings."
402
 
403
  if not bookmarks:
404
  logger.warning("No bookmarks available for chatbot")
405
+ return "⚠️ No bookmarks available. Please upload and process your bookmarks first."
406
 
407
  logger.info(f"Chatbot received query: {user_query}")
408
 
 
444
  return answer
445
 
446
  except Exception as e:
447
+ error_message = f"⚠️ Error processing your query: {str(e)}"
448
  logger.error(error_message)
449
  print(error_message) # Ensure error appears in Hugging Face Spaces logs
450
  return error_message
 
453
  def build_app():
454
  try:
455
  logger.info("Building Gradio app")
456
+ with gr.Blocks(css="""
457
+ .card {
458
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
459
+ transition: 0.3s;
460
+ }
461
+ .card:hover {
462
+ box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
463
+ }
464
+ """) as demo:
465
+ # General Overview
466
+ gr.Markdown("""
467
+ # πŸ“š SmartMarks - AI Browser Bookmarks Manager
468
+
469
+ Welcome to **SmartMarks**, your intelligent assistant for managing browser bookmarks. SmartMarks leverages AI to help you organize, search, and interact with your bookmarks seamlessly. Whether you're looking to categorize your links, retrieve information quickly, or maintain an updated list, SmartMarks has you covered.
470
+
471
+ ---
472
+
473
+ ## πŸš€ **How to Use SmartMarks**
474
+
475
+ SmartMarks is divided into three main sections:
476
+
477
+ 1. **πŸ“‚ Upload and Process Bookmarks:** Import your existing bookmarks and let SmartMarks analyze and categorize them for you.
478
+ 2. **πŸ’¬ Chat with Bookmarks:** Interact with your bookmarks using natural language queries to find relevant links effortlessly.
479
+ 3. **πŸ› οΈ Manage Bookmarks:** View, edit, delete, and export your bookmarks with ease.
480
 
481
+ Navigate through the tabs to explore each feature in detail.
482
+ """)
483
+
484
+ # Upload and Process Bookmarks Tab
485
  with gr.Tab("Upload and Process Bookmarks"):
486
+ gr.Markdown("""
487
+ ## πŸ“‚ **Upload and Process Bookmarks**
488
+
489
+ ### πŸ“ **Steps to Upload and Process:**
490
+
491
+ 1. **πŸ”½ Upload Bookmarks File:**
492
+ - Click on the **"Upload Bookmarks HTML File"** button.
493
+ - Select your browser's exported bookmarks HTML file from your device.
494
+
495
+ 2. **βš™οΈ Process Bookmarks:**
496
+ - After uploading, click on the **"Process Bookmarks"** button.
497
+ - SmartMarks will parse your bookmarks, fetch additional information, generate summaries, and categorize each link based on predefined categories.
498
 
499
+ 3. **πŸ“„ View Processed Bookmarks:**
500
+ - Once processing is complete, your bookmarks will be displayed in an organized and visually appealing format below.
501
+ """)
502
+
503
+ upload = gr.File(label="πŸ“ Upload Bookmarks HTML File", type='binary')
504
+ process_button = gr.Button("βš™οΈ Process Bookmarks")
505
+ output_text = gr.Textbox(label="βœ… Output", interactive=False)
506
+ bookmark_display = gr.HTML(label="πŸ“„ Bookmarks")
507
+
508
+ # Initialize Manage Bookmarks components
509
+ bookmark_selector = gr.CheckboxGroup(label="βœ… Select Bookmarks", choices=[])
510
+ bookmark_display_manage = gr.HTML(label="πŸ“„ Manage Bookmarks Display")
511
 
512
  process_button.click(
513
  process_uploaded_file,
514
  inputs=upload,
515
+ outputs=[output_text, bookmark_display, bookmark_selector, bookmark_display_manage]
516
  )
517
 
518
+ # Chat with Bookmarks Tab
519
  with gr.Tab("Chat with Bookmarks"):
520
+ gr.Markdown("""
521
+ ## πŸ’¬ **Chat with Bookmarks**
522
+
523
+ ### πŸ€– **How to Interact:**
524
+
525
+ 1. **✍️ Enter Your Query:**
526
+ - In the **"Ask about your bookmarks"** textbox, type your question or keyword related to your bookmarks. For example, "Do I have any bookmarks about GenerativeAI?"
527
+
528
+ 2. **πŸ“¨ Submit Your Query:**
529
+ - Click the **"Send"** button to submit your query.
530
+
531
+ 3. **πŸ“ˆ Receive AI-Driven Responses:**
532
+ - SmartMarks will analyze your query and provide relevant bookmarks that match your request, making it easier to find specific links without manual searching.
533
+ """)
534
+
535
+ user_input = gr.Textbox(label="✍️ Ask about your bookmarks", placeholder="e.g., Do I have any bookmarks about GenerativeAI?")
536
+ chat_output = gr.Textbox(label="πŸ’¬ Chatbot Response", interactive=False)
537
+ chat_button = gr.Button("πŸ“¨ Send")
538
 
539
  chat_button.click(
540
  chatbot_response,
 
542
  outputs=chat_output
543
  )
544
 
545
+ # Manage Bookmarks Tab
546
  with gr.Tab("Manage Bookmarks"):
547
+ gr.Markdown("""
548
+ ## πŸ› οΈ **Manage Bookmarks**
 
549
 
550
+ ### πŸ—‚οΈ **Features:**
551
+
552
+ 1. **πŸ‘οΈ View Bookmarks:**
553
+ - All your processed bookmarks are displayed here with their respective categories and summaries.
 
 
554
 
555
+ 2. **βœ… Select Bookmarks:**
556
+ - Use the checkboxes next to each bookmark to select one, multiple, or all bookmarks you wish to manage.
557
+
558
+ 3. **πŸ—‘οΈ Delete Selected Bookmarks:**
559
+ - After selecting the desired bookmarks, click the **"Delete Selected Bookmarks"** button to remove them from your list.
560
+
561
+ 4. **✏️ Edit Categories:**
562
+ - Select the bookmarks you want to re-categorize.
563
+ - Choose a new category from the dropdown menu labeled **"New Category"**.
564
+ - Click the **"Edit Category of Selected Bookmarks"** button to update their categories.
565
+
566
+ 5. **πŸ’Ύ Export Bookmarks:**
567
+ - Click the **"Export Bookmarks"** button to download your updated bookmarks as an HTML file.
568
+ - This file can be uploaded back to your browser to reflect the changes made within SmartMarks.
569
+ """)
570
+
571
+ manage_output = gr.Textbox(label="πŸ”„ Manage Output", interactive=False)
572
+ bookmark_display_manage = gr.HTML(label="πŸ“„ Manage Bookmarks Display")
573
+ bookmark_selector = gr.CheckboxGroup(label="βœ… Select Bookmarks", choices=[])
574
+
575
+ new_category_input = gr.Dropdown(label="πŸ†• New Category", choices=CATEGORIES, value="Uncategorized")
576
+ with gr.Row():
577
+ delete_button = gr.Button("πŸ—‘οΈ Delete Selected Bookmarks")
578
+ edit_category_button = gr.Button("✏️ Edit Category of Selected Bookmarks")
579
+ export_button = gr.Button("πŸ’Ύ Export Bookmarks")
580
+ download_link = gr.HTML(label="πŸ“₯ Download Exported Bookmarks")
581
 
582
  # Define button actions
583
  delete_button.click(
 
598
  outputs=download_link
599
  )
600
 
601
+ # Initialize display after processing bookmarks
602
  process_button.click(
603
  process_uploaded_file,
604
  inputs=upload,