openfree commited on
Commit
82bb213
โ€ข
1 Parent(s): 020670e

Update app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +141 -53
app-backup.py CHANGED
@@ -2,6 +2,38 @@ import requests
2
  import gradio as gr
3
  from datetime import datetime
4
  import random
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  USERNAME = "openfree"
7
 
@@ -193,9 +225,13 @@ def get_space_card(space, index):
193
  """
194
 
195
  def get_vercel_deployments():
196
- """Vercel API๋ฅผ ํ†ตํ•ด ๋ฐฐํฌ๋œ ์„œ๋น„์Šค ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ"""
197
  token = "A8IFZmgW2cqA4yUNlLPnci0N"
198
- url = "https://api.vercel.com/v6/deployments?limit=100" # limit ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€
 
 
 
 
199
 
200
  headers = {
201
  "Authorization": f"Bearer {token}",
@@ -203,57 +239,115 @@ def get_vercel_deployments():
203
  }
204
 
205
  try:
206
- response = requests.get(url, headers=headers)
207
- if response.status_code != 200:
208
- print(f"Vercel API Error: {response.text}")
209
- return []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
- deployments = response.json().get('deployments', [])
 
 
 
212
 
213
  # ์ƒํƒœ๊ฐ€ 'READY'์ด๊ณ  'url'์ด ์žˆ๋Š” ๋ฐฐํฌ๋งŒ ํ•„ํ„ฐ๋งํ•˜๊ณ  'javis1' ์ œ์™ธ
214
  active_deployments = [
215
- dep for dep in deployments
216
  if dep.get('state') == 'READY' and
217
  dep.get('url') and
218
- 'javis1' not in dep.get('name', '').lower() # javis1 ์ œ์™ธ
219
  ]
220
 
 
221
  return active_deployments
 
222
  except Exception as e:
223
  print(f"Error fetching Vercel deployments: {str(e)}")
224
  return []
225
 
226
 
227
- def get_vercel_card(deployment, index):
228
- """Generate HTML card for a Vercel deployment with like button"""
229
  raw_url = deployment.get('url', '')
230
 
231
- # URL ์ฒ˜๋ฆฌ ๋กœ์ง ์ˆ˜์ •
232
  if raw_url.startswith('http'):
233
- url = raw_url # ์ „์ฒด URL์ด ์ œ๊ณต๋œ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
234
  else:
235
- project_name = raw_url[:6] if len(raw_url) >= 6 else raw_url
236
- url = f"{project_name}.vercel.app"
237
-
238
- # Hugging Face ์ŠคํŽ˜์ด์Šค URL์ธ ๊ฒฝ์šฐ ์ง์ ‘ ์‚ฌ์šฉ
239
- if 'huggingface.co' in url:
240
- final_url = url
241
- else:
242
- final_url = f"https://{url}" if not url.startswith('http') else url
243
 
 
244
  created = format_timestamp(deployment.get('created'))
245
- name = deployment.get('name', 'Unnamed Project')
246
  state = deployment.get('state', 'N/A')
247
 
248
- # ๊ณ ์œ  ID ์ƒ์„ฑ (์นด๋“œ ์‹๋ณ„์šฉ)
249
  card_id = f"vercel-card-{url.replace('.', '-').replace('/', '-')}"
250
 
251
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
- bg_color = get_pastel_color(index + 20)
254
  tech_emojis = ['โšก', '๐Ÿš€', '๐ŸŒŸ', 'โœจ', '๐Ÿ’ซ', '๐Ÿ”ฅ', '๐ŸŒˆ', '๐ŸŽฏ', '๐ŸŽจ', '๐Ÿ”ฎ']
255
  random_emojis = random.sample(tech_emojis, 3)
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
258
  return f"""
259
  <div id="{card_id}" class="vercel-card"
@@ -269,7 +363,7 @@ def get_vercel_card(deployment, index):
269
  overflow: hidden;'
270
  onmouseover='this.style.transform="translateY(-5px) scale(1.02)"; this.style.boxShadow="0 8px 25px rgba(0,0,0,0.15)"'
271
  onmouseout='this.style.transform="translateY(0) scale(1)"; this.style.boxShadow="0 4px 15px rgba(0,0,0,0.1)"'>
272
- <!-- ... (์ด์ „ ์ฝ”๋“œ์™€ ๋™์ผ) ... -->
273
  <h3 style='color: #2d2d2d;
274
  margin: 0 0 20px 0;
275
  font-size: 1.4em;
@@ -277,25 +371,13 @@ def get_vercel_card(deployment, index):
277
  align-items: center;
278
  gap: 10px;'>
279
  <span style='font-size: 1.3em'>{random_emojis[0]}</span>
280
- <a href='{final_url}' target='_blank'
281
  style='text-decoration: none; color: #2d2d2d;'>
282
  {name}
283
  </a>
284
  <span style='font-size: 1.3em'>{random_emojis[1]}</span>
285
  </h3>
286
-
287
- <div style='margin: 15px 0; color: #444; background: rgba(255,255,255,0.5);
288
- padding: 15px; border-radius: 12px;'>
289
- <p style='margin: 8px 0;'>
290
- <strong>Status:</strong> โœ… {state}
291
- </p>
292
- <p style='margin: 8px 0;'>
293
- <strong>Created:</strong> ๐Ÿ“… {created}
294
- </p>
295
- <p style='margin: 8px 0;'>
296
- <strong>URL:</strong> ๐Ÿ”— https://{url}
297
- </p>
298
- </div>
299
  <div style='margin-top: 20px; display: flex; justify-content: space-between; align-items: center;'>
300
  <div class="like-section" style="display: flex; align-items: center; gap: 10px;">
301
  <button onclick="toggleLike('{card_id}')" class="like-button"
@@ -304,7 +386,7 @@ def get_vercel_card(deployment, index):
304
  </button>
305
  <span class="like-count" style="font-size: 1.2em; color: #666;">0</span>
306
  </div>
307
- <a href='{final_url}' target='_blank'
308
  style='background: linear-gradient(45deg, #0084ff, #00a3ff);
309
  color: white;
310
  padding: 10px 20px;
@@ -517,7 +599,6 @@ TOP_BEST_URLS = [
517
  ]
518
 
519
 
520
-
521
  def get_user_spaces():
522
  # ๊ธฐ์กด Hugging Face ์ŠคํŽ˜์ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ
523
  url = f"https://huggingface.co/api/spaces?author={USERNAME}&limit=500"
@@ -537,11 +618,12 @@ def get_user_spaces():
537
  if not should_exclude_space(space.get('id', '').split('/')[-1])
538
  ]
539
 
540
- # Vercel ๋ฐฐํฌ ๊ฐ€์ ธ์˜ค๊ธฐ
541
- vercel_deployments = get_vercel_deployments()
542
 
543
- # ์ˆœ์ˆ˜ Vercel ๋ฐฐํฌ ์ˆ˜๋งŒ ์นด์šดํŠธ
544
- vercel_count = len(vercel_deployments) if vercel_deployments else 0
 
545
 
546
  html_content = f"""
547
  <div style='padding: 20px; background-color: #f5f5f5;'>
@@ -555,23 +637,28 @@ def get_user_spaces():
555
  </a>
556
  </p>
557
  <p style='color: #666; margin: 0;'>
558
- Found {vercel_count} Vercel deployments and {len(user_spaces)} Hugging Face spaces
 
559
  </p>
560
  </div>
561
 
562
-
563
  <!-- Top Best -->
564
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿ† Top Best</h3>
565
  <div style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
566
- {"".join(get_vercel_card({"url": url["url"], "created": url["created"], "name": url["name"], "state": url["state"]}, idx)
567
- for idx, url in enumerate(TOP_BEST_URLS))}
 
 
 
568
  </div>
569
 
570
  <!-- Vercel Deployments -->
 
571
  <h3 style='color: #333; margin: 20px 0;'>โšก Vercel Deployments</h3>
572
  <div id="vercel-container" style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
573
  {"".join(get_vercel_card(dep, idx) for idx, dep in enumerate(vercel_deployments))}
574
  </div>
 
575
 
576
  <!-- Hugging Face Spaces -->
577
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿค— Hugging Face Spaces</h3>
@@ -633,7 +720,6 @@ def get_user_spaces():
633
  </script>
634
  """
635
 
636
-
637
  return html_content
638
 
639
  except Exception as e:
@@ -645,12 +731,14 @@ def get_user_spaces():
645
  <p>Please try again later.</p>
646
  </div>
647
  """
 
648
 
649
  # Creating the Gradio interface
650
  demo = gr.Blocks()
651
 
652
  with demo:
653
- html_output = gr.HTML(value=get_user_spaces()) # ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ ์ง์ ‘ ํ•จ์ˆ˜ ํ˜ธ์ถœ
654
 
655
  if __name__ == "__main__":
656
- demo.launch()
 
 
2
  import gradio as gr
3
  from datetime import datetime
4
  import random
5
+ from selenium import webdriver
6
+ from selenium.common.exceptions import WebDriverException
7
+ from PIL import Image
8
+ from io import BytesIO
9
+ import base64
10
+
11
+ def take_screenshot(url):
12
+ """์›น์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฐ์ƒท ์ดฌ์˜ ํ•จ์ˆ˜"""
13
+ if not url.startswith('http'):
14
+ url = f"https://{url}"
15
+
16
+ options = webdriver.ChromeOptions()
17
+ options.add_argument('--headless')
18
+ options.add_argument('--no-sandbox')
19
+ options.add_argument('--disable-dev-shm-usage')
20
+ options.add_argument('--window-size=1080,720')
21
+
22
+ try:
23
+ driver = webdriver.Chrome(options=options)
24
+ driver.get(url)
25
+ driver.implicitly_wait(10)
26
+ screenshot = driver.get_screenshot_as_png()
27
+ img = Image.open(BytesIO(screenshot))
28
+ buffered = BytesIO()
29
+ img.save(buffered, format="PNG")
30
+ return base64.b64encode(buffered.getvalue()).decode()
31
+ except WebDriverException as e:
32
+ print(f"์Šคํฌ๋ฆฐ์ƒท ์ดฌ์˜ ์‹คํŒจ: {str(e)}")
33
+ return None
34
+ finally:
35
+ if 'driver' in locals():
36
+ driver.quit()
37
 
38
  USERNAME = "openfree"
39
 
 
225
  """
226
 
227
  def get_vercel_deployments():
228
+ """Vercel API๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ๋ฐฐํฌ๋œ ์„œ๋น„์Šค ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ (ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ ์šฉ)"""
229
  token = "A8IFZmgW2cqA4yUNlLPnci0N"
230
+ base_url = "https://api.vercel.com/v6/deployments"
231
+ all_deployments = []
232
+ has_next = True
233
+ page = 1
234
+ until = None # ์ฒซ ์š”์ฒญ์—์„œ๋Š” until ํŒŒ๋ผ๋ฏธํ„ฐ ์—†์Œ
235
 
236
  headers = {
237
  "Authorization": f"Bearer {token}",
 
239
  }
240
 
241
  try:
242
+ while has_next:
243
+ # URL ๊ตฌ์„ฑ (ํŽ˜์ด์ง€๋„ค์ด์…˜ ํŒŒ๋ผ๋ฏธํ„ฐ ํฌํ•จ)
244
+ url = f"{base_url}?limit=100"
245
+ if until:
246
+ url += f"&until={until}"
247
+
248
+ print(f"Fetching page {page}... URL: {url}") # ๋””๋ฒ„๊น…์šฉ
249
+
250
+ response = requests.get(url, headers=headers)
251
+ if response.status_code != 200:
252
+ print(f"Vercel API Error: {response.text}")
253
+ break
254
+
255
+ data = response.json()
256
+ current_deployments = data.get('deployments', [])
257
+
258
+ if not current_deployments: # ๋” ์ด์ƒ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด ์ข…๋ฃŒ
259
+ break
260
+
261
+ all_deployments.extend(current_deployments)
262
+
263
+ # ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ์œ„ํ•œ until ๊ฐ’ ์„ค์ •
264
+ pagination = data.get('pagination', {})
265
+ until = pagination.get('next')
266
+ has_next = bool(until) # until ๊ฐ’์ด ์žˆ์œผ๋ฉด ๋‹ค์Œ ํŽ˜์ด์ง€ ์กด์žฌ
267
 
268
+ print(f"Page {page} fetched. Got {len(current_deployments)} deployments") # ๋””๋ฒ„๊น…์šฉ
269
+ page += 1
270
+
271
+ print(f"Total deployments fetched: {len(all_deployments)}") # ๋””๋ฒ„๊น…์šฉ
272
 
273
  # ์ƒํƒœ๊ฐ€ 'READY'์ด๊ณ  'url'์ด ์žˆ๋Š” ๋ฐฐํฌ๋งŒ ํ•„ํ„ฐ๋งํ•˜๊ณ  'javis1' ์ œ์™ธ
274
  active_deployments = [
275
+ dep for dep in all_deployments
276
  if dep.get('state') == 'READY' and
277
  dep.get('url') and
278
+ 'javis1' not in dep.get('name', '').lower()
279
  ]
280
 
281
+ print(f"Active deployments after filtering: {len(active_deployments)}") # ๋””๋ฒ„๊น…์šฉ
282
  return active_deployments
283
+
284
  except Exception as e:
285
  print(f"Error fetching Vercel deployments: {str(e)}")
286
  return []
287
 
288
 
289
+ def get_vercel_card(deployment, index, is_top_best=False):
290
+ """Vercel ๋ฐฐํฌ ์นด๋“œ HTML ์ƒ์„ฑ ํ•จ์ˆ˜"""
291
  raw_url = deployment.get('url', '')
292
 
293
+ # URL ์ฒ˜๋ฆฌ
294
  if raw_url.startswith('http'):
295
+ url = raw_url
296
  else:
297
+ url = f"https://{raw_url}"
 
 
 
 
 
 
 
298
 
299
+ name = deployment.get('name', '์ด๋ฆ„ ์—†๋Š” ํ”„๋กœ์ ํŠธ')
300
  created = format_timestamp(deployment.get('created'))
 
301
  state = deployment.get('state', 'N/A')
302
 
303
+ # ์นด๋“œ ID ์ƒ์„ฑ
304
  card_id = f"vercel-card-{url.replace('.', '-').replace('/', '-')}"
305
 
306
+ # Top Best ํ•ญ๋ชฉ์ผ ๊ฒฝ์šฐ์˜ ์Šคํฌ๋ฆฐ์ƒท ์ฒ˜๋ฆฌ
307
+ screenshot_html = ""
308
+ if is_top_best:
309
+ try:
310
+ screenshot_base64 = take_screenshot(raw_url)
311
+ if screenshot_base64:
312
+ screenshot_html = f"""
313
+ <div style="width: 100%; height: 200px; overflow: hidden; border-radius: 10px; margin-bottom: 15px;">
314
+ <img src="data:image/png;base64,{screenshot_base64}"
315
+ style="width: 100%; height: 100%; object-fit: cover;"
316
+ alt="{name} ์Šคํฌ๋ฆฐ์ƒท"/>
317
+ </div>
318
+ """
319
+ except Exception as e:
320
+ print(f"์Šคํฌ๋ฆฐ์ƒท ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜: {str(e)}")
321
 
322
+ bg_color = get_pastel_color(index + (20 if not is_top_best else 0))
323
  tech_emojis = ['โšก', '๐Ÿš€', '๐ŸŒŸ', 'โœจ', '๐Ÿ’ซ', '๐Ÿ”ฅ', '๐ŸŒˆ', '๐ŸŽฏ', '๐ŸŽจ', '๐Ÿ”ฎ']
324
  random_emojis = random.sample(tech_emojis, 3)
325
 
326
+ # Top Best์™€ ์ผ๋ฐ˜ ์นด๋“œ์˜ ๋‚ด์šฉ์„ ๋‹ค๋ฅด๊ฒŒ ๊ตฌ์„ฑ
327
+ if is_top_best:
328
+ info_section = f"""
329
+ <div style='margin: 15px 0; color: #444; background: rgba(255,255,255,0.5);
330
+ padding: 15px; border-radius: 12px;'>
331
+ <p style='margin: 8px 0;'>
332
+ <strong>URL:</strong> ๐Ÿ”— {url}
333
+ </p>
334
+ </div>
335
+ """
336
+ else:
337
+ info_section = f"""
338
+ <div style='margin: 15px 0; color: #444; background: rgba(255,255,255,0.5);
339
+ padding: 15px; border-radius: 12px;'>
340
+ <p style='margin: 8px 0;'>
341
+ <strong>Status:</strong> โœ… {state}
342
+ </p>
343
+ <p style='margin: 8px 0;'>
344
+ <strong>Created:</strong> ๐Ÿ“… {created}
345
+ </p>
346
+ <p style='margin: 8px 0;'>
347
+ <strong>URL:</strong> ๐Ÿ”— {url}
348
+ </p>
349
+ </div>
350
+ """
351
 
352
  return f"""
353
  <div id="{card_id}" class="vercel-card"
 
363
  overflow: hidden;'
364
  onmouseover='this.style.transform="translateY(-5px) scale(1.02)"; this.style.boxShadow="0 8px 25px rgba(0,0,0,0.15)"'
365
  onmouseout='this.style.transform="translateY(0) scale(1)"; this.style.boxShadow="0 4px 15px rgba(0,0,0,0.1)"'>
366
+ {screenshot_html}
367
  <h3 style='color: #2d2d2d;
368
  margin: 0 0 20px 0;
369
  font-size: 1.4em;
 
371
  align-items: center;
372
  gap: 10px;'>
373
  <span style='font-size: 1.3em'>{random_emojis[0]}</span>
374
+ <a href='{url}' target='_blank'
375
  style='text-decoration: none; color: #2d2d2d;'>
376
  {name}
377
  </a>
378
  <span style='font-size: 1.3em'>{random_emojis[1]}</span>
379
  </h3>
380
+ {info_section}
 
 
 
 
 
 
 
 
 
 
 
 
381
  <div style='margin-top: 20px; display: flex; justify-content: space-between; align-items: center;'>
382
  <div class="like-section" style="display: flex; align-items: center; gap: 10px;">
383
  <button onclick="toggleLike('{card_id}')" class="like-button"
 
386
  </button>
387
  <span class="like-count" style="font-size: 1.2em; color: #666;">0</span>
388
  </div>
389
+ <a href='{url}' target='_blank'
390
  style='background: linear-gradient(45deg, #0084ff, #00a3ff);
391
  color: white;
392
  padding: 10px 20px;
 
599
  ]
600
 
601
 
 
602
  def get_user_spaces():
603
  # ๊ธฐ์กด Hugging Face ์ŠคํŽ˜์ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ
604
  url = f"https://huggingface.co/api/spaces?author={USERNAME}&limit=500"
 
618
  if not should_exclude_space(space.get('id', '').split('/')[-1])
619
  ]
620
 
621
+ # TOP_BEST_URLS ํ•ญ๋ชฉ ์ˆ˜
622
+ top_best_count = len(TOP_BEST_URLS)
623
 
624
+ # Vercel API๋ฅผ ํ†ตํ•œ ์‹ค์ œ ๋ฐฐํฌ ์ˆ˜
625
+ vercel_deployments = get_vercel_deployments()
626
+ actual_vercel_count = len(vercel_deployments) if vercel_deployments else 0
627
 
628
  html_content = f"""
629
  <div style='padding: 20px; background-color: #f5f5f5;'>
 
637
  </a>
638
  </p>
639
  <p style='color: #666; margin: 0;'>
640
+ Found {actual_vercel_count} Vercel deployments and {len(user_spaces)} Hugging Face spaces<br>
641
+ (Plus {top_best_count} featured items in Top Best section)
642
  </p>
643
  </div>
644
 
 
645
  <!-- Top Best -->
646
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿ† Top Best</h3>
647
  <div style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
648
+ {"".join(get_vercel_card(
649
+ {"url": url["url"], "created": url["created"], "name": url["name"], "state": url["state"]},
650
+ idx,
651
+ is_top_best=True
652
+ ) for idx, url in enumerate(TOP_BEST_URLS))}
653
  </div>
654
 
655
  <!-- Vercel Deployments -->
656
+ {f'''
657
  <h3 style='color: #333; margin: 20px 0;'>โšก Vercel Deployments</h3>
658
  <div id="vercel-container" style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
659
  {"".join(get_vercel_card(dep, idx) for idx, dep in enumerate(vercel_deployments))}
660
  </div>
661
+ ''' if vercel_deployments else ''}
662
 
663
  <!-- Hugging Face Spaces -->
664
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿค— Hugging Face Spaces</h3>
 
720
  </script>
721
  """
722
 
 
723
  return html_content
724
 
725
  except Exception as e:
 
731
  <p>Please try again later.</p>
732
  </div>
733
  """
734
+
735
 
736
  # Creating the Gradio interface
737
  demo = gr.Blocks()
738
 
739
  with demo:
740
+ html_output = gr.HTML(value=get_user_spaces())
741
 
742
  if __name__ == "__main__":
743
+ demo.launch()
744
+