openfree commited on
Commit
f3e82a2
ยท
verified ยท
1 Parent(s): cc9e632

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -10
app.py CHANGED
@@ -1,13 +1,18 @@
1
- import os, json, time, datetime, requests, gradio as gr, re
 
 
 
2
 
3
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 1. ๊ธฐ๋ณธ ์„ค์ • โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
4
- BEST_FILE, PER_PAGE = "best_games.json", 9 # โถ ํŽ˜์ด์ง€๋‹น 9๊ฐœ ์œ ์ง€
 
5
 
6
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 2. BEST ๋ฐ์ดํ„ฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
7
  def _init_best():
8
  if not os.path.exists(BEST_FILE):
9
  json.dump([], open(BEST_FILE, "w"), ensure_ascii=False)
10
 
 
11
  def _load_best():
12
  try:
13
  raw = json.load(open(BEST_FILE))
@@ -19,7 +24,8 @@ def _load_best():
19
  print("BEST ๋กœ๋“œ ์˜ค๋ฅ˜:", e)
20
  return []
21
 
22
- def _save_best(lst): # URLโ€†๋ฆฌ์ŠคํŠธ ์ €์žฅ
 
23
  try:
24
  json.dump(lst, open(BEST_FILE, "w"), ensure_ascii=False, indent=2)
25
  return True
@@ -27,19 +33,35 @@ def _save_best(lst): # URLโ€†๋ฆฌ์ŠคํŠธ ์ €์žฅ
27
  print("BEST ์ €์žฅ ์˜ค๋ฅ˜:", e)
28
  return False
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  def add_url_to_best(url: str):
 
31
  data = _load_best()
32
  if url in data:
33
  return False
34
  data.insert(0, url)
35
  return _save_best(data)
36
 
 
37
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 3. ์œ ํ‹ธ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
  def page(lst, pg):
39
- s, e = (pg-1)*PER_PAGE, (pg-1)*PER_PAGE+PER_PAGE
40
- total = (len(lst)+PER_PAGE-1)//PER_PAGE
41
  return lst[s:e], total
42
 
 
43
  def process_url_for_iframe(url):
44
  """
45
  ๋ฐ˜ํ™˜: (iframe_url, extra_class, alternate_urls)
@@ -60,10 +82,14 @@ def process_url_for_iframe(url):
60
 
61
  return url, "", []
62
 
 
63
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 6. HTML ๊ทธ๋ฆฌ๋“œ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
64
  def html(cards, pg, total):
65
  if not cards:
66
- return "<div style='text-align:center;padding:70px;color:#555;'>ํ‘œ์‹œํ•  ๋ฐฐํฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</div>"
 
 
 
67
 
68
  css = r"""
69
  <style>
@@ -120,8 +146,9 @@ def html(cards, pg, total):
120
  for idx, url in enumerate(cards):
121
  iframe_url, extra_cls, alt_urls = process_url_for_iframe(url)
122
  frame_class = f"frame {extra_cls}".strip()
123
- iframe_id = f"iframe-{idx}-{hash(url)%10000}"
124
  alt_attr = f'data-alternate-urls="{",".join(alt_urls)}"' if alt_urls else ""
 
125
  h += f"""
126
  <div class="card">
127
  <div class="{frame_class}">
@@ -129,7 +156,11 @@ def html(cards, pg, total):
129
  sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"
130
  data-original-url="{url}" {alt_attr}></iframe>
131
  </div>
132
- <div class="foot"><a href="{url}" target="_blank">โ†— Open in Full Screen (New Tab)</a></div>
 
 
 
 
133
  </div>"""
134
  h += "</div></div>"
135
  h += f'<div class="page-info">Page {pg} / {total}</div>'
@@ -183,13 +214,14 @@ def build():
183
  data, tot = page(_load_best(), p)
184
  return html(data, p, tot), p
185
 
186
- b_prev.click(lambda p: render(max(1, p-1)), inputs=bp, outputs=[out, bp])
187
- b_next.click(lambda p: render(p+1), inputs=bp, outputs=[out, bp])
188
 
189
  demo.load(render, outputs=[out, bp])
190
 
191
  return demo
192
 
 
193
  app = build()
194
 
195
  if __name__ == "__main__":
 
1
+ import os
2
+ import json
3
+ import re
4
+ import gradio as gr
5
 
6
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 1. ๊ธฐ๋ณธ ์„ค์ • โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
7
+ BEST_FILE, PER_PAGE = "best_games.json", 9 # โถ ํŽ˜์ด์ง€๋‹น 9๊ฐœ ์œ ์ง€
8
+
9
 
10
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 2. BEST ๋ฐ์ดํ„ฐ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
11
  def _init_best():
12
  if not os.path.exists(BEST_FILE):
13
  json.dump([], open(BEST_FILE, "w"), ensure_ascii=False)
14
 
15
+
16
  def _load_best():
17
  try:
18
  raw = json.load(open(BEST_FILE))
 
24
  print("BEST ๋กœ๋“œ ์˜ค๋ฅ˜:", e)
25
  return []
26
 
27
+
28
+ def _save_best(lst): # URLโ€†๋ฆฌ์ŠคํŠธ ์ €์žฅ
29
  try:
30
  json.dump(lst, open(BEST_FILE, "w"), ensure_ascii=False, indent=2)
31
  return True
 
33
  print("BEST ์ €์žฅ ์˜ค๋ฅ˜:", e)
34
  return False
35
 
36
+
37
+ def to_hub_space_url(url: str) -> str:
38
+ """
39
+ *.hf.space URL์„ https://huggingface.co/spaces/<owner>/<space> ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜
40
+ ๋‹ค๋ฅธ URL์€ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
41
+ """
42
+ m = re.match(r"https?://([^-]+)-([^.]+)\.hf\.space(/.*)?", url)
43
+ if m:
44
+ owner, space, _ = m.groups()
45
+ return f"https://huggingface.co/spaces/{owner}/{space}"
46
+ return url
47
+
48
+
49
  def add_url_to_best(url: str):
50
+ # ์ €์žฅํ•  ๋•Œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ค€ ์›๋ณธ์„ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค
51
  data = _load_best()
52
  if url in data:
53
  return False
54
  data.insert(0, url)
55
  return _save_best(data)
56
 
57
+
58
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 3. ์œ ํ‹ธ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
59
  def page(lst, pg):
60
+ s, e = (pg - 1) * PER_PAGE, (pg - 1) * PER_PAGE + PER_PAGE
61
+ total = (len(lst) + PER_PAGE - 1) // PER_PAGE
62
  return lst[s:e], total
63
 
64
+
65
  def process_url_for_iframe(url):
66
  """
67
  ๋ฐ˜ํ™˜: (iframe_url, extra_class, alternate_urls)
 
82
 
83
  return url, "", []
84
 
85
+
86
  # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 6. HTML ๊ทธ๋ฆฌ๋“œ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
87
  def html(cards, pg, total):
88
  if not cards:
89
+ return (
90
+ "<div style='text-align:center;padding:70px;color:#555;'>"
91
+ "ํ‘œ์‹œํ•  ๋ฐฐํฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</div>"
92
+ )
93
 
94
  css = r"""
95
  <style>
 
146
  for idx, url in enumerate(cards):
147
  iframe_url, extra_cls, alt_urls = process_url_for_iframe(url)
148
  frame_class = f"frame {extra_cls}".strip()
149
+ iframe_id = f"iframe-{idx}-{hash(url) % 10000}"
150
  alt_attr = f'data-alternate-urls="{",".join(alt_urls)}"' if alt_urls else ""
151
+ safe_url = to_hub_space_url(url) # ์ƒˆ ํƒญ ๋งํฌ์šฉ ๋ณ€ํ™˜ URL
152
  h += f"""
153
  <div class="card">
154
  <div class="{frame_class}">
 
156
  sandbox="allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-downloads"
157
  data-original-url="{url}" {alt_attr}></iframe>
158
  </div>
159
+ <div class="foot">
160
+ <a href="{safe_url}" target="_blank" rel="noopener noreferrer">
161
+ โ†— Open in Full Screen (New Tab)
162
+ </a>
163
+ </div>
164
  </div>"""
165
  h += "</div></div>"
166
  h += f'<div class="page-info">Page {pg} / {total}</div>'
 
214
  data, tot = page(_load_best(), p)
215
  return html(data, p, tot), p
216
 
217
+ b_prev.click(lambda p: render(max(1, p - 1)), inputs=bp, outputs=[out, bp])
218
+ b_next.click(lambda p: render(p + 1), inputs=bp, outputs=[out, bp])
219
 
220
  demo.load(render, outputs=[out, bp])
221
 
222
  return demo
223
 
224
+
225
  app = build()
226
 
227
  if __name__ == "__main__":