BrotherTony commited on
Commit
0fe0128
·
verified ·
1 Parent(s): ad17cdc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +307 -179
app.py CHANGED
@@ -5,7 +5,7 @@ import random
5
  def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None):
6
  try:
7
  url = "https://huggingface.co/api/datasets"
8
- params = {"limit": 100, "full": "true"}
9
 
10
  if task and task.strip():
11
  params["filter"] = task.strip()
@@ -14,13 +14,27 @@ def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None)
14
  response.raise_for_status()
15
  datasets = response.json()
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  filtered = []
18
  for ds in datasets:
19
  likes = ds.get("likes", 0)
20
 
21
- if min_likes is not None and likes < min_likes:
22
  continue
23
- if max_likes is not None and likes > max_likes:
24
  continue
25
 
26
  if language and language.strip():
@@ -36,17 +50,15 @@ def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None)
36
  return """
37
  <div class='result-container empty-state'>
38
  <div class='empty-icon'>
39
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
40
  <circle cx="12" cy="12" r="10"/>
41
- <path d="M12 6v6l4 2"/>
 
42
  </svg>
43
  </div>
44
  <h3>No Results Found</h3>
45
- <p>Try adjusting your filters to discover datasets</p>
46
  </div>
47
- <script>
48
- new Audio('https://assets.mixkit.co/active_storage/sfx/2572/2572-preview.mp3').play().catch(() => {{}});
49
- </script>
50
  """
51
 
52
  dataset = random.choice(filtered)
@@ -60,45 +72,69 @@ def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None)
60
  tags_html = ''.join([f"<span class='tag'>{tag}</span>" for tag in tags])
61
 
62
  result = f"""
63
- <div class='result-container success-state'>
64
  <div class='result-header'>
65
  <h2 class='dataset-title'>{dataset_id}</h2>
66
  <p class='dataset-author'>by {author}</p>
67
  </div>
68
 
69
  <div class='stats-grid'>
70
- <div class='stat-card stat-primary'>
71
- <div class='stat-label'>Likes</div>
72
- <div class='stat-value'>{likes:,}</div>
 
 
 
 
 
73
  </div>
74
- <div class='stat-card stat-secondary'>
75
- <div class='stat-label'>Downloads</div>
76
- <div class='stat-value'>{downloads:,}</div>
 
 
 
 
 
 
 
77
  </div>
78
  </div>
79
 
80
- <div class='description-section'>
81
- <h3>Description</h3>
82
- <p>{description[:400]}{'...' if len(description) > 400 else ''}</p>
 
 
 
 
 
 
 
 
 
83
  </div>
84
 
85
- <div class='tags-section'>
86
- <h3>Tags</h3>
87
- <div class='tags-container'>{tags_html if tags_html else '<span class="no-tags">No tags available</span>'}</div>
88
- </div>
 
 
 
 
 
 
89
 
90
  <a href='https://huggingface.co/datasets/{dataset_id}' target='_blank' class='view-button'>
91
- View on HuggingFace
92
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
93
  <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
94
  <polyline points="15 3 21 3 21 9"/>
95
  <line x1="10" y1="14" x2="21" y2="3"/>
96
  </svg>
97
  </a>
98
  </div>
99
- <script>
100
- new Audio('https://assets.mixkit.co/active_storage/sfx/2570/2570-preview.mp3').play().catch(() => {{}});
101
- </script>
102
  """
103
  return result
104
 
@@ -106,7 +142,7 @@ def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None)
106
  return f"""
107
  <div class='result-container error-state'>
108
  <div class='error-icon'>
109
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
110
  <circle cx="12" cy="12" r="10"/>
111
  <line x1="15" y1="9" x2="9" y2="15"/>
112
  <line x1="9" y1="9" x2="15" y2="15"/>
@@ -115,173 +151,192 @@ def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None)
115
  <h3>Error</h3>
116
  <p>{str(e)}</p>
117
  </div>
118
- <script>
119
- new Audio('https://assets.mixkit.co/active_storage/sfx/2573/2573-preview.mp3').play().catch(() => {{}});
120
- </script>
121
  """
122
 
123
  custom_css = """
124
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
125
 
126
  * {
127
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
128
  }
129
 
130
  .gradio-container {
131
- max-width: 920px !important;
132
  margin: 0 auto !important;
 
133
  }
134
 
135
  body {
136
- background: #FAFBFC;
137
  }
138
 
139
  .header-section {
140
  text-align: center;
141
- padding: 56px 24px 40px;
142
- background: linear-gradient(135deg, #1E3A8A 0%, #1E40AF 100%);
143
- border-radius: 20px;
144
- margin-bottom: 40px;
145
  position: relative;
146
  overflow: hidden;
 
147
  }
148
 
149
  .header-section::before {
150
  content: '';
151
  position: absolute;
152
- top: 0;
153
- left: 0;
154
- right: 0;
155
- bottom: 0;
156
- background: radial-gradient(circle at 30% 50%, rgba(59, 130, 246, 0.2) 0%, transparent 50%),
157
- radial-gradient(circle at 70% 50%, rgba(147, 51, 234, 0.2) 0%, transparent 50%);
158
- pointer-events: none;
 
 
 
 
159
  }
160
 
161
  .main-title {
162
  color: white;
163
- font-size: 42px;
164
- font-weight: 700;
165
- margin: 0 0 12px 0;
166
- letter-spacing: -1px;
167
  position: relative;
168
  z-index: 1;
 
169
  }
170
 
171
  .main-subtitle {
172
- color: rgba(255, 255, 255, 0.85);
173
- font-size: 17px;
174
  margin: 0;
175
- font-weight: 400;
176
  position: relative;
177
  z-index: 1;
 
178
  }
179
 
180
  .filter-container {
181
  background: white;
182
- padding: 32px;
183
- border-radius: 16px;
184
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
185
- margin-bottom: 24px;
186
- border: 1px solid #E5E7EB;
187
  }
188
 
189
  .filter-label {
190
- color: #1F2937;
191
- font-size: 16px;
192
- font-weight: 600;
193
- margin-bottom: 24px;
194
  display: block;
 
195
  }
196
 
197
  label {
198
- color: #374151 !important;
199
  font-size: 14px !important;
200
- font-weight: 500 !important;
201
- margin-bottom: 8px !important;
 
202
  }
203
 
204
  input[type="number"], input[type="text"] {
205
- border: 1.5px solid #D1D5DB !important;
206
- border-radius: 10px !important;
207
- padding: 12px 14px !important;
208
  font-size: 15px !important;
209
- transition: all 0.2s ease !important;
 
 
 
 
 
210
  background: white !important;
 
211
  }
212
 
213
  input[type="number"]:focus, input[type="text"]:focus {
214
  border-color: #3B82F6 !important;
215
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
216
  outline: none !important;
 
217
  }
218
 
219
  button.primary {
220
- background: linear-gradient(135deg, #1E3A8A 0%, #1E40AF 100%) !important;
221
  border: none !important;
222
  color: white !important;
223
- font-size: 16px !important;
224
- font-weight: 600 !important;
225
- padding: 16px 40px !important;
226
- border-radius: 12px !important;
227
  cursor: pointer !important;
228
- transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1) !important;
229
- box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3) !important;
230
  width: 100% !important;
231
- margin-top: 8px !important;
 
232
  }
233
 
234
  button.primary:hover {
235
- transform: translateY(-2px) !important;
236
- box-shadow: 0 8px 20px rgba(30, 58, 138, 0.4) !important;
 
237
  }
238
 
239
  button.primary:active {
240
- transform: translateY(0px) !important;
241
  }
242
 
243
  .result-container {
244
  background: white;
245
- border-radius: 16px;
246
- padding: 40px;
247
- margin-top: 24px;
248
- border: 1px solid #E5E7EB;
249
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
250
  }
251
 
252
  .empty-state, .error-state {
253
  text-align: center;
254
- padding: 60px 40px;
255
  }
256
 
257
  .empty-icon, .error-icon {
258
- color: #9CA3AF;
259
- margin-bottom: 20px;
260
  display: flex;
261
  justify-content: center;
 
262
  }
263
 
264
  .empty-state h3, .error-state h3 {
265
- color: #1F2937;
266
- font-size: 20px;
267
- font-weight: 600;
268
- margin: 0 0 8px 0;
 
269
  }
270
 
271
  .empty-state p, .error-state p {
272
- color: #6B7280;
273
- font-size: 15px;
274
  margin: 0;
 
275
  }
276
 
277
  .success-state {
278
- animation: slideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
279
  }
280
 
281
  @keyframes slideIn {
282
  from {
283
  opacity: 0;
284
- transform: translateY(20px);
285
  }
286
  to {
287
  opacity: 1;
@@ -290,139 +345,217 @@ button.primary:active {
290
  }
291
 
292
  .result-header {
293
- border-bottom: 1px solid #F3F4F6;
294
- padding-bottom: 24px;
295
- margin-bottom: 28px;
296
  }
297
 
298
  .dataset-title {
299
- color: #111827;
300
- margin: 0 0 8px 0;
301
- font-size: 26px;
302
- font-weight: 700;
303
- letter-spacing: -0.5px;
 
304
  }
305
 
306
  .dataset-author {
307
- color: #6B7280;
308
  margin: 0;
309
- font-size: 15px;
310
- font-weight: 500;
311
  }
312
 
313
  .stats-grid {
314
  display: grid;
315
  grid-template-columns: repeat(2, 1fr);
316
- gap: 16px;
317
- margin-bottom: 32px;
318
  }
319
 
320
  .stat-card {
321
- padding: 20px;
322
- border-radius: 12px;
323
- text-align: center;
324
- transition: transform 0.2s ease;
 
 
 
325
  }
326
 
327
  .stat-card:hover {
328
- transform: translateY(-2px);
 
 
 
 
 
 
 
 
 
 
329
  }
330
 
331
- .stat-primary {
332
- background: linear-gradient(135deg, #1E3A8A 0%, #1E40AF 100%);
 
 
 
 
 
 
 
 
 
 
333
  }
334
 
335
- .stat-secondary {
336
- background: linear-gradient(135deg, #0891B2 0%, #06B6D4 100%);
337
  }
338
 
339
  .stat-label {
340
- color: rgba(255, 255, 255, 0.85);
341
  font-size: 13px;
342
  margin-bottom: 6px;
343
- font-weight: 500;
344
  text-transform: uppercase;
345
- letter-spacing: 0.5px;
 
346
  }
347
 
348
  .stat-value {
349
- color: white;
350
- font-size: 28px;
351
- font-weight: 700;
352
  }
353
 
354
- .description-section, .tags-section {
355
- margin-bottom: 28px;
356
  }
357
 
358
- .description-section h3, .tags-section h3 {
359
- color: #111827;
360
- font-size: 16px;
361
- font-weight: 600;
362
- margin: 0 0 12px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  }
364
 
365
- .description-section p {
366
- color: #4B5563;
367
- line-height: 1.7;
368
  font-size: 15px;
369
  margin: 0;
 
370
  }
371
 
372
  .tags-container {
373
  display: flex;
374
  flex-wrap: wrap;
375
- gap: 8px;
376
  }
377
 
378
  .tag {
379
  display: inline-block;
380
- background: #EFF6FF;
381
  color: #1E40AF;
382
- padding: 6px 14px;
383
- border-radius: 20px;
384
  font-size: 13px;
385
- font-weight: 500;
386
- border: 1px solid #DBEAFE;
 
387
  }
388
 
389
- .no-tags {
390
- color: #9CA3AF;
391
- font-size: 14px;
392
  }
393
 
394
  .view-button {
395
  display: inline-flex;
396
  align-items: center;
397
- gap: 8px;
398
- background: linear-gradient(135deg, #1E3A8A 0%, #1E40AF 100%);
399
  color: white;
400
- padding: 14px 28px;
401
- border-radius: 10px;
402
  text-decoration: none;
403
- font-weight: 600;
404
- font-size: 15px;
405
- transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
406
- box-shadow: 0 2px 8px rgba(30, 58, 138, 0.25);
 
407
  }
408
 
409
  .view-button:hover {
410
- transform: translateY(-2px);
411
- box-shadow: 0 4px 12px rgba(30, 58, 138, 0.35);
412
  text-decoration: none;
 
 
 
 
 
 
 
 
 
413
  }
414
 
415
  .footer-note {
416
  text-align: center;
417
- color: #6B7280;
418
- font-size: 14px;
419
- margin-top: 32px;
420
- padding: 20px;
421
- font-weight: 400;
422
  }
423
  """
424
 
425
- with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.Soft()) as app:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  gr.HTML("""
427
  <div class='header-section'>
428
  <h1 class='main-title'>Random Dataset Picker</h1>
@@ -431,20 +564,22 @@ with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.So
431
  """)
432
 
433
  with gr.Group():
434
- gr.HTML("<div class='filter-container'><span class='filter-label'>Filter Options</span></div>")
435
 
436
  with gr.Row():
437
  min_likes = gr.Number(
438
  label="Minimum Likes",
439
  precision=0,
440
  container=True,
441
- scale=1
 
442
  )
443
  max_likes = gr.Number(
444
  label="Maximum Likes",
445
  precision=0,
446
  container=True,
447
- scale=1
 
448
  )
449
 
450
  with gr.Row():
@@ -452,28 +587,30 @@ with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.So
452
  label="Task Category",
453
  placeholder="e.g., text-classification, image-classification",
454
  container=True,
455
- scale=1
 
456
  )
457
  language = gr.Textbox(
458
  label="Language Code",
459
  placeholder="e.g., en, fr, de, zh",
460
  container=True,
461
- scale=1
 
462
  )
463
 
464
- btn = gr.Button("Generate Random Dataset", variant="primary", size="lg", elem_classes=["generate-btn"])
465
 
466
  output = gr.HTML(
467
  value="""<div class='result-container empty-state'>
468
  <div class='empty-icon'>
469
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
470
  <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
471
  <polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
472
  <line x1="12" y1="22.08" x2="12" y2="12"/>
473
  </svg>
474
  </div>
475
  <h3>Ready to Explore</h3>
476
- <p>Click the button above to discover a random dataset</p>
477
  </div>"""
478
  )
479
 
@@ -483,15 +620,6 @@ with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.So
483
  outputs=output
484
  )
485
 
486
- gr.HTML("<div class='footer-note'>All filters are optional — Leave empty for completely random selection</div>")
487
-
488
- gr.HTML("""
489
- <script>
490
- document.querySelector('.generate-btn').addEventListener('click', function() {{
491
- const audio = new Audio('https://assets.mixkit.co/active_storage/sfx/2568/2568-preview.mp3');
492
- audio.play().catch(() => {{}});
493
- }});
494
- </script>
495
- """)
496
 
497
  app.launch()
 
5
  def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None):
6
  try:
7
  url = "https://huggingface.co/api/datasets"
8
+ params = {"full": "true"}
9
 
10
  if task and task.strip():
11
  params["filter"] = task.strip()
 
14
  response.raise_for_status()
15
  datasets = response.json()
16
 
17
+ if not datasets:
18
+ return """
19
+ <div class='result-container empty-state'>
20
+ <div class='empty-icon'>
21
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
22
+ <circle cx="12" cy="12" r="10"/>
23
+ <path d="M12 6v6l4 2"/>
24
+ </svg>
25
+ </div>
26
+ <h3>No Datasets Found</h3>
27
+ <p>Unable to fetch datasets. Please try again.</p>
28
+ </div>
29
+ """
30
+
31
  filtered = []
32
  for ds in datasets:
33
  likes = ds.get("likes", 0)
34
 
35
+ if min_likes is not None and min_likes > 0 and likes < min_likes:
36
  continue
37
+ if max_likes is not None and max_likes > 0 and likes > max_likes:
38
  continue
39
 
40
  if language and language.strip():
 
50
  return """
51
  <div class='result-container empty-state'>
52
  <div class='empty-icon'>
53
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
54
  <circle cx="12" cy="12" r="10"/>
55
+ <line x1="12" y1="8" x2="12" y2="12"/>
56
+ <line x1="12" y1="16" x2="12.01" y2="16"/>
57
  </svg>
58
  </div>
59
  <h3>No Results Found</h3>
60
+ <p>Try adjusting your filters or leave them empty for any dataset</p>
61
  </div>
 
 
 
62
  """
63
 
64
  dataset = random.choice(filtered)
 
72
  tags_html = ''.join([f"<span class='tag'>{tag}</span>" for tag in tags])
73
 
74
  result = f"""
75
+ <div class='result-container success-state' id='result-card'>
76
  <div class='result-header'>
77
  <h2 class='dataset-title'>{dataset_id}</h2>
78
  <p class='dataset-author'>by {author}</p>
79
  </div>
80
 
81
  <div class='stats-grid'>
82
+ <div class='stat-card stat-likes'>
83
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class='stat-icon'>
84
+ <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
85
+ </svg>
86
+ <div class='stat-content'>
87
+ <div class='stat-label'>Likes</div>
88
+ <div class='stat-value'>{likes:,}</div>
89
+ </div>
90
  </div>
91
+ <div class='stat-card stat-downloads'>
92
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class='stat-icon'>
93
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
94
+ <polyline points="7 10 12 15 17 10"/>
95
+ <line x1="12" y1="15" x2="12" y2="3"/>
96
+ </svg>
97
+ <div class='stat-content'>
98
+ <div class='stat-label'>Downloads</div>
99
+ <div class='stat-value'>{downloads:,}</div>
100
+ </div>
101
  </div>
102
  </div>
103
 
104
+ <div class='info-section'>
105
+ <div class='section-header'>
106
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
107
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
108
+ <polyline points="14 2 14 8 20 8"/>
109
+ <line x1="16" y1="13" x2="8" y2="13"/>
110
+ <line x1="16" y1="17" x2="8" y2="17"/>
111
+ <polyline points="10 9 9 9 8 9"/>
112
+ </svg>
113
+ <h3>Description</h3>
114
+ </div>
115
+ <p class='description-text'>{description[:450]}{'...' if len(description) > 450 else ''}</p>
116
  </div>
117
 
118
+ {f'''<div class='info-section'>
119
+ <div class='section-header'>
120
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
121
+ <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/>
122
+ <line x1="7" y1="7" x2="7.01" y2="7"/>
123
+ </svg>
124
+ <h3>Tags</h3>
125
+ </div>
126
+ <div class='tags-container'>{tags_html}</div>
127
+ </div>''' if tags else ''}
128
 
129
  <a href='https://huggingface.co/datasets/{dataset_id}' target='_blank' class='view-button'>
130
+ <span>View on HuggingFace</span>
131
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
132
  <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
133
  <polyline points="15 3 21 3 21 9"/>
134
  <line x1="10" y1="14" x2="21" y2="3"/>
135
  </svg>
136
  </a>
137
  </div>
 
 
 
138
  """
139
  return result
140
 
 
142
  return f"""
143
  <div class='result-container error-state'>
144
  <div class='error-icon'>
145
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
146
  <circle cx="12" cy="12" r="10"/>
147
  <line x1="15" y1="9" x2="9" y2="15"/>
148
  <line x1="9" y1="9" x2="15" y2="15"/>
 
151
  <h3>Error</h3>
152
  <p>{str(e)}</p>
153
  </div>
 
 
 
154
  """
155
 
156
  custom_css = """
157
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
158
 
159
  * {
160
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
161
  }
162
 
163
  .gradio-container {
164
+ max-width: 980px !important;
165
  margin: 0 auto !important;
166
+ padding: 0 20px !important;
167
  }
168
 
169
  body {
170
+ background: linear-gradient(180deg, #F8FAFC 0%, #F1F5F9 100%);
171
  }
172
 
173
  .header-section {
174
  text-align: center;
175
+ padding: 72px 32px 56px;
176
+ background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #334155 100%);
177
+ border-radius: 24px;
178
+ margin: 40px 0;
179
  position: relative;
180
  overflow: hidden;
181
+ box-shadow: 0 20px 60px rgba(15, 23, 42, 0.4);
182
  }
183
 
184
  .header-section::before {
185
  content: '';
186
  position: absolute;
187
+ top: -50%;
188
+ left: -50%;
189
+ width: 200%;
190
+ height: 200%;
191
+ background: radial-gradient(circle, rgba(59, 130, 246, 0.15) 0%, transparent 70%);
192
+ animation: pulse 8s ease-in-out infinite;
193
+ }
194
+
195
+ @keyframes pulse {
196
+ 0%, 100% { transform: translate(0, 0) scale(1); }
197
+ 50% { transform: translate(10px, 10px) scale(1.1); }
198
  }
199
 
200
  .main-title {
201
  color: white;
202
+ font-size: 52px;
203
+ font-weight: 800;
204
+ margin: 0 0 16px 0;
205
+ letter-spacing: -1.5px;
206
  position: relative;
207
  z-index: 1;
208
+ text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
209
  }
210
 
211
  .main-subtitle {
212
+ color: rgba(255, 255, 255, 0.9);
213
+ font-size: 18px;
214
  margin: 0;
215
+ font-weight: 500;
216
  position: relative;
217
  z-index: 1;
218
+ letter-spacing: 0.2px;
219
  }
220
 
221
  .filter-container {
222
  background: white;
223
+ padding: 40px;
224
+ border-radius: 20px;
225
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.02);
226
+ margin-bottom: 28px;
227
+ border: 1px solid #E2E8F0;
228
  }
229
 
230
  .filter-label {
231
+ color: #0F172A;
232
+ font-size: 18px;
233
+ font-weight: 700;
234
+ margin-bottom: 28px;
235
  display: block;
236
+ letter-spacing: -0.3px;
237
  }
238
 
239
  label {
240
+ color: #334155 !important;
241
  font-size: 14px !important;
242
+ font-weight: 600 !important;
243
+ margin-bottom: 10px !important;
244
+ letter-spacing: 0.2px !important;
245
  }
246
 
247
  input[type="number"], input[type="text"] {
248
+ border: 2px solid #E2E8F0 !important;
249
+ border-radius: 12px !important;
250
+ padding: 14px 16px !important;
251
  font-size: 15px !important;
252
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;
253
+ background: #F8FAFC !important;
254
+ font-weight: 500 !important;
255
+ }
256
+
257
+ input[type="number"]:hover, input[type="text"]:hover {
258
  background: white !important;
259
+ border-color: #CBD5E1 !important;
260
  }
261
 
262
  input[type="number"]:focus, input[type="text"]:focus {
263
  border-color: #3B82F6 !important;
264
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1) !important;
265
  outline: none !important;
266
+ background: white !important;
267
  }
268
 
269
  button.primary {
270
+ background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%) !important;
271
  border: none !important;
272
  color: white !important;
273
+ font-size: 17px !important;
274
+ font-weight: 700 !important;
275
+ padding: 18px 48px !important;
276
+ border-radius: 14px !important;
277
  cursor: pointer !important;
278
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
279
+ box-shadow: 0 8px 24px rgba(15, 23, 42, 0.35) !important;
280
  width: 100% !important;
281
+ margin-top: 12px !important;
282
+ letter-spacing: 0.3px !important;
283
  }
284
 
285
  button.primary:hover {
286
+ transform: translateY(-3px) !important;
287
+ box-shadow: 0 12px 32px rgba(15, 23, 42, 0.45) !important;
288
+ background: linear-gradient(135deg, #1E293B 0%, #334155 100%) !important;
289
  }
290
 
291
  button.primary:active {
292
+ transform: translateY(-1px) !important;
293
  }
294
 
295
  .result-container {
296
  background: white;
297
+ border-radius: 20px;
298
+ padding: 48px;
299
+ margin-top: 28px;
300
+ border: 1px solid #E2E8F0;
301
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.02);
302
  }
303
 
304
  .empty-state, .error-state {
305
  text-align: center;
306
+ padding: 80px 40px;
307
  }
308
 
309
  .empty-icon, .error-icon {
310
+ color: #94A3B8;
311
+ margin-bottom: 24px;
312
  display: flex;
313
  justify-content: center;
314
+ opacity: 0.7;
315
  }
316
 
317
  .empty-state h3, .error-state h3 {
318
+ color: #0F172A;
319
+ font-size: 24px;
320
+ font-weight: 700;
321
+ margin: 0 0 12px 0;
322
+ letter-spacing: -0.5px;
323
  }
324
 
325
  .empty-state p, .error-state p {
326
+ color: #64748B;
327
+ font-size: 16px;
328
  margin: 0;
329
+ font-weight: 500;
330
  }
331
 
332
  .success-state {
333
+ animation: slideIn 0.5s cubic-bezier(0.16, 1, 0.3, 1);
334
  }
335
 
336
  @keyframes slideIn {
337
  from {
338
  opacity: 0;
339
+ transform: translateY(30px);
340
  }
341
  to {
342
  opacity: 1;
 
345
  }
346
 
347
  .result-header {
348
+ border-bottom: 2px solid #F1F5F9;
349
+ padding-bottom: 28px;
350
+ margin-bottom: 36px;
351
  }
352
 
353
  .dataset-title {
354
+ color: #0F172A;
355
+ margin: 0 0 10px 0;
356
+ font-size: 32px;
357
+ font-weight: 800;
358
+ letter-spacing: -1px;
359
+ line-height: 1.2;
360
  }
361
 
362
  .dataset-author {
363
+ color: #64748B;
364
  margin: 0;
365
+ font-size: 16px;
366
+ font-weight: 600;
367
  }
368
 
369
  .stats-grid {
370
  display: grid;
371
  grid-template-columns: repeat(2, 1fr);
372
+ gap: 20px;
373
+ margin-bottom: 40px;
374
  }
375
 
376
  .stat-card {
377
+ padding: 28px;
378
+ border-radius: 16px;
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 20px;
382
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
383
+ border: 2px solid transparent;
384
  }
385
 
386
  .stat-card:hover {
387
+ transform: translateY(-4px);
388
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
389
+ }
390
+
391
+ .stat-likes {
392
+ background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
393
+ color: white;
394
+ }
395
+
396
+ .stat-likes:hover {
397
+ border-color: #FCA5A5;
398
  }
399
 
400
+ .stat-downloads {
401
+ background: linear-gradient(135deg, #06B6D4 0%, #0891B2 100%);
402
+ color: white;
403
+ }
404
+
405
+ .stat-downloads:hover {
406
+ border-color: #67E8F9;
407
+ }
408
+
409
+ .stat-icon {
410
+ flex-shrink: 0;
411
+ opacity: 0.9;
412
  }
413
 
414
+ .stat-content {
415
+ flex: 1;
416
  }
417
 
418
  .stat-label {
 
419
  font-size: 13px;
420
  margin-bottom: 6px;
421
+ font-weight: 600;
422
  text-transform: uppercase;
423
+ letter-spacing: 1px;
424
+ opacity: 0.9;
425
  }
426
 
427
  .stat-value {
428
+ font-size: 32px;
429
+ font-weight: 800;
430
+ letter-spacing: -1px;
431
  }
432
 
433
+ .info-section {
434
+ margin-bottom: 36px;
435
  }
436
 
437
+ .section-header {
438
+ display: flex;
439
+ align-items: center;
440
+ gap: 10px;
441
+ margin-bottom: 16px;
442
+ }
443
+
444
+ .section-header svg {
445
+ color: #3B82F6;
446
+ flex-shrink: 0;
447
+ }
448
+
449
+ .section-header h3 {
450
+ color: #0F172A;
451
+ font-size: 18px;
452
+ font-weight: 700;
453
+ margin: 0;
454
+ letter-spacing: -0.3px;
455
  }
456
 
457
+ .description-text {
458
+ color: #475569;
459
+ line-height: 1.8;
460
  font-size: 15px;
461
  margin: 0;
462
+ font-weight: 500;
463
  }
464
 
465
  .tags-container {
466
  display: flex;
467
  flex-wrap: wrap;
468
+ gap: 10px;
469
  }
470
 
471
  .tag {
472
  display: inline-block;
473
+ background: linear-gradient(135deg, #DBEAFE 0%, #BFDBFE 100%);
474
  color: #1E40AF;
475
+ padding: 8px 18px;
476
+ border-radius: 24px;
477
  font-size: 13px;
478
+ font-weight: 600;
479
+ border: 2px solid #93C5FD;
480
+ transition: all 0.2s ease;
481
  }
482
 
483
+ .tag:hover {
484
+ transform: translateY(-2px);
485
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
486
  }
487
 
488
  .view-button {
489
  display: inline-flex;
490
  align-items: center;
491
+ gap: 12px;
492
+ background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%);
493
  color: white;
494
+ padding: 16px 36px;
495
+ border-radius: 12px;
496
  text-decoration: none;
497
+ font-weight: 700;
498
+ font-size: 16px;
499
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
500
+ box-shadow: 0 6px 20px rgba(15, 23, 42, 0.3);
501
+ letter-spacing: 0.2px;
502
  }
503
 
504
  .view-button:hover {
505
+ transform: translateY(-3px);
506
+ box-shadow: 0 10px 28px rgba(15, 23, 42, 0.4);
507
  text-decoration: none;
508
+ background: linear-gradient(135deg, #1E293B 0%, #334155 100%);
509
+ }
510
+
511
+ .view-button svg {
512
+ transition: transform 0.3s ease;
513
+ }
514
+
515
+ .view-button:hover svg {
516
+ transform: translateX(3px);
517
  }
518
 
519
  .footer-note {
520
  text-align: center;
521
+ color: #64748B;
522
+ font-size: 15px;
523
+ margin-top: 36px;
524
+ padding: 24px;
525
+ font-weight: 500;
526
  }
527
  """
528
 
529
+ js_code = """
530
+ function playSound(url) {
531
+ const audio = new Audio(url);
532
+ audio.volume = 0.3;
533
+ audio.play().catch(e => console.log('Audio play failed:', e));
534
+ }
535
+
536
+ document.addEventListener('DOMContentLoaded', function() {
537
+ const observer = new MutationObserver(function(mutations) {
538
+ mutations.forEach(function(mutation) {
539
+ if (mutation.addedNodes.length) {
540
+ mutation.addedNodes.forEach(function(node) {
541
+ if (node.classList && node.classList.contains('success-state')) {
542
+ playSound('https://assets.mixkit.co/active_storage/sfx/2568/2568-preview.mp3');
543
+ }
544
+ });
545
+ }
546
+ });
547
+ });
548
+
549
+ setTimeout(() => {
550
+ const outputDiv = document.querySelector('.gradio-html');
551
+ if (outputDiv) {
552
+ observer.observe(outputDiv, { childList: true, subtree: true });
553
+ }
554
+ }, 1000);
555
+ });
556
+ """
557
+
558
+ with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.Soft(), js=js_code) as app:
559
  gr.HTML("""
560
  <div class='header-section'>
561
  <h1 class='main-title'>Random Dataset Picker</h1>
 
564
  """)
565
 
566
  with gr.Group():
567
+ gr.HTML("<div class='filter-container'><span class='filter-label'>Optional Filters</span></div>")
568
 
569
  with gr.Row():
570
  min_likes = gr.Number(
571
  label="Minimum Likes",
572
  precision=0,
573
  container=True,
574
+ scale=1,
575
+ value=None
576
  )
577
  max_likes = gr.Number(
578
  label="Maximum Likes",
579
  precision=0,
580
  container=True,
581
+ scale=1,
582
+ value=None
583
  )
584
 
585
  with gr.Row():
 
587
  label="Task Category",
588
  placeholder="e.g., text-classification, image-classification",
589
  container=True,
590
+ scale=1,
591
+ value=""
592
  )
593
  language = gr.Textbox(
594
  label="Language Code",
595
  placeholder="e.g., en, fr, de, zh",
596
  container=True,
597
+ scale=1,
598
+ value=""
599
  )
600
 
601
+ btn = gr.Button("Generate Random Dataset", variant="primary", size="lg")
602
 
603
  output = gr.HTML(
604
  value="""<div class='result-container empty-state'>
605
  <div class='empty-icon'>
606
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
607
  <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
608
  <polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
609
  <line x1="12" y1="22.08" x2="12" y2="12"/>
610
  </svg>
611
  </div>
612
  <h3>Ready to Explore</h3>
613
+ <p>Click the button above to discover a genuinely random dataset</p>
614
  </div>"""
615
  )
616
 
 
620
  outputs=output
621
  )
622
 
623
+ gr.HTML("<div class='footer-note'>All filters are optional — Leave empty for genuinely random selection from all datasets</div>")
 
 
 
 
 
 
 
 
 
624
 
625
  app.launch()