openfree commited on
Commit
9c9698b
โ€ข
1 Parent(s): f79dac7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -70
app.py CHANGED
@@ -6,29 +6,35 @@ from selenium import webdriver
6
  from selenium.common.exceptions import WebDriverException
7
  from PIL import Image
8
  from io import BytesIO
 
9
 
10
  def take_screenshot(url):
11
  """์›น์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฐ์ƒท ์ดฌ์˜ ํ•จ์ˆ˜"""
 
 
 
12
  options = webdriver.ChromeOptions()
13
  options.add_argument('--headless')
14
  options.add_argument('--no-sandbox')
15
  options.add_argument('--disable-dev-shm-usage')
 
16
 
17
  try:
18
  driver = webdriver.Chrome(options=options)
19
- driver.set_window_size(1080, 720) # ์Šคํฌ๋ฆฐ์ƒท ํฌ๊ธฐ ์„ค์ •
20
  driver.get(url)
21
  driver.implicitly_wait(10)
22
  screenshot = driver.get_screenshot_as_png()
23
- return Image.open(BytesIO(screenshot))
 
 
 
24
  except WebDriverException as e:
25
  print(f"์Šคํฌ๋ฆฐ์ƒท ์ดฌ์˜ ์‹คํŒจ: {str(e)}")
26
- return Image.new('RGB', (1, 1)) # ์˜ค๋ฅ˜ ์‹œ ๋นˆ ์ด๋ฏธ์ง€ ๋ฐ˜ํ™˜
27
  finally:
28
- if driver:
29
  driver.quit()
30
 
31
-
32
  USERNAME = "openfree"
33
 
34
  def format_timestamp(timestamp):
@@ -279,7 +285,7 @@ def get_vercel_deployments():
279
  print(f"Error fetching Vercel deployments: {str(e)}")
280
  return []
281
 
282
- def get_vercel_card(deployment, index):
283
  """Vercel ๋ฐฐํฌ ์นด๋“œ HTML ์ƒ์„ฑ ํ•จ์ˆ˜"""
284
  raw_url = deployment.get('url', '')
285
 
@@ -295,61 +301,27 @@ def get_vercel_card(deployment, index):
295
 
296
  # ์นด๋“œ ID ์ƒ์„ฑ
297
  card_id = f"vercel-card-{url.replace('.', '-').replace('/', '-')}"
298
-
299
-
300
- # ์Šคํฌ๋ฆฐ์ƒท ์ด๋ฏธ์ง€ ๊ฐ€์ ธ์˜ค๊ธฐ
301
- try:
302
- screenshot = take_screenshot(url)
303
- screenshot_html = f"""
304
- <div style="width: 100%; height: 200px; overflow: hidden; border-radius: 10px; margin-bottom: 15px;">
305
- <img src="data:image/png;base64,{screenshot}"
306
- style="width: 100%; height: 100%; object-fit: cover;"
307
- alt="{name} ์Šคํฌ๋ฆฐ์ƒท"/>
308
- </div>
309
- """
310
- except Exception as e:
311
- print(f"์Šคํฌ๋ฆฐ์ƒท ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜: {str(e)}")
312
- screenshot_html = "" # ์˜ค๋ฅ˜ ์‹œ ์Šคํฌ๋ฆฐ์ƒท ์˜์—ญ ์ƒ๋žต
313
-
314
- # ๋‚˜๋จธ์ง€ ์นด๋“œ ์Šคํƒ€์ผ๋ง ์ฝ”๋“œ๋Š” ๊ธฐ์กด๊ณผ ๋™์ผ...
315
- return f"""
316
- <div id="{card_id}" class="vercel-card"
317
- style='border: none;
318
- padding: 25px;
319
- margin: 15px;
320
- border-radius: 20px;
321
- background-color: {get_pastel_color(index)};
322
- box-shadow: 0 4px 15px rgba(0,0,0,0.1);'>
323
- {screenshot_html}
324
- <h3>{name}</h3>
325
- <div style='margin: 15px 0;'>
326
- <p>์ƒํƒœ: {state}</p>
327
- <p>์ƒ์„ฑ์ผ: {created}</p>
328
- <p>URL: <a href="{url}" target="_blank">{url}</a></p>
329
- </div>
330
- </div>
331
- """
332
-
333
- # Hugging Face ์ŠคํŽ˜์ด์Šค URL์ธ ๊ฒฝ์šฐ ์ง์ ‘ ์‚ฌ์šฉ
334
- if 'huggingface.co' in url:
335
- final_url = url
336
- else:
337
- final_url = f"https://{url}" if not url.startswith('http') else url
338
-
339
- created = format_timestamp(deployment.get('created'))
340
- name = deployment.get('name', 'Unnamed Project')
341
- state = deployment.get('state', 'N/A')
342
-
343
- # ๊ณ ์œ  ID ์ƒ์„ฑ (์นด๋“œ ์‹๋ณ„์šฉ)
344
- card_id = f"vercel-card-{url.replace('.', '-').replace('/', '-')}"
345
 
346
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
 
348
- bg_color = get_pastel_color(index + 20)
349
  tech_emojis = ['โšก', '๐Ÿš€', '๐ŸŒŸ', 'โœจ', '๐Ÿ’ซ', '๐Ÿ”ฅ', '๐ŸŒˆ', '๐ŸŽฏ', '๐ŸŽจ', '๐Ÿ”ฎ']
350
  random_emojis = random.sample(tech_emojis, 3)
351
 
352
-
353
  return f"""
354
  <div id="{card_id}" class="vercel-card"
355
  data-likes="0"
@@ -364,7 +336,7 @@ def get_vercel_card(deployment, index):
364
  overflow: hidden;'
365
  onmouseover='this.style.transform="translateY(-5px) scale(1.02)"; this.style.boxShadow="0 8px 25px rgba(0,0,0,0.15)"'
366
  onmouseout='this.style.transform="translateY(0) scale(1)"; this.style.boxShadow="0 4px 15px rgba(0,0,0,0.1)"'>
367
- <!-- ... (์ด์ „ ์ฝ”๋“œ์™€ ๋™์ผ) ... -->
368
  <h3 style='color: #2d2d2d;
369
  margin: 0 0 20px 0;
370
  font-size: 1.4em;
@@ -372,7 +344,7 @@ def get_vercel_card(deployment, index):
372
  align-items: center;
373
  gap: 10px;'>
374
  <span style='font-size: 1.3em'>{random_emojis[0]}</span>
375
- <a href='{final_url}' target='_blank'
376
  style='text-decoration: none; color: #2d2d2d;'>
377
  {name}
378
  </a>
@@ -388,7 +360,7 @@ def get_vercel_card(deployment, index):
388
  <strong>Created:</strong> ๐Ÿ“… {created}
389
  </p>
390
  <p style='margin: 8px 0;'>
391
- <strong>URL:</strong> ๐Ÿ”— https://{url}
392
  </p>
393
  </div>
394
  <div style='margin-top: 20px; display: flex; justify-content: space-between; align-items: center;'>
@@ -399,7 +371,7 @@ def get_vercel_card(deployment, index):
399
  </button>
400
  <span class="like-count" style="font-size: 1.2em; color: #666;">0</span>
401
  </div>
402
- <a href='{final_url}' target='_blank'
403
  style='background: linear-gradient(45deg, #0084ff, #00a3ff);
404
  color: white;
405
  padding: 10px 20px;
@@ -634,9 +606,8 @@ def get_user_spaces():
634
  # TOP_BEST_URLS ํ•ญ๋ชฉ ์ˆ˜
635
  top_best_count = len(TOP_BEST_URLS)
636
 
637
- # Vercel API๋ฅผ ํ†ตํ•œ ์‹ค์ œ ๋ฐฐํฌ ์ˆ˜ (๋””๋ฒ„๊น…์„ ์œ„ํ•œ ์ถœ๋ ฅ ์ถ”๊ฐ€)
638
  vercel_deployments = get_vercel_deployments()
639
- print(f"Debug - Vercel API response: {vercel_deployments}") # ๋””๋ฒ„๊น… ๋กœ๊ทธ
640
  actual_vercel_count = len(vercel_deployments) if vercel_deployments else 0
641
 
642
  html_content = f"""
@@ -659,8 +630,11 @@ def get_user_spaces():
659
  <!-- Top Best -->
660
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿ† Top Best</h3>
661
  <div style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
662
- {"".join(get_vercel_card({"url": url["url"], "created": url["created"], "name": url["name"], "state": url["state"]}, idx)
663
- for idx, url in enumerate(TOP_BEST_URLS))}
 
 
 
664
  </div>
665
 
666
  <!-- Vercel Deployments -->
@@ -731,7 +705,6 @@ def get_user_spaces():
731
  </script>
732
  """
733
 
734
-
735
  return html_content
736
 
737
  except Exception as e:
@@ -743,15 +716,14 @@ def get_user_spaces():
743
  <p>Please try again later.</p>
744
  </div>
745
  """
 
746
 
747
  # Creating the Gradio interface
748
  demo = gr.Blocks()
749
 
750
  with demo:
751
- html_output = gr.HTML(value=get_user_spaces()) # ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ ์ง์ ‘ ํ•จ์ˆ˜ ํ˜ธ์ถœ
752
 
753
  if __name__ == "__main__":
754
- demo = gr.Blocks()
755
- with demo:
756
- gr.HTML(value=get_user_spaces())
757
- demo.launch()
 
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
 
40
  def format_timestamp(timestamp):
 
285
  print(f"Error fetching Vercel deployments: {str(e)}")
286
  return []
287
 
288
+ def get_vercel_card(deployment, index, is_top_best=False):
289
  """Vercel ๋ฐฐํฌ ์นด๋“œ HTML ์ƒ์„ฑ ํ•จ์ˆ˜"""
290
  raw_url = deployment.get('url', '')
291
 
 
301
 
302
  # ์นด๋“œ ID ์ƒ์„ฑ
303
  card_id = f"vercel-card-{url.replace('.', '-').replace('/', '-')}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
+ # Top Best ํ•ญ๋ชฉ์ผ ๊ฒฝ์šฐ๋งŒ ์Šคํฌ๋ฆฐ์ƒท ์ถ”๊ฐ€
306
+ screenshot_html = ""
307
+ if is_top_best:
308
+ try:
309
+ screenshot_base64 = take_screenshot(raw_url)
310
+ if screenshot_base64:
311
+ screenshot_html = f"""
312
+ <div style="width: 100%; height: 200px; overflow: hidden; border-radius: 10px; margin-bottom: 15px;">
313
+ <img src="data:image/png;base64,{screenshot_base64}"
314
+ style="width: 100%; height: 100%; object-fit: cover;"
315
+ alt="{name} ์Šคํฌ๋ฆฐ์ƒท"/>
316
+ </div>
317
+ """
318
+ except Exception as e:
319
+ print(f"์Šคํฌ๋ฆฐ์ƒท ์ฒ˜๋ฆฌ ์˜ค๋ฅ˜: {str(e)}")
320
 
321
+ bg_color = get_pastel_color(index + (20 if not is_top_best else 0))
322
  tech_emojis = ['โšก', '๐Ÿš€', '๐ŸŒŸ', 'โœจ', '๐Ÿ’ซ', '๐Ÿ”ฅ', '๐ŸŒˆ', '๐ŸŽฏ', '๐ŸŽจ', '๐Ÿ”ฎ']
323
  random_emojis = random.sample(tech_emojis, 3)
324
 
 
325
  return f"""
326
  <div id="{card_id}" class="vercel-card"
327
  data-likes="0"
 
336
  overflow: hidden;'
337
  onmouseover='this.style.transform="translateY(-5px) scale(1.02)"; this.style.boxShadow="0 8px 25px rgba(0,0,0,0.15)"'
338
  onmouseout='this.style.transform="translateY(0) scale(1)"; this.style.boxShadow="0 4px 15px rgba(0,0,0,0.1)"'>
339
+ {screenshot_html}
340
  <h3 style='color: #2d2d2d;
341
  margin: 0 0 20px 0;
342
  font-size: 1.4em;
 
344
  align-items: center;
345
  gap: 10px;'>
346
  <span style='font-size: 1.3em'>{random_emojis[0]}</span>
347
+ <a href='{url}' target='_blank'
348
  style='text-decoration: none; color: #2d2d2d;'>
349
  {name}
350
  </a>
 
360
  <strong>Created:</strong> ๐Ÿ“… {created}
361
  </p>
362
  <p style='margin: 8px 0;'>
363
+ <strong>URL:</strong> ๐Ÿ”— {url}
364
  </p>
365
  </div>
366
  <div style='margin-top: 20px; display: flex; justify-content: space-between; align-items: center;'>
 
371
  </button>
372
  <span class="like-count" style="font-size: 1.2em; color: #666;">0</span>
373
  </div>
374
+ <a href='{url}' target='_blank'
375
  style='background: linear-gradient(45deg, #0084ff, #00a3ff);
376
  color: white;
377
  padding: 10px 20px;
 
606
  # TOP_BEST_URLS ํ•ญ๋ชฉ ์ˆ˜
607
  top_best_count = len(TOP_BEST_URLS)
608
 
609
+ # Vercel API๋ฅผ ํ†ตํ•œ ์‹ค์ œ ๋ฐฐํฌ ์ˆ˜
610
  vercel_deployments = get_vercel_deployments()
 
611
  actual_vercel_count = len(vercel_deployments) if vercel_deployments else 0
612
 
613
  html_content = f"""
 
630
  <!-- Top Best -->
631
  <h3 style='color: #333; margin: 20px 0;'>๐Ÿ† Top Best</h3>
632
  <div style='display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;'>
633
+ {"".join(get_vercel_card(
634
+ {"url": url["url"], "created": url["created"], "name": url["name"], "state": url["state"]},
635
+ idx,
636
+ is_top_best=True
637
+ ) for idx, url in enumerate(TOP_BEST_URLS))}
638
  </div>
639
 
640
  <!-- Vercel Deployments -->
 
705
  </script>
706
  """
707
 
 
708
  return html_content
709
 
710
  except Exception as e:
 
716
  <p>Please try again later.</p>
717
  </div>
718
  """
719
+
720
 
721
  # Creating the Gradio interface
722
  demo = gr.Blocks()
723
 
724
  with demo:
725
+ html_output = gr.HTML(value=get_user_spaces())
726
 
727
  if __name__ == "__main__":
728
+ demo.launch()
729
+