Crocody commited on
Commit
bd711e3
ยท
verified ยท
1 Parent(s): a5ce452

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -24
app.py CHANGED
@@ -9,18 +9,13 @@ HF_TOKEN = os.getenv("HF_TOKEN")
9
 
10
  api = HfApi(token=HF_TOKEN)
11
 
12
- # --- ์ž์—ฐ์–ด ์ •๋ ฌ ํ•จ์ˆ˜ (mymuse2๊ฐ€ mymuse10๋ณด๋‹ค ์•ž์— ์˜ค๋„๋ก ์„ค์ •) ---
13
  def natural_sort_key(s):
14
  return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]
15
 
16
  def get_lora_samples(sort_desc=False):
17
- """๋ฐ์ดํ„ฐ์…‹์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€ ์ž์—ฐ์–ด ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค."""
18
  try:
19
- # ์บ์‹œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์ตœ์‹  ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด list_repo_files ํ˜ธ์ถœ
20
  files = api.list_repo_files(repo_id=REPO_ID, repo_type=REPO_TYPE)
21
  samples = [f for f in files if f.startswith("LoRA_Samples/") and f.lower().endswith(('.png', '.jpg', '.jpeg'))]
22
-
23
- # ํŒŒ์ผ๋ช… ๊ธฐ์ค€ ์ •๋ ฌ ์‹คํ–‰
24
  samples.sort(key=lambda x: natural_sort_key(os.path.basename(x)), reverse=sort_desc)
25
  return samples
26
  except Exception as e:
@@ -28,20 +23,33 @@ def get_lora_samples(sort_desc=False):
28
  return []
29
 
30
  def update_gallery_data(sort_desc=False):
31
- """๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๊ฐค๋Ÿฌ๋ฆฌ ๋ฐ์ดํ„ฐ์™€ ์ƒํƒœ ๊ฐ’์„ ๋™์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•œ ๋ž˜ํผ ํ•จ์ˆ˜"""
32
  paths = get_lora_samples(sort_desc=sort_desc)
33
  gallery_val = [(hf_hub_url(repo_id=REPO_ID, repo_type=REPO_TYPE, filename=p), os.path.splitext(os.path.basename(p))[0]) for p in paths]
34
  return gallery_val, paths
35
 
36
  def generate_download_links(image_path):
37
  if not image_path:
38
- return "<div style='color: #94a3b8; text-align: center; margin-top: 120px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
39
 
40
  filename = os.path.splitext(os.path.basename(image_path))[0]
 
41
  target_folders = ["Qwen2509", "Qwen2512", "Zit"]
42
 
43
- html_output = f"<h3 style='margin-top:0; font-size: 18px; color: #1e293b;'>๐Ÿ“ฆ {filename} LoRA ๋‹ค์šด๋กœ๋“œ ๋งํฌ</h3>"
44
- html_output += "<table class='download-table'><thead><tr><th>๋ฒ„์ „ / ํด๋”</th><th>๋‹ค์šด๋กœ๋“œ ๋งํฌ</th></tr></thead><tbody>"
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
  all_files = api.list_repo_files(repo_id=REPO_ID, repo_type=REPO_TYPE)
47
 
@@ -55,7 +63,12 @@ def generate_download_links(image_path):
55
  else:
56
  html_output += f"<tr><td><b>{folder}</b></td><td style='color: #ef4444;'>ํŒŒ์ผ ์—†์Œ</td></tr>"
57
 
58
- html_output += "</tbody></table>"
 
 
 
 
 
59
  return html_output
60
 
61
  # --- ์Šคํƒ€์ผ์‹œํŠธ ---
@@ -63,18 +76,16 @@ custom_css = """
63
  body, .gradio-container { background-color: #f4f6f9 !important; font-family: sans-serif !important; }
64
  #lora-gallery { background: transparent !important; border: none !important; box-shadow: none !important; }
65
  #lora-gallery .gallery-item { background: #ffffff !important; border-radius: 12px !important; border: 1px solid #e2e8f0 !important; padding: 14px !important; }
66
- #info-panel { background: #ffffff !important; border-radius: 16px !important; border: 1px solid #e2e8f0 !important; padding: 24px !important; min-height: 450px; }
67
  .download-table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 15px; border-radius: 8px; overflow: hidden; border: 1px solid #e2e8f0; }
68
  .download-table th { background-color: #f8fafc; color: #64748b; padding: 12px 16px; font-size: 14px; border-bottom: 1px solid #e2e8f0; }
69
  .download-table td { padding: 14px 16px; font-size: 14px; border-bottom: 1px solid #e2e8f0; color: #334155; }
70
  .btn-download { color: #2563eb !important; font-weight: 600; text-decoration: none; }
71
  .btn-download:hover { text-decoration: underline; }
72
- /* ๋ฒ„ํŠผ ์Šคํƒ€์ผ ์ปค์Šคํ…€ */
73
  .nav-btn { font-weight: 600 !important; background: #ffffff !important; border: 1px solid #e2e8f0 !important; border-radius: 8px !important; }
74
  """
75
 
76
  with ui.Blocks(css=custom_css) as demo:
77
- # ํƒ€์ดํ‹€ ์˜์—ญ๊ณผ ์šฐ์ธก ๋ฒ„ํŠผ ๋‹จ์ถ• ๋ผ์ธ์„ ์ผ๋ ฌ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•œ ์ƒ๋‹จ ํˆด๋ฐ” ๊ตฌ์„ฑ
78
  with ui.Row():
79
  ui.Markdown("# โœจ mymuse LoRA Management Center")
80
  with ui.Row(elem_id="action-bar"):
@@ -85,7 +96,6 @@ with ui.Blocks(css=custom_css) as demo:
85
  with ui.Row():
86
  # ์™ผ์ชฝ ๊ทธ๋ฆฌ๋“œ ์˜์—ญ
87
  with ui.Column(scale=2):
88
- # ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ๋กœ๋“œ (์˜ค๋ฆ„์ฐจ์ˆœ)
89
  initial_paths = get_lora_samples(sort_desc=False)
90
  initial_gallery = [(hf_hub_url(repo_id=REPO_ID, repo_type=REPO_TYPE, filename=p), os.path.splitext(os.path.basename(p))[0]) for p in initial_paths]
91
 
@@ -98,34 +108,29 @@ with ui.Blocks(css=custom_css) as demo:
98
  show_label=False,
99
  elem_id="lora-gallery"
100
  )
101
- # ํ˜„์žฌ ์ •๋ ฌ๋œ ํŒŒ์ผ ๊ฒฝ๋กœ๋“ค์„ ๋“ค๊ณ  ์žˆ๋Š” ์ƒํƒœ ๋ณ€์ˆ˜
102
  paths_holder = ui.State(value=initial_paths)
103
 
104
- # ์˜ค๋ฅธ์ชฝ ์ •๋ณด ์ถœ๋ ฅ ์˜์—ญ
105
  with ui.Column(scale=1):
106
  with ui.HTML(elem_id="info-panel") as output_area:
107
- output_area.value = "<div style='color: #94a3b8; text-align: center; margin-top: 140px; font-size: 15px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
108
 
109
- # --- ์ด๋ฒคํŠธ ๋งตํ•‘ (์ƒ๋‹จ ์ œ์–ด ๋ฒ„ํŠผ ๋™์ž‘ ๊ตฌํ˜„) ---
110
-
111
- # 1. ์˜ค๋ฆ„์ฐจ์ˆœ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ
112
  btn_asc.click(
113
  fn=lambda: update_gallery_data(sort_desc=False),
114
  inputs=[],
115
  outputs=[gallery, paths_holder]
116
  )
117
 
118
- # 2. ๋‚ด๋ฆผ์ฐจ์ˆœ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ
119
  btn_desc.click(
120
  fn=lambda: update_gallery_data(sort_desc=True),
121
  inputs=[],
122
  outputs=[gallery, paths_holder]
123
  )
124
 
125
- # 3. ์ƒˆ๋กœ๊ณ ์นจ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ (๊ธฐ๋ณธ ์˜ค๋ฆ„์ฐจ์ˆœ ๊ฐฑ์‹  ๋ฐ ์šฐ์ธก ํŒจ๋„ ์ดˆ๊ธฐํ™”)
126
  def refresh_all():
127
  gallery_val, paths = update_gallery_data(sort_desc=False)
128
- reset_html = "<div style='color: #94a3b8; text-align: center; margin-top: 140px; font-size: 15px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
129
  return gallery_val, paths, reset_html
130
 
131
  btn_refresh.click(
@@ -134,7 +139,6 @@ with ui.Blocks(css=custom_css) as demo:
134
  outputs=[gallery, paths_holder, output_area]
135
  )
136
 
137
- # 4. ์นด๋“œ ์„ ํƒ ์ด๋ฒคํŠธ
138
  def on_select(evt: ui.SelectData, paths):
139
  return generate_download_links(paths[evt.index])
140
 
 
9
 
10
  api = HfApi(token=HF_TOKEN)
11
 
 
12
  def natural_sort_key(s):
13
  return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]
14
 
15
  def get_lora_samples(sort_desc=False):
 
16
  try:
 
17
  files = api.list_repo_files(repo_id=REPO_ID, repo_type=REPO_TYPE)
18
  samples = [f for f in files if f.startswith("LoRA_Samples/") and f.lower().endswith(('.png', '.jpg', '.jpeg'))]
 
 
19
  samples.sort(key=lambda x: natural_sort_key(os.path.basename(x)), reverse=sort_desc)
20
  return samples
21
  except Exception as e:
 
23
  return []
24
 
25
  def update_gallery_data(sort_desc=False):
 
26
  paths = get_lora_samples(sort_desc=sort_desc)
27
  gallery_val = [(hf_hub_url(repo_id=REPO_ID, repo_type=REPO_TYPE, filename=p), os.path.splitext(os.path.basename(p))[0]) for p in paths]
28
  return gallery_val, paths
29
 
30
  def generate_download_links(image_path):
31
  if not image_path:
32
+ return "<div style='color: #94a3b8; text-align: center; margin-top: 140px; font-size: 15px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
33
 
34
  filename = os.path.splitext(os.path.basename(image_path))[0]
35
+ img_url = hf_hub_url(repo_id=REPO_ID, repo_type=REPO_TYPE, filename=image_path)
36
  target_folders = ["Qwen2509", "Qwen2512", "Zit"]
37
 
38
+ # 1. ์ƒ๋‹จ ์ด๋ฏธ์ง€ ๋ฐฐ์น˜ ๋ฐ 2. ํ•˜๋‹จ ํ…์ŠคํŠธ ๋‚ด์šฉ ์œ ๊ธฐ์  ๊ฒฐํ•ฉ (HTML ๋ ˆ์ด์•„์›ƒ)
39
+ html_output = f"""
40
+ <div style='display: flex; flex-direction: column; align-items: center; gap: 20px;'>
41
+ <div style='width: 100%; max-width: 280px; aspect-ratio: 3/4; overflow: hidden; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);'>
42
+ <img src='{img_url}' style='width: 100%; height: 100%; object-fit: cover;' alt='{filename} preview'/>
43
+ </div>
44
+
45
+ <div style='width: 100%;'>
46
+ <h3 style='margin: 10px 0 5px 0; font-size: 18px; color: #1e293b; display: flex; align-items: center; gap: 6px;'>๐Ÿ“ฆ {filename} LoRA ๋‹ค์šด๋กœ๋“œ ๋งํฌ</h3>
47
+ <table class='download-table'>
48
+ <thead>
49
+ <tr><th>๋ฒ„์ „ / ํด๋”</th><th>๋‹ค์šด๋กœ๋“œ ๋งํฌ</th></tr>
50
+ </thead>
51
+ <tbody>
52
+ """
53
 
54
  all_files = api.list_repo_files(repo_id=REPO_ID, repo_type=REPO_TYPE)
55
 
 
63
  else:
64
  html_output += f"<tr><td><b>{folder}</b></td><td style='color: #ef4444;'>ํŒŒ์ผ ์—†์Œ</td></tr>"
65
 
66
+ html_output += """
67
+ </tbody>
68
+ </table>
69
+ </div>
70
+ </div>
71
+ """
72
  return html_output
73
 
74
  # --- ์Šคํƒ€์ผ์‹œํŠธ ---
 
76
  body, .gradio-container { background-color: #f4f6f9 !important; font-family: sans-serif !important; }
77
  #lora-gallery { background: transparent !important; border: none !important; box-shadow: none !important; }
78
  #lora-gallery .gallery-item { background: #ffffff !important; border-radius: 12px !important; border: 1px solid #e2e8f0 !important; padding: 14px !important; }
79
+ #info-panel { background: #ffffff !important; border-radius: 16px !important; border: 1px solid #e2e8f0 !important; padding: 24px !important; min-height: 500px; }
80
  .download-table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 15px; border-radius: 8px; overflow: hidden; border: 1px solid #e2e8f0; }
81
  .download-table th { background-color: #f8fafc; color: #64748b; padding: 12px 16px; font-size: 14px; border-bottom: 1px solid #e2e8f0; }
82
  .download-table td { padding: 14px 16px; font-size: 14px; border-bottom: 1px solid #e2e8f0; color: #334155; }
83
  .btn-download { color: #2563eb !important; font-weight: 600; text-decoration: none; }
84
  .btn-download:hover { text-decoration: underline; }
 
85
  .nav-btn { font-weight: 600 !important; background: #ffffff !important; border: 1px solid #e2e8f0 !important; border-radius: 8px !important; }
86
  """
87
 
88
  with ui.Blocks(css=custom_css) as demo:
 
89
  with ui.Row():
90
  ui.Markdown("# โœจ mymuse LoRA Management Center")
91
  with ui.Row(elem_id="action-bar"):
 
96
  with ui.Row():
97
  # ์™ผ์ชฝ ๊ทธ๋ฆฌ๋“œ ์˜์—ญ
98
  with ui.Column(scale=2):
 
99
  initial_paths = get_lora_samples(sort_desc=False)
100
  initial_gallery = [(hf_hub_url(repo_id=REPO_ID, repo_type=REPO_TYPE, filename=p), os.path.splitext(os.path.basename(p))[0]) for p in initial_paths]
101
 
 
108
  show_label=False,
109
  elem_id="lora-gallery"
110
  )
 
111
  paths_holder = ui.State(value=initial_paths)
112
 
113
+ # ์˜ค๋ฅธ์ชฝ ์ •๋ณด ์ถœ๋ ฅ ์˜์—ญ (์ƒ๋‹จ ์ด๋ฏธ์ง€ + ํ•˜๋‹จ ์ •๋ณด ๊ตฌ์กฐ ๋ฐ˜์˜)
114
  with ui.Column(scale=1):
115
  with ui.HTML(elem_id="info-panel") as output_area:
116
+ output_area.value = "<div style='color: #94a3b8; text-align: center; margin-top: 180px; font-size: 15px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
117
 
118
+ # --- ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ---
 
 
119
  btn_asc.click(
120
  fn=lambda: update_gallery_data(sort_desc=False),
121
  inputs=[],
122
  outputs=[gallery, paths_holder]
123
  )
124
 
 
125
  btn_desc.click(
126
  fn=lambda: update_gallery_data(sort_desc=True),
127
  inputs=[],
128
  outputs=[gallery, paths_holder]
129
  )
130
 
 
131
  def refresh_all():
132
  gallery_val, paths = update_gallery_data(sort_desc=False)
133
+ reset_html = "<div style='color: #94a3b8; text-align: center; margin-top: 180px; font-size: 15px;'>์™ผ์ชฝ ๋ชฉ๋ก์—์„œ ๋กœ๋ผ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด<br>๋ฒ„์ „๋ณ„ ์ƒํƒœ ์ •๋ณด ๋ฐ ๋‹ค์šด๋กœ๋“œ ์ฐฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.</div>"
134
  return gallery_val, paths, reset_html
135
 
136
  btn_refresh.click(
 
139
  outputs=[gallery, paths_holder, output_area]
140
  )
141
 
 
142
  def on_select(evt: ui.SelectData, paths):
143
  return generate_download_links(paths[evt.index])
144