siddhartharya commited on
Commit
9cc4f0d
β€’
1 Parent(s): 6842452

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +99 -1033
README.md CHANGED
@@ -8,1067 +8,146 @@ sdk_version: 5.5.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
- # πŸ“š SmartMarks - AI Browser Bookmarks Manager
12
 
13
- ![License](https://img.shields.io/badge/license-MIT-blue.svg)
14
- ![Gradio](https://img.shields.io/badge/Gradio-v3.38.0-blue)
15
- ![Python](https://img.shields.io/badge/Python-3.8%2B-blue.svg)
16
- ![Hugging Face Spaces](https://img.shields.io/badge/Hugging%20Face-Spaces-green.svg)
17
 
18
- ## 🌟 Overview
19
-
20
- **SmartMarks** is your intelligent assistant for managing browser bookmarks. Leveraging the power of AI, SmartMarks helps 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.
21
-
22
- ### Key Features
23
-
24
- - **πŸ“‚ Upload and Process Bookmarks:** Import your existing bookmarks and let SmartMarks analyze and categorize them for you.
25
- - **πŸ’¬ Chat with Bookmarks:** Interact with your bookmarks using natural language queries to find relevant links effortlessly.
26
- - **πŸ› οΈ Manage Bookmarks:** View, edit, delete, and export your bookmarks with ease.
27
- - **🎨 Dynamic Color Theme:** Automatically adapts to your system or browser's light/dark mode preferences for optimal readability and aesthetics.
28
-
29
- ## πŸš€ How to Use SmartMarks
30
 
 
 
 
 
 
 
 
31
  SmartMarks is divided into three main sections:
32
 
33
- 1. **πŸ“‚ Upload and Process Bookmarks:** Import and process your bookmarks.
34
- 2. **πŸ’¬ Chat with Bookmarks:** Ask questions about your bookmarks using natural language.
35
- 3. **πŸ› οΈ Manage Bookmarks:** Manage your bookmarks by viewing, editing, deleting, and exporting them.
36
-
37
  Navigate through the tabs to explore each feature in detail.
38
 
39
- ## πŸ“¦ Deployment on Hugging Face Spaces
40
-
41
- SmartMarks is designed to run seamlessly on [Hugging Face Spaces](https://huggingface.co/spaces), providing an interactive and user-friendly interface.
42
-
43
- ### Prerequisites
44
-
45
- - **Hugging Face Account:** To deploy on Hugging Face Spaces, you need an account. Sign up [here](https://huggingface.co/join).
46
- - **API Key:** SmartMarks utilizes the Groq Cloud API for its chatbot functionality. Ensure you have a valid `GROQ_API_KEY`.
47
-
48
- ### Repository Structure
49
-
50
- smartmarks/ β”‚ β”œβ”€β”€ app.py β”œβ”€β”€ app.css β”œβ”€β”€ requirements.txt β”œβ”€β”€ README.md β”œβ”€β”€ LICENSE └── screenshots/ β”œβ”€β”€ light_mode.png └── dark_mode.png
51
-
52
-
53
- ### Setting Up Environment Variables
54
-
55
- 1. **GROQ_API_KEY:**
56
- SmartMarks requires the `GROQ_API_KEY` to interact with the Groq Cloud API. To set this up:
57
-
58
- - Navigate to your Space's dashboard on Hugging Face.
59
- - Go to **Settings** > **Secrets**.
60
- - Add a new secret with the key `GROQ_API_KEY` and paste your API key as the value.
61
-
62
- > **Note:** Keep your API keys secure. Never expose them in your code or repository.
63
-
64
- ### Installing Dependencies
65
-
66
- Hugging Face Spaces automatically installs dependencies listed in the `requirements.txt` file. Ensure your `requirements.txt` includes all necessary packages:
67
-
68
- ```plaintext
69
- gradio
70
- beautifulsoup4
71
- sentence-transformers
72
- faiss-cpu
73
- aiohttp
74
- openai
75
- uuid
76
-
77
-
78
-
79
- Thought for 8 seconds
80
- Certainly! Below are the updated app.css and README.md files for your SmartMarks - AI Browser Bookmarks Manager application. Additionally, I've included the necessary updates to your app.py to ensure that the external CSS file is properly integrated. These changes aim to enhance the application's appearance and maintainability by separating styles from the Python code.
81
-
82
- 1. app.css
83
- This CSS file contains all the styles previously embedded within your app.py. By moving the styles to an external file, you enhance the maintainability and scalability of your application.
84
-
85
- css
86
- Copy code
87
- /* app.css */
88
-
89
- /* Card Styling */
90
- .card {
91
- box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
92
- transition: 0.3s;
93
- padding: 10px;
94
- margin: 10px;
95
- border-radius: 5px;
96
- }
97
-
98
- .card:hover {
99
- box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
100
- }
101
-
102
- /* Dynamic Theme Styling */
103
- @media (prefers-color-scheme: dark) {
104
- body {
105
- color: white;
106
- background-color: #121212;
107
- }
108
- .card {
109
- background-color: #1e1e1e;
110
- }
111
- a {
112
- color: #bb86fc;
113
- }
114
- h1, h2, h3, p, strong {
115
- color: inherit;
116
- }
117
- }
118
-
119
- @media (prefers-color-scheme: light) {
120
- body {
121
- color: black;
122
- background-color: white;
123
- }
124
- .card {
125
- background-color: #fff;
126
- }
127
- a {
128
- color: #1a0dab;
129
- }
130
- h1, h2, h3, p, strong {
131
- color: inherit;
132
- }
133
- }
134
- 2. Updated app.py
135
- To integrate the external app.css file, update your app.py by modifying the gr.Blocks initialization to load the CSS from the app.css file instead of embedding it directly. Ensure that the app.css file is located in the same directory as your app.py or adjust the path accordingly.
136
-
137
- python
138
- Copy code
139
- # app.py
140
-
141
- import gradio as gr
142
- from bs4 import BeautifulSoup
143
- from sentence_transformers import SentenceTransformer
144
- import faiss
145
- import numpy as np
146
- import asyncio
147
- import aiohttp
148
- import re
149
- import base64
150
- import logging
151
- import os
152
- import sys
153
- import uuid # For unique IDs
154
-
155
- # Import OpenAI library
156
- import openai
157
-
158
- # Set up logging to output to the console
159
- logger = logging.getLogger(__name__)
160
- logger.setLevel(logging.INFO)
161
-
162
- # Create a console handler
163
- console_handler = logging.StreamHandler(sys.stdout)
164
- console_handler.setLevel(logging.INFO)
165
-
166
- # Create a formatter and set it for the handler
167
- formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s %(message)s')
168
- console_handler.setFormatter(formatter)
169
-
170
- # Add the handler to the logger
171
- logger.addHandler(console_handler)
172
-
173
- # Initialize models and variables
174
- logger.info("Initializing models and variables")
175
- embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
176
- faiss_index = faiss.IndexIDMap(faiss.IndexFlatL2(embedding_model.get_sentence_embedding_dimension()))
177
- bookmarks = []
178
- fetch_cache = {}
179
-
180
- # Define the categories
181
- CATEGORIES = [
182
- "Social Media",
183
- "News and Media",
184
- "Education and Learning",
185
- "Entertainment",
186
- "Shopping and E-commerce",
187
- "Finance and Banking",
188
- "Technology",
189
- "Health and Fitness",
190
- "Travel and Tourism",
191
- "Food and Recipes",
192
- "Sports",
193
- "Arts and Culture",
194
- "Government and Politics",
195
- "Business and Economy",
196
- "Science and Research",
197
- "Personal Blogs and Journals",
198
- "Job Search and Careers",
199
- "Music and Audio",
200
- "Videos and Movies",
201
- "Reference and Knowledge Bases",
202
- "Dead Link",
203
- "Uncategorized",
204
- ]
205
-
206
- # Set up Groq Cloud API key and base URL
207
- GROQ_API_KEY = os.getenv('GROQ_API_KEY')
208
-
209
- if not GROQ_API_KEY:
210
- logger.error("GROQ_API_KEY environment variable not set.")
211
-
212
- # Set OpenAI API key and base URL to use Groq Cloud API
213
- openai.api_key = GROQ_API_KEY
214
- openai.api_base = "https://api.groq.com/openai/v1" # Corrected API base URL
215
-
216
- # Function to parse bookmarks from HTML
217
- def parse_bookmarks(file_content):
218
- logger.info("Parsing bookmarks")
219
- try:
220
- soup = BeautifulSoup(file_content, 'html.parser')
221
- extracted_bookmarks = []
222
- for link in soup.find_all('a'):
223
- url = link.get('href')
224
- title = link.text.strip()
225
- if url and title:
226
- extracted_bookmarks.append({'url': url, 'title': title})
227
- logger.info(f"Extracted {len(extracted_bookmarks)} bookmarks")
228
- return extracted_bookmarks
229
- except Exception as e:
230
- logger.error("Error parsing bookmarks: %s", e)
231
- raise
232
-
233
- # Asynchronous function to fetch URL info
234
- async def fetch_url_info(session, bookmark):
235
- url = bookmark['url']
236
- if url in fetch_cache:
237
- bookmark.update(fetch_cache[url])
238
- return bookmark
239
-
240
- try:
241
- logger.info(f"Fetching URL info for: {url}")
242
- async with session.get(url, timeout=10) as response:
243
- bookmark['etag'] = response.headers.get('ETag', 'N/A')
244
- bookmark['status_code'] = response.status
245
-
246
- if response.status >= 400:
247
- bookmark['dead_link'] = True
248
- bookmark['description'] = ''
249
- logger.warning(f"Dead link detected: {url} with status {response.status}")
250
- else:
251
- bookmark['dead_link'] = False
252
- content = await response.text()
253
- soup = BeautifulSoup(content, 'html.parser')
254
-
255
- # Extract meta description or Open Graph description
256
- meta_description = soup.find('meta', attrs={'name': 'description'})
257
- og_description = soup.find('meta', attrs={'property': 'og:description'})
258
- if og_description and og_description.get('content'):
259
- description = og_description.get('content')
260
- elif meta_description and meta_description.get('content'):
261
- description = meta_description.get('content')
262
- else:
263
- # If no description, extract visible text
264
- texts = soup.stripped_strings
265
- description = ' '.join(texts[:200]) # Limit to first 200 words
266
- # Generate summary using LLM
267
- description = generate_summary_with_llm(description)
268
-
269
- bookmark['description'] = description
270
- logger.info(f"Fetched description for {url}")
271
- except Exception as e:
272
- bookmark['dead_link'] = True
273
- bookmark['etag'] = 'N/A'
274
- bookmark['status_code'] = 'N/A'
275
- bookmark['description'] = ''
276
- logger.error(f"Error fetching URL info for {url}: {e}")
277
- finally:
278
- fetch_cache[url] = {
279
- 'etag': bookmark.get('etag'),
280
- 'status_code': bookmark.get('status_code'),
281
- 'dead_link': bookmark.get('dead_link'),
282
- 'description': bookmark.get('description'),
283
- }
284
- return bookmark
285
-
286
- # Asynchronous processing of bookmarks
287
- async def process_bookmarks_async(bookmarks_list):
288
- logger.info("Processing bookmarks asynchronously")
289
- try:
290
- async with aiohttp.ClientSession() as session:
291
- tasks = []
292
- for bookmark in bookmarks_list:
293
- task = asyncio.ensure_future(fetch_url_info(session, bookmark))
294
- tasks.append(task)
295
- await asyncio.gather(*tasks)
296
- logger.info("Completed processing bookmarks asynchronously")
297
- except Exception as e:
298
- logger.error(f"Error in asynchronous processing of bookmarks: {e}")
299
- raise
300
-
301
- # Generate summary for a bookmark using LLM
302
- def generate_summary_with_llm(text):
303
- logger.info("Generating summary with LLM")
304
- try:
305
- prompt = f"Summarize the following content in a concise manner:\n\n{text}"
306
- response = openai.ChatCompletion.create(
307
- model='gpt-3.5-turbo', # Use appropriate model
308
- messages=[
309
- {"role": "system", "content": "You are a helpful assistant that summarizes text."},
310
- {"role": "user", "content": prompt}
311
- ],
312
- max_tokens=150,
313
- temperature=0.5,
314
- )
315
- summary = response['choices'][0]['message']['content'].strip()
316
- logger.info("Summary generated successfully")
317
- return summary
318
- except Exception as e:
319
- logger.error(f"Error generating summary with LLM: {e}")
320
- return "No summary available."
321
-
322
- # Generate summary for a bookmark
323
- def generate_summary(bookmark):
324
- description = bookmark.get('description', '')
325
- if description:
326
- bookmark['summary'] = description
327
- else:
328
- # Fallback summary generation
329
- title = bookmark.get('title', '')
330
- if title:
331
- bookmark['summary'] = title
332
- else:
333
- bookmark['summary'] = 'No summary available.'
334
- logger.info(f"Generated summary for bookmark: {bookmark.get('url')}")
335
- return bookmark
336
-
337
- # Assign category to a bookmark using LLM
338
- def assign_category_with_llm(summary):
339
- logger.info("Assigning category with LLM")
340
- try:
341
- categories_str = ', '.join(CATEGORIES)
342
- prompt = f"Assign the most appropriate category to the following summary from the list of categories.\n\nSummary: {summary}\n\nCategories: {categories_str}\n\nCategory:"
343
- response = openai.ChatCompletion.create(
344
- model='gpt-3.5-turbo', # Use appropriate model
345
- messages=[
346
- {"role": "system", "content": "You are a helpful assistant that assigns categories."},
347
- {"role": "user", "content": prompt}
348
- ],
349
- max_tokens=10,
350
- temperature=0.3,
351
- )
352
- category = response['choices'][0]['message']['content'].strip()
353
- # Ensure the category is valid
354
- if category in CATEGORIES:
355
- logger.info(f"Assigned category '{category}' successfully")
356
- return category
357
- else:
358
- logger.warning(f"Received invalid category '{category}' from LLM. Defaulting to 'Uncategorized'.")
359
- return "Uncategorized"
360
- except Exception as e:
361
- logger.error(f"Error assigning category with LLM: {e}")
362
- return "Uncategorized"
363
-
364
- # Assign category to a bookmark
365
- def assign_category(bookmark):
366
- if bookmark.get('dead_link'):
367
- bookmark['category'] = 'Dead Link'
368
- logger.info(f"Assigned category 'Dead Link' to bookmark: {bookmark.get('url')}")
369
- return bookmark
370
-
371
- summary = bookmark.get('summary', '')
372
- if summary:
373
- category = assign_category_with_llm(summary)
374
- bookmark['category'] = category
375
- else:
376
- bookmark['category'] = 'Uncategorized'
377
- logger.info(f"No summary available to assign category for bookmark: {bookmark.get('url')}")
378
- return bookmark
379
-
380
- # Vectorize summaries and build FAISS index
381
- def vectorize_and_index(bookmarks_list):
382
- global faiss_index
383
- logger.info("Vectorizing summaries and updating FAISS index")
384
- try:
385
- summaries = [bookmark['summary'] for bookmark in bookmarks_list]
386
- embeddings = embedding_model.encode(summaries).astype('float32')
387
- ids = [uuid.uuid4().int & (1<<64)-1 for _ in bookmarks_list] # Generate unique 64-bit integer IDs
388
- faiss_index.add_with_ids(embeddings, np.array(ids))
389
- logger.info("FAISS index updated successfully")
390
- return embeddings, ids
391
- except Exception as e:
392
- logger.error(f"Error in vectorizing and indexing: {e}")
393
- raise
394
-
395
- # Remove vectors from FAISS index by IDs
396
- def remove_from_faiss(ids_to_remove):
397
- global faiss_index
398
- logger.info(f"Removing {len(ids_to_remove)} vectors from FAISS index")
399
- try:
400
- faiss_index.remove_ids(np.array(ids_to_remove))
401
- logger.info("Vectors removed from FAISS index successfully")
402
- except Exception as e:
403
- logger.error(f"Error removing vectors from FAISS index: {e}")
404
-
405
- # Generate HTML display for bookmarks
406
- def display_bookmarks():
407
- logger.info("Generating HTML display for bookmarks")
408
- cards = ''
409
- for i, bookmark in enumerate(bookmarks):
410
- index = i + 1 # Start index at 1
411
- status = "❌ Dead Link" if bookmark.get('dead_link') else "βœ… Active"
412
- title = bookmark['title']
413
- url = bookmark['url']
414
- etag = bookmark.get('etag', 'N/A')
415
- summary = bookmark.get('summary', '')
416
- category = bookmark.get('category', 'Uncategorized')
417
-
418
- # Apply inline styles using CSS variables
419
- if bookmark.get('dead_link'):
420
- card_style = "border: 2px solid var(--error-color);"
421
- text_style = "color: var(--error-color);"
422
- else:
423
- card_style = "border: 2px solid var(--success-color);"
424
- text_style = "color: var(--text-color);"
425
-
426
- card_html = f'''
427
- <div class="card" style="{card_style}; padding: 10px; margin: 10px; border-radius: 5px;">
428
- <div class="card-content">
429
- <h3 style="{text_style}">{index}. {title} {status}</h3>
430
- <p style="{text_style}"><strong>Category:</strong> {category}</p>
431
- <p style="{text_style}"><strong>URL:</strong> <a href="{url}" target="_blank" style="{text_style}">{url}</a></p>
432
- <p style="{text_style}"><strong>ETag:</strong> {etag}</p>
433
- <p style="{text_style}"><strong>Summary:</strong> {summary}</p>
434
- </div>
435
- </div>
436
- '''
437
- cards += card_html
438
- logger.info("HTML display generated")
439
- return cards
440
-
441
- # Process the uploaded file
442
- def process_uploaded_file(file, state_bookmarks):
443
- global bookmarks, faiss_index
444
- logger.info("Processing uploaded file")
445
- if file is None:
446
- logger.warning("No file uploaded")
447
- return (
448
- "⚠️ Please upload a bookmarks HTML file.",
449
- "",
450
- gr.update(choices=[]),
451
- display_bookmarks(),
452
- state_bookmarks # Return the unchanged state
453
- )
454
-
455
- try:
456
- file_content = file.decode('utf-8')
457
- except UnicodeDecodeError as e:
458
- logger.error(f"Error decoding the file: {e}")
459
- return (
460
- "⚠️ Error decoding the file. Please ensure it's a valid HTML file.",
461
- "",
462
- gr.update(choices=[]),
463
- display_bookmarks(),
464
- state_bookmarks # Return the unchanged state
465
- )
466
-
467
- try:
468
- bookmarks = parse_bookmarks(file_content)
469
- except Exception as e:
470
- logger.error(f"Error parsing bookmarks: {e}")
471
- return (
472
- "⚠️ Error parsing the bookmarks HTML file.",
473
- "",
474
- gr.update(choices=[]),
475
- display_bookmarks(),
476
- state_bookmarks # Return the unchanged state
477
- )
478
-
479
- if not bookmarks:
480
- logger.warning("No bookmarks found in the uploaded file")
481
- return (
482
- "⚠️ No bookmarks found in the uploaded file.",
483
- "",
484
- gr.update(choices=[]),
485
- display_bookmarks(),
486
- state_bookmarks # Return the unchanged state
487
- )
488
-
489
- # Asynchronously fetch bookmark info
490
- try:
491
- asyncio.run(process_bookmarks_async(bookmarks))
492
- except Exception as e:
493
- logger.error(f"Error processing bookmarks asynchronously: {e}")
494
- return (
495
- "⚠️ Error processing bookmarks.",
496
- "",
497
- gr.update(choices=[]),
498
- display_bookmarks(),
499
- state_bookmarks # Return the unchanged state
500
- )
501
-
502
- # Generate summaries and assign categories
503
- for bookmark in bookmarks:
504
- generate_summary(bookmark)
505
- assign_category(bookmark)
506
-
507
- try:
508
- embeddings, ids = vectorize_and_index(bookmarks)
509
- except Exception as e:
510
- logger.error(f"Error building FAISS index: {e}")
511
- return (
512
- "⚠️ Error building search index.",
513
- "",
514
- gr.update(choices=[]),
515
- display_bookmarks(),
516
- state_bookmarks # Return the unchanged state
517
- )
518
-
519
- # Assign unique IDs to bookmarks
520
- for bookmark, id_ in zip(bookmarks, ids):
521
- bookmark['id'] = id_
522
-
523
- message = f"βœ… Successfully processed {len(bookmarks)} bookmarks."
524
- logger.info(message)
525
- bookmark_html = display_bookmarks()
526
-
527
- # Prepare Manage Bookmarks tab outputs
528
- choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
529
- bookmarks_html_manage = display_bookmarks()
530
-
531
- # Update the shared state
532
- updated_state = bookmarks.copy()
533
-
534
- return (
535
- message,
536
- bookmark_html,
537
- gr.update(choices=choices, value=[]),
538
- bookmarks_html_manage,
539
- updated_state # Return the updated state
540
- )
541
-
542
- # Delete selected bookmarks
543
- def delete_selected_bookmarks(selected_indices, state_bookmarks):
544
- if not selected_indices:
545
- return "⚠️ No bookmarks selected.", gr.update(choices=[]), display_bookmarks(), state_bookmarks
546
-
547
- bookmarks = state_bookmarks.copy()
548
- ids_to_remove = []
549
- indices = []
550
- for s in selected_indices:
551
- try:
552
- idx = int(s.split('.')[0]) - 1
553
- if 0 <= idx < len(bookmarks):
554
- ids_to_remove.append(bookmarks[idx]['id'])
555
- indices.append(idx)
556
- else:
557
- logger.warning(f"Index out of range: {idx + 1}")
558
- except ValueError:
559
- logger.error(f"Invalid selection format: {s}")
560
-
561
- # Remove bookmarks from the list
562
- indices = sorted(indices, reverse=True)
563
- for idx in indices:
564
- logger.info(f"Deleting bookmark at index {idx + 1}")
565
- bookmarks.pop(idx)
566
-
567
- # Remove embeddings from FAISS index
568
- remove_from_faiss(ids_to_remove)
569
-
570
- message = "πŸ—‘οΈ Selected bookmarks deleted successfully."
571
- logger.info(message)
572
-
573
- # Regenerate HTML display
574
- bookmarks_html = display_bookmarks()
575
-
576
- # Update choices for selection
577
- choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
578
-
579
- # Update the shared state
580
- updated_state = bookmarks.copy()
581
-
582
- return message, gr.update(choices=choices, value=[]), bookmarks_html, updated_state
583
-
584
- # Edit category of selected bookmarks
585
- def edit_selected_bookmarks_category(selected_indices, new_category, state_bookmarks):
586
- if not selected_indices:
587
- return (
588
- "⚠️ No bookmarks selected.",
589
- gr.update(choices=[f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(state_bookmarks)], value=[]),
590
- display_bookmarks(),
591
- state_bookmarks
592
- )
593
-
594
- if not new_category:
595
- return (
596
- "⚠️ No new category selected.",
597
- gr.update(choices=[f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(state_bookmarks)], value=[]),
598
- display_bookmarks(),
599
- state_bookmarks
600
- )
601
-
602
- bookmarks = state_bookmarks.copy()
603
- for s in selected_indices:
604
- try:
605
- idx = int(s.split('.')[0]) - 1
606
- if 0 <= idx < len(bookmarks):
607
- bookmarks[idx]['category'] = new_category
608
- logger.info(f"Updated category for bookmark {idx + 1} to {new_category}")
609
- except ValueError:
610
- logger.error(f"Invalid selection format: {s}")
611
-
612
- message = "✏️ Category updated for selected bookmarks."
613
- logger.info(message)
614
-
615
- # Regenerate HTML display
616
- bookmarks_html = display_bookmarks()
617
-
618
- # Update choices for selection
619
- choices = [f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)]
620
-
621
- # Update the shared state
622
- updated_state = bookmarks.copy()
623
-
624
- return message, gr.update(choices=choices, value=[]), bookmarks_html, updated_state
625
-
626
- # Export bookmarks to HTML
627
- def export_bookmarks(state_bookmarks):
628
- bookmarks = state_bookmarks
629
- if not bookmarks:
630
- logger.warning("No bookmarks to export")
631
- return "⚠️ No bookmarks to export."
632
- try:
633
- logger.info("Exporting bookmarks to HTML")
634
- # Create an HTML content similar to the imported bookmarks file
635
- soup = BeautifulSoup("<!DOCTYPE NETSCAPE-Bookmark-file-1><Title>Bookmarks</Title><H1>Bookmarks</H1>", 'html.parser')
636
- dl = soup.new_tag('DL')
637
- for bookmark in bookmarks:
638
- dt = soup.new_tag('DT')
639
- a = soup.new_tag('A', href=bookmark['url'])
640
- a.string = bookmark['title']
641
- dt.append(a)
642
- dl.append(dt)
643
- soup.append(dl)
644
- html_content = str(soup)
645
- # Encode the HTML content to base64 for download
646
- b64 = base64.b64encode(html_content.encode()).decode()
647
- href = f'data:text/html;base64,{b64}'
648
- logger.info("Bookmarks exported successfully")
649
- return f'<a href="{href}" download="bookmarks.html">πŸ’Ύ Download Exported Bookmarks</a>'
650
- except Exception as e:
651
- logger.error(f"Error exporting bookmarks: {e}")
652
- return "⚠️ Error exporting bookmarks."
653
-
654
- # Chatbot response using Groq Cloud API with FAISS search
655
- def chatbot_response(user_query, state_bookmarks):
656
- if not GROQ_API_KEY:
657
- logger.warning("GROQ_API_KEY not set.")
658
- return "⚠️ API key not set. Please set the GROQ_API_KEY environment variable in the Hugging Face Space settings."
659
-
660
- bookmarks = state_bookmarks
661
- if not bookmarks:
662
- logger.warning("No bookmarks available for chatbot")
663
- return "⚠️ No bookmarks available. Please upload and process your bookmarks first."
664
-
665
- logger.info(f"Chatbot received query: {user_query}")
666
-
667
- # Prepare the prompt for the LLM using FAISS search
668
- try:
669
- # Encode the user query
670
- query_embedding = embedding_model.encode([user_query]).astype('float32')
671
-
672
- # Perform FAISS search
673
- k = 5 # Number of top results to retrieve
674
- distances, indices = faiss_index.search(query_embedding, k)
675
-
676
- # Fetch the corresponding bookmarks
677
- relevant_bookmarks = []
678
- for idx in indices[0]:
679
- if idx == -1:
680
- continue # No more results
681
- # Find the bookmark with matching ID
682
- for bookmark in bookmarks:
683
- if bookmark.get('id') == idx:
684
- relevant_bookmarks.append(bookmark)
685
- break
686
-
687
- if not relevant_bookmarks:
688
- return "πŸ” No relevant bookmarks found for your query."
689
-
690
- # Prepare the summary of relevant bookmarks
691
- bookmark_data = ""
692
- for bm in relevant_bookmarks:
693
- bookmark_data += f"Title: {bm['title']}\nURL: {bm['url']}\nSummary: {bm['summary']}\n\n"
694
-
695
- # Construct the prompt
696
- prompt = f"""
697
- You are an assistant that helps users find relevant bookmarks from their collection based on their queries.
698
-
699
- User Query:
700
- {user_query}
701
-
702
- Relevant Bookmarks:
703
- {bookmark_data}
704
-
705
- Please provide a concise summary of the most relevant bookmarks that match the user's query.
706
- """
707
-
708
- # Call the Groq Cloud API via the OpenAI client
709
- response = openai.ChatCompletion.create(
710
- model='gpt-3.5-turbo', # Use appropriate model
711
- messages=[
712
- {"role": "system", "content": "You help users find relevant bookmarks based on their queries."},
713
- {"role": "user", "content": prompt}
714
- ],
715
- max_tokens=500,
716
- temperature=0.7,
717
- )
718
-
719
- # Extract the response text
720
- answer = response['choices'][0]['message']['content'].strip()
721
- logger.info("Chatbot response generated using Groq Cloud API")
722
- return answer
723
-
724
- except Exception as e:
725
- error_message = f"⚠️ Error processing your query: {str(e)}"
726
- logger.error(error_message)
727
- print(error_message) # Ensure error appears in Hugging Face Spaces logs
728
- return error_message
729
-
730
- # Build the Gradio app
731
- def build_app():
732
- try:
733
- logger.info("Building Gradio app")
734
- with gr.Blocks(css="app.css") as demo: # Load external CSS file
735
- # Shared states
736
- state_bookmarks = gr.State([])
737
- chat_history = gr.State([])
738
-
739
- # General Overview
740
- gr.Markdown("""
741
- # πŸ“š SmartMarks - AI Browser Bookmarks Manager
742
-
743
- 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.
744
-
745
- ---
746
-
747
- ## πŸš€ **How to Use SmartMarks**
748
-
749
- SmartMarks is divided into three main sections:
750
-
751
- 1. **πŸ“‚ Upload and Process Bookmarks:** Import your existing bookmarks and let SmartMarks analyze and categorize them for you.
752
- 2. **πŸ’¬ Chat with Bookmarks:** Interact with your bookmarks using natural language queries to find relevant links effortlessly.
753
- 3. **πŸ› οΈ Manage Bookmarks:** View, edit, delete, and export your bookmarks with ease.
754
-
755
- Navigate through the tabs to explore each feature in detail.
756
- """)
757
-
758
- # Define Manage Bookmarks components outside the tab for global access
759
- bookmark_selector = gr.CheckboxGroup(label="βœ… Select Bookmarks", choices=[])
760
- bookmark_display_manage = gr.HTML(label="πŸ“„ Manage Bookmarks Display")
761
-
762
- # Upload and Process Bookmarks Tab
763
- with gr.Tab("Upload and Process Bookmarks"):
764
- gr.Markdown("""
765
- ## πŸ“‚ **Upload and Process Bookmarks**
766
-
767
- ### πŸ“ **Steps to Upload and Process:**
768
-
769
- 1. **πŸ”½ Upload Bookmarks File:**
770
- - Click on the **"πŸ“ Upload Bookmarks HTML File"** button.
771
- - Select your browser's exported bookmarks HTML file from your device.
772
-
773
- 2. **βš™οΈ Process Bookmarks:**
774
- - After uploading, click on the **"βš™οΈ Process Bookmarks"** button.
775
- - SmartMarks will parse your bookmarks, fetch additional information, generate summaries, and categorize each link based on predefined categories.
776
-
777
- 3. **πŸ“„ View Processed Bookmarks:**
778
- - Once processing is complete, your bookmarks will be displayed in an organized and visually appealing format below.
779
- """)
780
-
781
- upload = gr.File(label="πŸ“ Upload Bookmarks HTML File", type='binary')
782
- process_button = gr.Button("βš™οΈ Process Bookmarks")
783
- output_text = gr.Textbox(label="βœ… Output", interactive=False)
784
- bookmark_display = gr.HTML(label="πŸ“„ Bookmarks")
785
-
786
- process_button.click(
787
- process_uploaded_file,
788
- inputs=[upload, state_bookmarks],
789
- outputs=[output_text, bookmark_display, bookmark_selector, bookmark_display_manage, state_bookmarks]
790
- )
791
-
792
- # Chat with Bookmarks Tab
793
- with gr.Tab("Chat with Bookmarks"):
794
- gr.Markdown("""
795
- ## πŸ’¬ **Chat with Bookmarks**
796
-
797
- ### πŸ€– **How to Interact:**
798
-
799
- 1. **✍️ Enter Your Query:**
800
- - 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?"
801
-
802
- 2. **πŸ“¨ Submit Your Query:**
803
- - Click the **"πŸ“¨ Send"** button to submit your query.
804
-
805
- 3. **πŸ“ˆ Receive AI-Driven Responses:**
806
- - SmartMarks will analyze your query and provide relevant bookmarks that match your request, making it easier to find specific links without manual searching.
807
-
808
- 4. **πŸ—‚οΈ View Chat History:**
809
- - All your queries and the corresponding AI responses are displayed in the chat history for your reference.
810
- """)
811
-
812
- with gr.Row():
813
- chat_history_display = gr.Chatbot(label="πŸ—¨οΈ Chat History")
814
- with gr.Column(scale=1):
815
- chat_input = gr.Textbox(
816
- label="✍️ Ask about your bookmarks",
817
- placeholder="e.g., Do I have any bookmarks about GenerativeAI?",
818
- lines=1,
819
- interactive=True
820
- )
821
- chat_button = gr.Button("πŸ“¨ Send")
822
-
823
- # When user presses Enter in chat_input
824
- chat_input.submit(
825
- chatbot_response,
826
- inputs=[chat_input, state_bookmarks],
827
- outputs=chat_history_display
828
- )
829
-
830
- # When user clicks Send button
831
- chat_button.click(
832
- chatbot_response,
833
- inputs=[chat_input, state_bookmarks],
834
- outputs=chat_history_display
835
- )
836
-
837
- # Manage Bookmarks Tab
838
- with gr.Tab("Manage Bookmarks"):
839
- gr.Markdown("""
840
- ## πŸ› οΈ **Manage Bookmarks**
841
-
842
- ### πŸ—‚οΈ **Features:**
843
-
844
- 1. **πŸ‘οΈ View Bookmarks:**
845
- - All your processed bookmarks are displayed here with their respective categories and summaries.
846
 
847
- 2. **βœ… Select Bookmarks:**
848
- - Use the checkboxes next to each bookmark to select one, multiple, or all bookmarks you wish to manage.
 
849
 
850
- 3. **πŸ—‘οΈ Delete Selected Bookmarks:**
851
- - After selecting the desired bookmarks, click the **"πŸ—‘οΈ Delete Selected Bookmarks"** button to remove them from your list.
 
852
 
853
- 4. **✏️ Edit Categories:**
854
- - Select the bookmarks you want to re-categorize.
855
- - Choose a new category from the dropdown menu labeled **"πŸ†• New Category"**.
856
- - Click the **"✏️ Edit Category of Selected Bookmarks"** button to update their categories.
857
 
858
- 5. **πŸ’Ύ Export Bookmarks:**
859
- - Click the **"πŸ’Ύ Export Bookmarks"** button to download your updated bookmarks as an HTML file.
860
- - This file can be uploaded back to your browser to reflect the changes made within SmartMarks.
861
 
862
- 6. **πŸ”„ Refresh Bookmarks:**
863
- - Click the **"πŸ”„ Refresh Bookmarks"** button to ensure the latest state is reflected in the display.
864
- """)
865
 
866
- manage_output = gr.Textbox(label="πŸ”„ Manage Output", interactive=False)
867
- new_category_input = gr.Dropdown(label="πŸ†• New Category", choices=CATEGORIES, value="Uncategorized")
868
- with gr.Row():
869
- delete_button = gr.Button("πŸ—‘οΈ Delete Selected Bookmarks")
870
- edit_category_button = gr.Button("✏️ Edit Category of Selected Bookmarks")
871
- export_button = gr.Button("πŸ’Ύ Export Bookmarks")
872
- download_link = gr.HTML(label="πŸ“₯ Download Exported Bookmarks")
873
- refresh_button = gr.Button("πŸ”„ Refresh Bookmarks")
874
 
875
- # Define button actions
876
- delete_button.click(
877
- delete_selected_bookmarks,
878
- inputs=[bookmark_selector, state_bookmarks],
879
- outputs=[manage_output, bookmark_selector, bookmark_display_manage, state_bookmarks]
880
- )
881
 
882
- edit_category_button.click(
883
- edit_selected_bookmarks_category,
884
- inputs=[bookmark_selector, new_category_input, state_bookmarks],
885
- outputs=[manage_output, bookmark_selector, bookmark_display_manage, state_bookmarks]
886
- )
887
 
888
- export_button.click(
889
- export_bookmarks,
890
- inputs=[state_bookmarks],
891
- outputs=download_link
892
- )
893
 
894
- refresh_button.click(
895
- lambda bookmarks: (
896
- [
897
- f"{i+1}. {bookmark['title']} (Category: {bookmark['category']})" for i, bookmark in enumerate(bookmarks)
898
- ],
899
- display_bookmarks()
900
- ),
901
- inputs=[state_bookmarks],
902
- outputs=[bookmark_selector, bookmark_display_manage]
903
- )
904
 
905
- logger.info("Launching Gradio app")
906
- demo.launch(debug=True)
907
- except Exception as e:
908
- logger.error(f"Error building the app: {e}")
909
- print(f"Error building the app: {e}")
910
 
911
- if __name__ == "__main__":
912
- build_app()
913
- Key Changes:
914
 
915
- External CSS Integration:
916
- Changed gr.Blocks(css=""" ... """) to gr.Blocks(css="app.css") to load styles from the external app.css file.
917
- Folder Structure Consideration:
918
- Ensure that the app.css file is located in the same directory as app.py or adjust the path accordingly.
919
- 3. Updated README.md
920
- The updated README.md now reflects the addition of the external app.css file and provides clear instructions on maintaining and organizing your project files.
921
 
 
 
 
 
922
  markdown
923
  Copy code
924
- # πŸ“š SmartMarks - AI Browser Bookmarks Manager
925
-
926
- ![License](https://img.shields.io/badge/license-MIT-blue.svg)
927
- ![Gradio](https://img.shields.io/badge/Gradio-v3.38.0-blue)
928
- ![Python](https://img.shields.io/badge/Python-3.8%2B-blue.svg)
929
- ![Hugging Face Spaces](https://img.shields.io/badge/Hugging%20Face-Spaces-green.svg)
930
-
931
- ## 🌟 Overview
932
-
933
- **SmartMarks** is your intelligent assistant for managing browser bookmarks. Leveraging the power of AI, SmartMarks helps 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.
934
-
935
- ### Key Features
936
-
937
- - **πŸ“‚ Upload and Process Bookmarks:** Import your existing bookmarks and let SmartMarks analyze and categorize them for you.
938
- - **πŸ’¬ Chat with Bookmarks:** Interact with your bookmarks using natural language queries to find relevant links effortlessly.
939
- - **πŸ› οΈ Manage Bookmarks:** View, edit, delete, and export your bookmarks with ease.
940
- - **🎨 Dynamic Color Theme:** Automatically adapts to your system or browser's light/dark mode preferences for optimal readability and aesthetics.
941
-
942
- ## πŸš€ How to Use SmartMarks
943
-
944
- SmartMarks is divided into three main sections:
945
-
946
- 1. **πŸ“‚ Upload and Process Bookmarks:** Import and process your bookmarks.
947
- 2. **πŸ’¬ Chat with Bookmarks:** Ask questions about your bookmarks using natural language.
948
- 3. **πŸ› οΈ Manage Bookmarks:** Manage your bookmarks by viewing, editing, deleting, and exporting them.
949
-
950
- Navigate through the tabs to explore each feature in detail.
951
-
952
- ## πŸ“¦ Deployment on Hugging Face Spaces
953
 
954
- SmartMarks is designed to run seamlessly on [Hugging Face Spaces](https://huggingface.co/spaces), providing an interactive and user-friendly interface.
955
 
956
- ### Prerequisites
957
 
958
- - **Hugging Face Account:** To deploy on Hugging Face Spaces, you need an account. Sign up [here](https://huggingface.co/join).
959
- - **API Key:** SmartMarks utilizes the Groq Cloud API for its chatbot functionality. Ensure you have a valid `GROQ_API_KEY`.
960
 
961
- ### Repository Structure
962
 
963
- smartmarks/ β”‚ β”œβ”€β”€ app.py β”œβ”€β”€ app.css β”œβ”€β”€ requirements.txt β”œβ”€β”€ README.md β”œβ”€β”€ LICENSE └── screenshots/ β”œβ”€β”€ light_mode.png └── dark_mode.png
 
964
 
965
- markdown
966
  Copy code
967
-
968
- ### Setting Up Environment Variables
969
-
970
- 1. **GROQ_API_KEY:**
971
- SmartMarks requires the `GROQ_API_KEY` to interact with the Groq Cloud API. To set this up:
972
-
973
- - Navigate to your Space's dashboard on Hugging Face.
974
- - Go to **Settings** > **Secrets**.
975
- - Add a new secret with the key `GROQ_API_KEY` and paste your API key as the value.
976
-
977
- > **Note:** Keep your API keys secure. Never expose them in your code or repository.
978
-
979
- ### Installing Dependencies
980
-
981
- Hugging Face Spaces automatically installs dependencies listed in the `requirements.txt` file. Ensure your `requirements.txt` includes all necessary packages:
982
-
983
- ```plaintext
984
  gradio
985
  beautifulsoup4
986
  sentence-transformers
987
  faiss-cpu
988
- aiohttp
989
- openai
990
- uuid
991
- Note: The uuid library is part of Python's standard library and doesn't require installation. You can remove it from requirements.txt if preferred.
992
-
993
- Deploying the Space
994
- Create a New Space:
995
-
996
- Navigate to Hugging Face Spaces and click on "Create new Space".
997
- Choose the Gradio SDK and set the visibility (public or private) as desired.
998
- Upload Your Code:
999
 
1000
- Clone your Space repository or use the web interface to upload app.py, app.css, requirements.txt, README.md, and LICENSE.
1001
- Launch the Space:
1002
-
1003
- Once all files are uploaded, Hugging Face Spaces will automatically build and deploy your application.
1004
- Access your Space via the provided URL.
1005
  🌈 Dynamic Color Theme
1006
  SmartMarks automatically detects your system or browser's preferred color scheme and adjusts the application's theme accordingly:
1007
 
1008
  Dark Mode: White text on a dark background for reduced eye strain in low-light environments.
1009
  Light Mode: Black text on a light background for bright environments.
1010
- This dynamic theming ensures optimal readability and aesthetics without any manual intervention.
1011
 
1012
- How It Works
1013
- The application uses CSS media queries to detect the user's preferred color scheme and applies appropriate styles by loading them from the external app.css file:
1014
 
1015
- css
1016
- Copy code
1017
- /* app.css */
1018
 
1019
- /* Card Styling */
1020
- .card {
1021
- box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
1022
- transition: 0.3s;
1023
- padding: 10px;
1024
- margin: 10px;
1025
- border-radius: 5px;
1026
- }
1027
 
1028
- .card:hover {
1029
- box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
1030
- }
1031
 
1032
- /* Dynamic Theme Styling */
1033
- @media (prefers-color-scheme: dark) {
1034
- body {
1035
- color: white;
1036
- background-color: #121212;
1037
- }
1038
- .card {
1039
- background-color: #1e1e1e;
1040
- }
1041
- a {
1042
- color: #bb86fc;
1043
- }
1044
- h1, h2, h3, p, strong {
1045
- color: inherit;
1046
- }
1047
- }
1048
 
1049
- @media (prefers-color-scheme: light) {
1050
- body {
1051
- color: black;
1052
- background-color: white;
1053
- }
1054
- .card {
1055
- background-color: #fff;
1056
- }
1057
- a {
1058
- color: #1a0dab;
1059
- }
1060
- h1, h2, h3, p, strong {
1061
- color: inherit;
1062
- }
1063
- }
1064
- These styles ensure that the text and background colors adapt based on the user's system or browser theme settings.
1065
 
1066
- πŸ“Έ Screenshots
1067
- Note: Replace the placeholders below with actual screenshots of your application in both light and dark modes.
1068
 
1069
- Light Mode
1070
 
1071
- Dark Mode
1072
 
1073
  πŸ“‹ Features in Detail
1074
  πŸ“‚ Upload and Process Bookmarks
@@ -1082,17 +161,17 @@ After uploading, click on the "βš™οΈ Process Bookmarks" button.
1082
  SmartMarks will parse your bookmarks, fetch additional information, generate summaries, and categorize each link based on predefined categories.
1083
  View Processed Bookmarks:
1084
 
1085
- Once processing is complete, your bookmarks will be displayed in an organized and visually appealing format below.
1086
  πŸ’¬ Chat with Bookmarks
1087
  Enter Your Query:
1088
 
1089
- 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?"
1090
  Submit Your Query:
1091
 
1092
  Click the "πŸ“¨ Send" button to submit your query.
1093
  Receive AI-Driven Responses:
1094
 
1095
- SmartMarks will analyze your query and provide relevant bookmarks that match your request, making it easier to find specific links without manual searching.
1096
  View Chat History:
1097
 
1098
  All your queries and the corresponding AI responses are displayed in the chat history for your reference.
@@ -1105,32 +184,19 @@ Select Bookmarks:
1105
  Use the checkboxes next to each bookmark to select one, multiple, or all bookmarks you wish to manage.
1106
  Delete Selected Bookmarks:
1107
 
1108
- After selecting the desired bookmarks, click the "πŸ—‘οΈ Delete Selected Bookmarks" button to remove them from your list.
1109
  Edit Categories:
1110
 
1111
  Select the bookmarks you want to re-categorize.
1112
  Choose a new category from the dropdown menu labeled "πŸ†• New Category".
1113
- Click the "✏️ Edit Category of Selected Bookmarks" button to update their categories.
1114
  Export Bookmarks:
1115
 
1116
- Click the "πŸ’Ύ Export Bookmarks" button to download your updated bookmarks as an HTML file.
1117
  This file can be uploaded back to your browser to reflect the changes made within SmartMarks.
1118
  Refresh Bookmarks:
1119
 
1120
  Click the "πŸ”„ Refresh Bookmarks" button to ensure the latest state is reflected in the display.
1121
- πŸ”§ Configuration
1122
- Ensure that the GROQ_API_KEY environment variable is set correctly, as it's essential for the chatbot functionality to interact with the Groq Cloud API.
1123
-
1124
- Setting Up Environment Variables
1125
- Navigate to Space Settings:
1126
-
1127
- Go to your Space's dashboard on Hugging Face.
1128
- Add Secret:
1129
-
1130
- Click on Settings > Secrets.
1131
- Add a new secret with the key GROQ_API_KEY and paste your API key as the value.
1132
- Note: Keep your API keys secure. Never expose them in your code or repository.
1133
-
1134
  🀝 Contributing
1135
  Contributions are welcome! Please follow these steps to contribute:
1136
 
@@ -1165,10 +231,10 @@ Open a Pull Request:
1165
 
1166
  Navigate to your forked repository on GitHub and click on "Compare & pull request".
1167
  πŸ“œ License
1168
- This project is licensed under the MIT License. See the LICENSE file for details.
1169
 
1170
  πŸ“ž Contact
1171
- For any questions or feedback, please contact your-email@example.com.
1172
 
1173
  Happy Bookmarking with SmartMarks! πŸš€πŸ“š
1174
 
 
8
  app_file: app.py
9
  pinned: false
10
  ---
11
+ πŸ“š SmartMarks - AI Browser Bookmarks Manager
12
 
 
 
 
 
13
 
14
+ 🌟 Overview
15
+ SmartMarks is your intelligent assistant for managing browser bookmarks. Leveraging the power of AI, SmartMarks helps 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.
 
 
 
 
 
 
 
 
 
 
16
 
17
+ Key Features
18
+ πŸ“‚ Upload and Process Bookmarks: Import your existing bookmarks and let SmartMarks analyze and categorize them for you.
19
+ πŸ’¬ Chat with Bookmarks: Interact with your bookmarks using natural language queries to find relevant links effortlessly.
20
+ πŸ› οΈ Manage Bookmarks: View, edit, delete, and export your bookmarks with ease.
21
+ πŸš€ High Processing Speed: Enhanced performance through concurrent fetching and processing of bookmarks.
22
+ 🎨 Dynamic Color Theme: Automatically adapts to your system or browser's light/dark mode preferences for optimal readability and aesthetics.
23
+ πŸš€ How to Use SmartMarks
24
  SmartMarks is divided into three main sections:
25
 
26
+ πŸ“‚ Upload and Process Bookmarks: Import and process your bookmarks.
27
+ πŸ’¬ Chat with Bookmarks: Ask questions about your bookmarks using natural language.
28
+ πŸ› οΈ Manage Bookmarks: Manage your bookmarks by viewing, editing, deleting, and exporting them.
 
29
  Navigate through the tabs to explore each feature in detail.
30
 
31
+ πŸ“‚ Upload and Process Bookmarks
32
+ πŸ“ Steps:
33
+ Upload Bookmarks File:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
+ Click on the "πŸ“ Upload Bookmarks HTML File" button.
36
+ Select your browser's exported bookmarks HTML file from your device.
37
+ Process Bookmarks:
38
 
39
+ After uploading, click on the "βš™οΈ Process Bookmarks" button.
40
+ SmartMarks will parse your bookmarks, fetch additional information, generate summaries, and categorize each link based on predefined categories.
41
+ View Processed Bookmarks:
42
 
43
+ Once processing is complete, your bookmarks will be displayed in an organized and visually appealing format.
44
+ πŸ’¬ Chat with Bookmarks
45
+ πŸ€– How to Interact:
46
+ Enter Your Query:
47
 
48
+ In the "✍️ Ask about your bookmarks" textbox, type your question or keyword related to your bookmarks. For example, "Do I have any bookmarks about AI?"
49
+ Submit Your Query:
 
50
 
51
+ Click the "πŸ“¨ Send" button to submit your query.
52
+ Receive AI-Driven Responses:
 
53
 
54
+ SmartMarks will analyze your query and provide relevant bookmarks that match your request, making it easier to find specific links without manual searching.
55
+ View Chat History:
 
 
 
 
 
 
56
 
57
+ All your queries and the corresponding AI responses are displayed in the chat history for your reference.
58
+ πŸ› οΈ Manage Bookmarks
59
+ πŸ—‚οΈ Features:
60
+ View Bookmarks:
 
 
61
 
62
+ All your processed bookmarks are displayed here with their respective categories and summaries.
63
+ Select Bookmarks:
 
 
 
64
 
65
+ Use the checkboxes next to each bookmark to select one, multiple, or all bookmarks you wish to manage.
66
+ Delete Selected Bookmarks:
 
 
 
67
 
68
+ After selecting the desired bookmarks, click the "πŸ—‘οΈ Delete Selected" button to remove them from your list.
69
+ Edit Categories:
 
 
 
 
 
 
 
 
70
 
71
+ Select the bookmarks you want to re-categorize.
72
+ Choose a new category from the dropdown menu labeled "πŸ†• New Category".
73
+ Click the "✏️ Edit Category" button to update their categories.
74
+ Export Bookmarks:
 
75
 
76
+ Click the "πŸ’Ύ Export" button to download your updated bookmarks as an HTML file.
77
+ This file can be uploaded back to your browser to reflect the changes made within SmartMarks.
78
+ Refresh Bookmarks:
79
 
80
+ Click the "πŸ”„ Refresh Bookmarks" button to ensure the latest state is reflected in the display.
81
+ πŸ“¦ Deployment on Hugging Face Spaces
82
+ SmartMarks is designed to run seamlessly on Hugging Face Spaces, providing an interactive and user-friendly interface.
 
 
 
83
 
84
+ Prerequisites
85
+ Hugging Face Account: To deploy on Hugging Face Spaces, you need an account. Sign up here.
86
+ API Key: SmartMarks utilizes the Groq Cloud API for its chatbot functionality. Ensure you have a valid GROQ_API_KEY.
87
+ Repository Structure
88
  markdown
89
  Copy code
90
+ smartmarks/
91
+ β”œβ”€β”€ app.py
92
+ β”œβ”€β”€ app.css
93
+ β”œβ”€β”€ requirements.txt
94
+ β”œβ”€β”€ README.md
95
+ └── screenshots/
96
+ β”œβ”€β”€ light_mode.png
97
+ └── dark_mode.png
98
+ Setting Up Environment Variables
99
+ GROQ_API_KEY: SmartMarks requires the GROQ_API_KEY to interact with the Groq Cloud API. To set this up:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
+ Navigate to your Space's dashboard on Hugging Face.
102
 
103
+ Go to Settings > Secrets.
104
 
105
+ Add a new secret with the key GROQ_API_KEY and paste your API key as the value.
 
106
 
107
+ Note: Keep your API keys secure. Never expose them in your code or repository.
108
 
109
+ Installing Dependencies
110
+ Hugging Face Spaces automatically installs dependencies listed in the requirements.txt file. Ensure your requirements.txt includes all necessary packages:
111
 
112
+ shell
113
  Copy code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  gradio
115
  beautifulsoup4
116
  sentence-transformers
117
  faiss-cpu
118
+ requests
119
+ numpy
120
+ openai>=0.27.0,<1.0.0
121
+ Note: The uuid library is part of Python's standard library and doesn't require installation via pip. You can remove it from requirements.txt if it was previously included.
 
 
 
 
 
 
 
122
 
 
 
 
 
 
123
  🌈 Dynamic Color Theme
124
  SmartMarks automatically detects your system or browser's preferred color scheme and adjusts the application's theme accordingly:
125
 
126
  Dark Mode: White text on a dark background for reduced eye strain in low-light environments.
127
  Light Mode: Black text on a light background for bright environments.
128
+ These styles ensure that the text and background colors adapt based on the user's system or browser theme settings.
129
 
130
+ πŸ“Έ Screenshots
131
+ Note: Replace the placeholders below with actual screenshots of your application in both light and dark modes.
132
 
133
+ Light Mode
 
 
134
 
135
+ Dark Mode
 
 
 
 
 
 
 
136
 
137
+ πŸ”§ Configuration
138
+ Ensure that the GROQ_API_KEY environment variable is set correctly, as it's essential for the chatbot functionality to interact with the Groq Cloud API.
 
139
 
140
+ Setting Up Environment Variables
141
+ Navigate to Space Settings:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ Go to your Space's dashboard on Hugging Face.
144
+ Add Secret:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ Click on Settings > Secrets.
 
147
 
148
+ Add a new secret with the key GROQ_API_KEY and paste your API key as the value.
149
 
150
+ Note: Keep your API keys secure. Never expose them in your code or repository.
151
 
152
  πŸ“‹ Features in Detail
153
  πŸ“‚ Upload and Process Bookmarks
 
161
  SmartMarks will parse your bookmarks, fetch additional information, generate summaries, and categorize each link based on predefined categories.
162
  View Processed Bookmarks:
163
 
164
+ Once processing is complete, your bookmarks will be displayed in an organized and visually appealing format.
165
  πŸ’¬ Chat with Bookmarks
166
  Enter Your Query:
167
 
168
+ In the "✍️ Ask about your bookmarks" textbox, type your question or keyword related to your bookmarks. For example, "Do I have any bookmarks about AI?"
169
  Submit Your Query:
170
 
171
  Click the "πŸ“¨ Send" button to submit your query.
172
  Receive AI-Driven Responses:
173
 
174
+ SmartMarks will analyze your query and provide relevant bookmarks that match your request.
175
  View Chat History:
176
 
177
  All your queries and the corresponding AI responses are displayed in the chat history for your reference.
 
184
  Use the checkboxes next to each bookmark to select one, multiple, or all bookmarks you wish to manage.
185
  Delete Selected Bookmarks:
186
 
187
+ After selecting the desired bookmarks, click the "πŸ—‘οΈ Delete Selected" button to remove them from your list.
188
  Edit Categories:
189
 
190
  Select the bookmarks you want to re-categorize.
191
  Choose a new category from the dropdown menu labeled "πŸ†• New Category".
192
+ Click the "✏️ Edit Category" button to update their categories.
193
  Export Bookmarks:
194
 
195
+ Click the "πŸ’Ύ Export" button to download your updated bookmarks as an HTML file.
196
  This file can be uploaded back to your browser to reflect the changes made within SmartMarks.
197
  Refresh Bookmarks:
198
 
199
  Click the "πŸ”„ Refresh Bookmarks" button to ensure the latest state is reflected in the display.
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  🀝 Contributing
201
  Contributions are welcome! Please follow these steps to contribute:
202
 
 
231
 
232
  Navigate to your forked repository on GitHub and click on "Compare & pull request".
233
  πŸ“œ License
234
+ This project is licensed under the MIT License.
235
 
236
  πŸ“ž Contact
237
+ For any questions or feedback, please contact siddhartharya@gmail.com
238
 
239
  Happy Bookmarking with SmartMarks! πŸš€πŸ“š
240