ginipick commited on
Commit
293f472
·
verified ·
1 Parent(s): 21582cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -32
app.py CHANGED
@@ -12,7 +12,7 @@ print(f"API 토큰: {TOKEN[:4]}... (마스킹됨)")
12
  print(f"팀 ID: {TEAM if TEAM else '없음'}")
13
 
14
  # ───────────────────── 2. BEST 데이터 ────────────────────
15
- BEST_FILE, PER_PAGE = "best_games.json", 48
16
  def _init_best():
17
  if not os.path.exists(BEST_FILE):
18
  json.dump([], open(BEST_FILE, "w"))
@@ -196,9 +196,10 @@ def html(cards, pg, total):
196
  css=r"""
197
  <style>
198
  body{margin:0;font-family:Poppins,sans-serif;background:linear-gradient(135deg,#C5E8FF 0%,#FFD6E0 100%);}
199
- .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:28px 24px;margin:0 20px 60px;}
200
- @media(max-width:1024px){.grid{grid-template-columns:repeat(2,1fr);} }
201
- @media(max-width:640px){ .grid{grid-template-columns:1fr;} }
 
202
  .card{background:#fff;border-radius:18px;overflow:hidden;box-shadow:0 10px 25px rgba(0,0,0,.08);transition:.3s}
203
  .card:hover{transform:translateY(-6px);box-shadow:0 16px 40px rgba(0,0,0,.12)}
204
  .hdr{padding:20px 24px;background:rgba(255,255,255,.75);backdrop-filter:blur(8px);border-bottom:1px solid #eee;}
@@ -209,7 +210,7 @@ def html(cards, pg, total):
209
  transform:scale(.7);transform-origin:top left;border:0;}
210
  .foot{padding:14px 24px;background:rgba(255,255,255,.85);backdrop-filter:blur(8px);text-align:right;}
211
  .link{font-size:.85rem;font-weight:600;color:#4a6dd8;text-decoration:none;}
212
- .cnt{text-align:center;font-size:.85rem;color:#555;margin:10px 0 40px;}
213
  </style>"""
214
 
215
  h=css+"<div class='grid'>"
@@ -228,7 +229,7 @@ def html(cards, pg, total):
228
  # ───────────────────── 7. Gradio Blocks UI ───────────────
229
  def build():
230
  _init_best()
231
- with gr.Blocks(title="Vibe Game Craft", css="body{overflow-x:hidden;}") as demo:
232
  gr.Markdown("<h1 style='text-align:center;padding:32px 0 0;color:#333;'>🎮 Vibe Game Craft</h1>")
233
 
234
  # URL 추가 인터페이스
@@ -254,27 +255,6 @@ def build():
254
  d, t = page(_load_best(), p)
255
  return html(d, p, t), p
256
 
257
- def add_url():
258
- title = title_input.value
259
- url = url_input.value
260
-
261
- if not title or not url:
262
- return "❌ 제목과 URL을 모두 입력해주세요."
263
-
264
- if not url.startswith("http"):
265
- url = "https://" + url
266
-
267
- if add_url_to_best(title, url):
268
- return f"✅ URL이 성공적으로 추가되었습니다: {url}"
269
- else:
270
- return f"❌ URL 추가에 실패했습니다: {url}"
271
-
272
- def run_bypass():
273
- if bypass_all_protection():
274
- return "✅ 모든 프로젝트의 보호 설정이 비활성화되었습니다."
275
- else:
276
- return "❌ 일부 또는 모든 프로젝트의 보호 설정 비활성화에 실패했습니다."
277
-
278
  def prev(b):
279
  b = max(1, b-1)
280
  h, _ = show_best(b)
@@ -286,15 +266,27 @@ def build():
286
  h, _ = show_best(b)
287
  return h, b
288
 
 
 
 
 
 
289
  # 이벤트 연결
290
- add_btn.click(add_url, outputs=[status_msg])
291
- b_best.click(show_best, outputs=[out, bp])
292
  b_prev.click(prev, inputs=[bp], outputs=[out, bp])
293
  b_next.click(nxt, inputs=[bp], outputs=[out, bp])
294
- b_ref.click(lambda b: show_best(b)[0], inputs=[bp], outputs=[out])
295
- b_bypass.click(run_bypass, outputs=[status_msg])
296
 
297
- # 초기 로드
 
 
 
 
 
 
 
 
 
 
 
298
  demo.load(show_best, outputs=[out, bp])
299
  return demo
300
 
 
12
  print(f"팀 ID: {TEAM if TEAM else '없음'}")
13
 
14
  # ───────────────────── 2. BEST 데이터 ────────────────────
15
+ BEST_FILE, PER_PAGE = "best_games.json", 9
16
  def _init_best():
17
  if not os.path.exists(BEST_FILE):
18
  json.dump([], open(BEST_FILE, "w"))
 
196
  css=r"""
197
  <style>
198
  body{margin:0;font-family:Poppins,sans-serif;background:linear-gradient(135deg,#C5E8FF 0%,#FFD6E0 100%);}
199
+ .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:28px 24px;margin:0 auto;max-width:1200px;padding:20px;}
200
+ @media(max-width:1024px){.grid{grid-template-columns:repeat(3,1fr);} }
201
+ @media(max-width:768px){.grid{grid-template-columns:repeat(2,1fr);} }
202
+ @media(max-width:500px){ .grid{grid-template-columns:1fr;} }
203
  .card{background:#fff;border-radius:18px;overflow:hidden;box-shadow:0 10px 25px rgba(0,0,0,.08);transition:.3s}
204
  .card:hover{transform:translateY(-6px);box-shadow:0 16px 40px rgba(0,0,0,.12)}
205
  .hdr{padding:20px 24px;background:rgba(255,255,255,.75);backdrop-filter:blur(8px);border-bottom:1px solid #eee;}
 
210
  transform:scale(.7);transform-origin:top left;border:0;}
211
  .foot{padding:14px 24px;background:rgba(255,255,255,.85);backdrop-filter:blur(8px);text-align:right;}
212
  .link{font-size:.85rem;font-weight:600;color:#4a6dd8;text-decoration:none;}
213
+ .cnt{text-align:center;font-size:.85rem;color:#555;margin:10px 0 20px;}
214
  </style>"""
215
 
216
  h=css+"<div class='grid'>"
 
229
  # ───────────────────── 7. Gradio Blocks UI ───────────────
230
  def build():
231
  _init_best()
232
+ with gr.Blocks(title="Vibe Game Craft", css="body{overflow-x:hidden;} .gradio-container{margin:0 auto; max-width:1280px;}") as demo:
233
  gr.Markdown("<h1 style='text-align:center;padding:32px 0 0;color:#333;'>🎮 Vibe Game Craft</h1>")
234
 
235
  # URL 추가 인터페이스
 
255
  d, t = page(_load_best(), p)
256
  return html(d, p, t), p
257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  def prev(b):
259
  b = max(1, b-1)
260
  h, _ = show_best(b)
 
266
  h, _ = show_best(b)
267
  return h, b
268
 
269
+ # 페이지 네비게이션 버튼 (하단에 배치)
270
+ with gr.Row(elem_classes="navigation-buttons"):
271
+ b_prev = gr.Button("⬅️ 이전 페이지", size="sm")
272
+ b_next = gr.Button("다음 페이지 ➡️", size="sm")
273
+
274
  # 이벤트 연결
 
 
275
  b_prev.click(prev, inputs=[bp], outputs=[out, bp])
276
  b_next.click(nxt, inputs=[bp], outputs=[out, bp])
 
 
277
 
278
+ # CSS 스타일 추가
279
+ css = """
280
+ .navigation-buttons {
281
+ display: flex;
282
+ justify-content: center;
283
+ margin-bottom: 40px;
284
+ }
285
+ .navigation-buttons button {
286
+ margin: 0 10px;
287
+ min-width: 120px;
288
+ }
289
+ """
290
  demo.load(show_best, outputs=[out, bp])
291
  return demo
292