File size: 22,475 Bytes
3acbd6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
import gradio as gr
import requests
import logging
import datetime
import threading
import time
from pytz import timezone
from collections import defaultdict

logging.basicConfig(level=logging.INFO)

# ๋กœ๊ทธ์ธ ์ธ์ฆ ์ •๋ณด
VALID_USERNAME = "ets2020"
VALID_PASSWORD = "1089"

# ๋กœ๊ทธ์ธ ์ƒํƒœ ๊ด€๋ฆฌ
is_logged_in = False

# ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
def process_logout():
    global is_logged_in
    is_logged_in = False
    return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), None

# ์•„์ด๋””๋ณ„ ์ด๋ฉ”์ผ ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ •๋ณด (์‹ค์ œ ๋ฐฐํฌ ์‹œ์—๋Š” ๋ณด์•ˆ์„ ์œ„ํ•ด ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค)
CREDENTIALS = {
    "whispersound": ["*****", "*****"],
    "happydoggg": ["*****", "*****"],
    "magictreee": ["*****", "*****"],
    "fastcarr": ["*****", "*****"],
    "corpcorp1": ["*****", "*****"],
    "rara527": ["*****", "*****"],
    "bluskyyy": ["*****", "*****"],
    "ssboost": ["*****", "*****"],
    "ekdhstldhs": ["*****", "*****"],
}

# ์„œ๋น„์Šค ๋ชฉ๋ก
TARGETS = [
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜+์ƒํ™œ๊ฑด๊ฐ•", "url": "https://huggingface.co/spaces/whispersound/kmkm_1-1"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/whispersound/kmkm_2-1"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/whispersound/kmkm_3-1"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-ํ•ต์‹ฌ๊ธฐ๋Šฅ", "url": "https://huggingface.co/spaces/whispersound/kmkm_4-1"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-๋ฐฉ๋ฌธํ›„๊ธฐ", "url": "https://huggingface.co/spaces/whispersound/kmkm_5-1"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜", "url": "https://huggingface.co/spaces/whispersound/mmmha_1-1"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/whispersound/mmmha_2-1"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/whispersound/mmmha_3-1"},
    {"name": "์œ ํŠœ๋ธŒ-์š”์•ฝ", "url": "https://huggingface.co/spaces/whispersound/ybyb-r-1"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ผ๋ฐ˜)", "url": "https://huggingface.co/spaces/whispersound/ybyb_1-1"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ™œ๊ฑด๊ฐ•)", "url": "https://huggingface.co/spaces/whispersound/ybyb_1-2-1"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์—ฌํ–‰)", "url": "https://huggingface.co/spaces/whispersound/ybyb_2-1"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ’ˆ๋ฆฌ๋ทฐ)", "url": "https://huggingface.co/spaces/whispersound/ybyb_3-1"},
    {"name": "์ด์ปค๋จธ์Šค-์นดํ”ผ๋ผ์ดํŒ…", "url": "https://huggingface.co/spaces/whispersound/LuLu_cp_1_R-1"},
    {"name": "์ด์ปค๋จธ-์ƒ์„ธํŽ˜์ด์ง€๊ธฐํš", "url": "https://huggingface.co/spaces/whispersound/plpl_1-1"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜+์ƒํ™œ๊ฑด๊ฐ•(์ œํœด์šฉ)", "url": "https://huggingface.co/spaces/whispersound/kmkm_1-4"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ(์ œํœด์šฉ)", "url": "https://huggingface.co/spaces/whispersound/kmkm_3-4"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-ํ•ต์‹ฌ๊ธฐ๋Šฅ(์ œํœด์šฉ)", "url": "https://huggingface.co/spaces/whispersound/kmkm_4-4"},
    
    {"name": "์ปจํŠธ๋กค-์ˆ˜๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/fastcarr/ldleeer1-1"},
    {"name": "์ปจํŠธ๋กค-์ž๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/fastcarr/lleryr1-1"},
    {"name": "์ปจํŠธ๋กค-์œ ํŠœ๋ธŒ", "url": "https://huggingface.co/spaces/fastcarr/kketywe1-1"},
    {"name": "์ปจํŠธ๋กค-์นดํ”ผ์ƒ์„ธ", "url": "https://huggingface.co/spaces/fastcarr/euywe1-1"},
    {"name": "๊ธฐ๋Šฅ-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/fastcarr/vvvpppp_1-1"},
    {"name": "๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธํฌ๋กค๋Ÿฌ", "url": "https://huggingface.co/spaces/fastcarr/ttpp323-1"},
    {"name": "๊ธฐ๋Šฅ-์œ ํŠœ๋ธŒ๋Œ€๋ณธ์ถ”์ถœ๊ธฐ", "url": "https://huggingface.co/spaces/fastcarr/YT_Ts_R-1"},
    {"name": "๊ธฐ๋Šฅ-PDF์ƒ์„ฑ๊ธฐ", "url": "https://huggingface.co/spaces/fastcarr/gaewate1-1"},
    {"name": "๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธํฌ๋กค๋Ÿฌ(์ œํœด์šฉ)", "url": "https://huggingface.co/spaces/fastcarr/ttpp323-4"},
    {"name": "๊ธฐ๋Šฅ-์œ ํŠœ๋ธŒ๋Œ€๋ณธ์ถ”์ถœ๊ธฐ(์ œํœด์šฉ)", "url": "https://huggingface.co/spaces/fastcarr/YT_Ts_R-4"},

    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜+์ƒํ™œ๊ฑด๊ฐ•", "url": "https://huggingface.co/spaces/happydoggg/kmkm_1-2"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/happydoggg/kmkm_2-2"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/happydoggg/kmkm_3-2"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-ํ•ต์‹ฌ๊ธฐ๋Šฅ", "url": "https://huggingface.co/spaces/happydoggg/kmkm_4-2"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-๋ฐฉ๋ฌธํ›„๊ธฐ", "url": "https://huggingface.co/spaces/happydoggg/kmkm_5-2"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜", "url": "https://huggingface.co/spaces/happydoggg/mmmha_1-2"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/happydoggg/mmmha_2-2"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/happydoggg/mmmha_3-2"},
    {"name": "์œ ํŠœ๋ธŒ-์š”์•ฝ", "url": "https://huggingface.co/spaces/happydoggg/ybyb-r-2"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ผ๋ฐ˜)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_1-2"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ™œ๊ฑด๊ฐ•)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_1-2-2"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์—ฌํ–‰)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_2-2"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ’ˆ๋ฆฌ๋ทฐ)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_3-2"},
    {"name": "์ด์ปค๋จธ์Šค-์นดํ”ผ๋ผ์ดํŒ…", "url": "https://huggingface.co/spaces/happydoggg/LuLu_cp_1_R-2"},
    {"name": "์ด์ปค๋จธ์Šค-์ƒ์„ธํŽ˜์ด์ง€๊ธฐํš", "url": "https://huggingface.co/spaces/happydoggg/plpl_1-2"},

    {"name": "์ปจํŠธ๋กค-์ˆ˜๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/corpcorp1/ldleeer1-2"},
    {"name": "์ปจํŠธ๋กค-์ž๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/corpcorp1/lleryr1-2"},
    {"name": "์ปจํŠธ๋กค-์œ ํŠœ๋ธŒ", "url": "https://huggingface.co/spaces/corpcorp1/kketywe1-2"},
    {"name": "์ปจํŠธ๋กค-์นดํ”ผ์ƒ์„ธ", "url": "https://huggingface.co/spaces/corpcorp1/euywe1-2"},
    {"name": "๊ธฐ๋Šฅ-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/corpcorp1/vvvpppp_1-2"},
    {"name": "๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธํฌ๋กค๋Ÿฌ", "url": "https://huggingface.co/spaces/corpcorp1/ttpp323-2"},
    {"name": "๊ธฐ๋Šฅ-์œ ํŠœ๋ธŒ๋Œ€๋ณธ์ถ”์ถœ๊ธฐ", "url": "https://huggingface.co/spaces/corpcorp1/YT_Ts_R-2"},
    {"name": "๊ธฐ๋Šฅ-PDF์ƒ์„ฑ๊ธฐ", "url": "https://huggingface.co/spaces/corpcorp1/gaewate1-2"},

    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜+์ƒํ™œ๊ฑด๊ฐ•", "url": "https://huggingface.co/spaces/magictreee/kmkm_1-3"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/magictreee/kmkm_2-3"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/magictreee/kmkm_3-3"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-ํ•ต์‹ฌ๊ธฐ๋Šฅ", "url": "https://huggingface.co/spaces/magictreee/kmkm_4-3"},
    {"name": "์ˆ˜๋™๋ธ”๋กœ๊ทธ-๋ฐฉ๋ฌธํ›„๊ธฐ", "url": "https://huggingface.co/spaces/magictreee/kmkm_5-3"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ผ๋ฐ˜", "url": "https://huggingface.co/spaces/magictreee/mmmha_1-3"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์—ฌํ–‰", "url": "https://huggingface.co/spaces/magictreee/mmmha_2-3"},
    {"name": "์ž๋™๋ธ”๋กœ๊ทธ-์ƒํ’ˆ๋ฆฌ๋ทฐ", "url": "https://huggingface.co/spaces/magictreee/mmmha_3-3"},
    {"name": "์œ ํŠœ๋ธŒ-์š”์•ฝ", "url": "https://huggingface.co/spaces/magictreee/ybyb-r-3"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ผ๋ฐ˜)", "url": "https://huggingface.co/spaces/magictreee/ybyb_1-3"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ™œ๊ฑด๊ฐ•)", "url": "https://huggingface.co/spaces/magictreee/ybyb_1-2-3"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์—ฌํ–‰)", "url": "https://huggingface.co/spaces/magictreee/ybyb_2-3"},
    {"name": "์œ ํŠœ๋ธŒ-๋ธ”๋กœ๊ทธ(์ƒํ’ˆ๋ฆฌ๋ทฐ)", "url": "https://huggingface.co/spaces/magictreee/ybyb_3-3"},
    {"name": "์ด์ปค๋จธ์Šค-์นดํ”ผ๋ผ์ดํŒ…", "url": "https://huggingface.co/spaces/magictreee/LuLu_cp_1_R-3"},
    {"name": "์ด์ปค๋จธ์Šค-์ƒ์„ธํŽ˜์ด์ง€๊ธฐํš", "url": "https://huggingface.co/spaces/magictreee/plpl_1-3"},

    {"name": "์ปจํŠธ๋กค-์ˆ˜๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/rara527/ldleeer1-3"},
    {"name": "์ปจํŠธ๋กค-์ž๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/rara527/lleryr1-3"},
    {"name": "์ปจํŠธ๋กค-์œ ํŠœ๋ธŒ", "url": "https://huggingface.co/spaces/rara527/kketywe1-3"},
    {"name": "์ปจํŠธ๋กค-์นดํ”ผ์ƒ์„ธ", "url": "https://huggingface.co/spaces/rara527/euywe1-3"},
    {"name": "๊ธฐ๋Šฅ-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/rara527/vvvpppp_1-3"},
    {"name": "๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธํฌ๋กค๋Ÿฌ", "url": "https://huggingface.co/spaces/rara527/ttpp323-3"},
    {"name": "๊ธฐ๋Šฅ-์œ ํŠœ๋ธŒ๋Œ€๋ณธ์ถ”์ถœ๊ธฐ", "url": "https://huggingface.co/spaces/rara527/YT_Ts_R-3"},
    {"name": "๊ธฐ๋Šฅ-PDF์ƒ์„ฑ๊ธฐ", "url": "https://huggingface.co/spaces/rara527/gaewate1-3"},

    {"name": "๋ฉ”์ธ๊ธฐ๋Šฅ-์ƒํ’ˆ๋ฐฐ๊ฒฝ์ด๋ฏธ์ง€", "url": "https://huggingface.co/spaces/bluskyyy/asvdqw3g234"},
    {"name": "๋ฉ”์ธ๊ธฐ๋Šฅ-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/bluskyyy/4234g5hhs"},
    {"name": "๋ฉ”์ธ๊ธฐ๋Šฅ-์ด๋ฏธ์ง€์ƒ์„ฑ๊ธฐ", "url": "https://huggingface.co/spaces/bluskyyy/asdfqwe"},
    {"name": "๋ฉ”์ธ๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธํฌ์ŠคํŒ…", "url": "https://huggingface.co/spaces/bluskyyy/33f23f3f-3"},

    {"name": "์ด๋ฏธ์ง€-๋ฐฐ๊ฒฝ์ œ๊ฑฐ", "url": "https://huggingface.co/spaces/ssboost/B_G"},
    {"name": "์ด๋ฏธ์ง€-ํ™”์งˆ๊ฐœ์„ ๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/Up_G"},
    {"name": "์ด๋ฏธ์ง€-ModelSwap", "url": "https://huggingface.co/spaces/ssboost/ModelSwap-1"},
    {"name": "์ด๋ฏธ์ง€-ํ•„ํ„ฐ", "url": "https://huggingface.co/spaces/ssboost/Image_Filter-1"},
    {"name": "์ด๋ฏธ์ง€-๋ณต์›", "url": "https://huggingface.co/spaces/ssboost/old_restoration-1"},
    {"name": "์ด๋ฏธ์ง€-์ด์ปค๋จธ์ŠคAI์ด๋ฏธ์ง€์ƒ์„ฑ", "url": "https://huggingface.co/spaces/ssboost/6hjw3hs3"},
    {"name": "์ด๋ฏธ์ง€-๋ฐฐ๊ฒฝ์ƒ์„ฑ๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/g7yhw43gssdf"},
    {"name": "์ด๋ฏธ์ง€-๋ฐฐ๊ฒฝ์ƒ์„ฑ๊ธฐ(์˜ˆ์‹œ)", "url": "https://huggingface.co/spaces/ssboost/asdfewef"},
    {"name": "์ด๋ฏธ์ง€-๋ฐฐ๊ฒฝ์ƒ์„ฑ๊ธฐ(์œ )", "url": "https://huggingface.co/spaces/ssboost/veegsd"},
    {"name": "์ด๋ฏธ์ง€-๋ธ”๋กœ๊ทธ์ด๋ฏธ์ง€์ƒ", "url": "https://huggingface.co/spaces/ssboost/dfq23d"},
    {"name": "์ด๋ฏธ์ง€-์ด๋ฏธ์ง€ํŽธ์ง‘", "url": "https://huggingface.co/spaces/ssboost/swq2f"},
    {"name": "์ด์ปค๋จธ์Šค-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/ssboost/fe2fsd"},
    {"name": "์ด์ปค๋จธ์Šค-๋„ค์ด๋ฒ„์‡ผํ•‘์ƒํ’ˆ๋ช…๋ถ„์„", "url": "https://huggingface.co/spaces/ssboost/d34feer"},
    {"name": "์œ ์šฉํ•œํˆด-๊ธ€๋‹ค๋“ฌ", "url": "https://huggingface.co/spaces/ssboost/E2T4TWEWEWE"},
    {"name": "์œ ์šฉํ•œํˆด-์…€๋Ÿฌ ์ž๋™ ๋ฒˆ์—ญ๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/G378DFE4AS"},
    {"name": "์œ ์šฉํ•œํˆด-gif", "url": "https://huggingface.co/spaces/ssboost/gif-1"},
    {"name": "์œ ์šฉํ•œํˆด-์œ ์‚ฌ๋ฐฉ์ง€์ด๋ฏธ์ง€๋ณ€ํ˜•๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/N_I"},
    {"name": "์œ ์šฉํ•œํˆด-๋ธ”๋กœ๊ทธํ˜•ํƒœ์†Œ๋ถ„์„", "url": "https://huggingface.co/spaces/ssboost/ge3gsdgas"},
    {"name": "๊ธ€์“ฐ๊ธฐ-์ˆ˜๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/ssboost/EWV2DDWEE"},
    {"name": "๊ธ€์“ฐ๊ธฐ-์ž๋™๋ธ”๋กœ๊ทธ", "url": "https://huggingface.co/spaces/ssboost/G3YGSDE"},
    {"name": "๊ธ€์“ฐ๊ธฐ-์œ ํŠœ๋ธŒ", "url": "https://huggingface.co/spaces/ssboost/FVW3GSX3"},
    {"name": "์ด์ปค๋จธ์Šค-์ƒํ’ˆ๋ช…(๋ฉ”์ธํ‚ค์›Œ๋“œ)", "url": "https://huggingface.co/spaces/ssboost/F23ASFGGD"},
    {"name": "์ด์ปค๋จธ์Šค-์ƒํ’ˆ๋ช…(์ƒํ’ˆ๋ช…๋ถ„์„)", "url": "https://huggingface.co/spaces/ssboost/F23ASFGGD-2"},
    {"name": "์ด์ปค๋จธ์Šค-์†Œ์‹ฑ๋ถ„์„๊ธฐ(ํ’€๋ฒ„์ „)", "url": "https://huggingface.co/spaces/ssboost/3gghdf5"},
    {"name": "์ด์ปค๋จธ์Šค-์†Œ์‹ฑ๋ถ„์„๊ธฐ(๊ฐ„๋žตํ™”)", "url": "https://huggingface.co/spaces/ssboost/geo5g4gfj"},
    {"name": "์ด๋ฏธ์ง€-๊ธ€์ž์ง€์šฐ๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/hkpdejhed"},
    {"name": "์ด๋ฏธ์ง€-์ด๋ฏธ์ง€๋ฐ”๊พธ๊ธฐ", "url": "https://huggingface.co/spaces/ssboost/g94h4jd"},

    
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-๋ฆฌ๋ทฐ๋ถ„์„", "url": "https://huggingface.co/spaces/ekdhstldhs/86f86f80yg"},
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-๋ธ”๋กœ๊ทธ์ƒ์„ฑ", "url": "https://huggingface.co/spaces/ekdhstldhs/f23fewde"},
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-์†Œ์‹ฑ๋ถ„์„๊ธฐ(ํ’€๋ฒ„์ „)", "url": "https://huggingface.co/spaces/ekdhstldhs/f232fwe"},
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-์†Œ์‹ฑ๋ถ„์„๊ธฐ(๊ฐ„๋žตํ™”)", "url": "https://huggingface.co/spaces/ekdhstldhs/df2wwewe"},
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-์ธ๋„ค์ผ๋ฐฐ๊ฒฝ๋ฐ”๊พธ๊ธฐ", "url": "https://huggingface.co/spaces/ekdhstldhs/fsqwgvdsd"},
    {"name": "๋ฉ”์ธํŽ˜์ด์ง€-์ด๋ฏธ์ง€์ƒ์„ฑ", "url": "https://huggingface.co/spaces/ekdhstldhs/g34ysdv234g"},
    {"name": "๊ธฐํƒ€๊ธฐ๋Šฅ-๋ฐฐ๊ฒฝ์ง€์šฐ๊ธฐ", "url": "https://huggingface.co/spaces/ekdhstldhs/df2wedds"},
    {"name": "๊ธฐํƒ€๊ธฐ๋Šฅ-ํ™”์งˆ๊ฐœ์„ ๊ธฐ", "url": "https://huggingface.co/spaces/ekdhstldhs/fef232fsdes"},
    {"name": "๋ณด์กฐ๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธ(์ƒํ’ˆ๋ฆฌ๋ทฐ)", "url": "https://huggingface.co/spaces/ekdhstldhs/kkie2"},
    {"name": "๋ณด์กฐ๊ธฐ๋Šฅ-๋ธ”๋กœ๊ทธ(ํ•ต์‹ฌ๊ธฐ๋Šฅ)", "url": "https://huggingface.co/spaces/ekdhstldhs/kkie3"}
    
]

KST = timezone('Asia/Seoul')

# ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
def process_login(username, password):
    global is_logged_in
    if username == VALID_USERNAME and password == VALID_PASSWORD:
        is_logged_in = True
        dashboard_html = update_dashboard()  # ๋Œ€์‹œ๋ณด๋“œ ๋ฐ์ดํ„ฐ ๋กœ๋“œ
        return gr.update(visible=False), gr.update(visible=True), "๋กœ๊ทธ์ธ ์„ฑ๊ณต! ๋Œ€์‹œ๋ณด๋“œ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.", dashboard_html
    else:
        return gr.update(visible=True), gr.update(visible=False), "์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", None

# URL ์ƒํƒœ ์ฒดํฌ ํ•จ์ˆ˜ - ๊ฐœ์„ ๋œ ๋ฒ„์ „
def check_url_status(url):
    try:
        response = requests.get(url, timeout=5)
        response_text = response.text.lower()
        
        # ํŽ˜์ด์ง€๊ฐ€ ์ผ์‹œ์ค‘์ง€๋œ ๊ฒฝ์šฐ์˜ ๋ช…ํ™•ํ•œ ํ‘œ์‹œ ํ™•์ธ
        if "paused by its owner" in response_text or "this space has been paused" in response_text:
            return "Paused"
        
        # ์‘๋‹ต ์ฝ”๋“œ ํ™•์ธ
        if response.status_code == 200:
            # 200 OK์ด์ง€๋งŒ ๋‚ด์šฉ์— ์˜ค๋ฅ˜ ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
            error_keywords = ["runtime error", "no application file", "build error", 
                             "configuration error", "error", "failed"]
            for keyword in error_keywords:
                if keyword in response_text:
                    return "์˜ค๋ฅ˜"
                    
            # ๋‹ค๋ฅธ ์ƒํƒœ ํ‚ค์›Œ๋“œ๋„ ํ™•์ธ
            if "paused" in response_text:
                return "Paused"
            elif "sleeping" in response_text or "asleep" in response_text:
                return "Sleeping"
            elif "building" in response_text:
                return "Building"
            elif "restarting" in response_text:
                return "Restarting"
            elif "starting" in response_text:
                return "Starting"
                
            # ์ •์ƒ ์‹คํ–‰ ์ค‘
            return "Running"
            
        elif response.status_code == 503:
            return "Sleeping"  # 503์€ ์ผ๋ฐ˜์ ์œผ๋กœ sleeping ์ƒํƒœ
        elif response.status_code >= 400:
            return "์˜ค๋ฅ˜"  # 400๋Œ€, 500๋Œ€ ์ฝ”๋“œ๋Š” ์˜ค๋ฅ˜
        
        # ๊ธฐ๋ณธ๊ฐ’
        return "์ƒํƒœ ๋ถˆ๋ช…"
            
    except requests.exceptions.Timeout:
        return "ํƒ€์ž„์•„์›ƒ"
    except requests.exceptions.ConnectionError:
        return "์—ฐ๊ฒฐ ์˜ค๋ฅ˜"
    except Exception as e:
        logging.error(f"URL ์ฒดํฌ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {url}, {str(e)}")
        return "๊ธฐํƒ€ ์˜ค๋ฅ˜"

# HTML ๋ธ”๋ก ์ƒ์„ฑ ํ•จ์ˆ˜
def generate_html(targets):
    grouped_by_id = defaultdict(lambda: defaultdict(list))
    for target in targets:
        user_id = target['url'].split('/')[4]  # ์•„์ด๋”” ์ถ”์ถœ
        function = target['name'].split('-')[0]  # ๊ธฐ๋Šฅ๋ณ„ ์นดํ…Œ๊ณ ๋ฆฌ ์ถ”์ถœ
        grouped_by_id[user_id][function].append(target)

    status_html = "<h2>์•„์ด๋””๋ณ„ ๋ฐ ๊ธฐ๋Šฅ๋ณ„ ๊ตฌ๋ถ„</h2>"

    # ์ƒํƒœ๋ณ„ ํ…์ŠคํŠธ ์ƒ‰์ƒ ์ง€์ •
    status_colors = {
        "Running": "#4CAF50",  # ๋…น์ƒ‰
        "Sleeping": "#808080",  # ํšŒ์ƒ‰
        "Paused": "#FFA500",    # ์ฃผํ™ฉ์ƒ‰
        "Building": "#2196F3",  # ํŒŒ๋ž€์ƒ‰
        "Restarting": "#9C27B0", # ๋ณด๋ผ์ƒ‰
        "Starting": "#03A9F4",  # ํ•˜๋Š˜์ƒ‰
        "์˜ค๋ฅ˜": "#FF0000",      # ๋นจ๊ฐ„์ƒ‰
        "ํƒ€์ž„์•„์›ƒ": "#FF0000",  # ๋นจ๊ฐ„์ƒ‰
        "์—ฐ๊ฒฐ ์˜ค๋ฅ˜": "#FF0000", # ๋นจ๊ฐ„์ƒ‰
        "๊ธฐํƒ€ ์˜ค๋ฅ˜": "#FF0000", # ๋นจ๊ฐ„์ƒ‰
        "์ƒํƒœ ๋ถˆ๋ช…": "#000000"  # ๊ฒ€์€์ƒ‰
    }

    for user_id, functions in grouped_by_id.items():
        email, password = CREDENTIALS.get(user_id, ["N/A", "N/A"])  # ์•„์ด๋””๋ณ„ ์ด๋ฉ”์ผ ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ
        status_html += (
            f"<div style='border: 2px solid #4CAF50; padding: 10px; margin: 10px 0; border-radius: 8px;'>"
            f"<h3 style='font-size: 1.5em; font-weight: bold;'>์•„์ด๋””๋ช…: {user_id}</h3>"
            f"<p><strong>์ด๋ฉ”์ผ:</strong> {email}<br><strong>๋น„๋ฐ€๋ฒˆํ˜ธ:</strong> {password}</p>"
        )
        for function, items in functions.items():
            status_html += (
                f"<div style='padding: 8px; margin: 5px 0; background-color: #F9F9F9; border-radius: 5px;'>"
                f"<strong style='font-size: 1.2em;'>{function}</strong><br>"
            )
            for item in items:
                item_name = item["name"].split('-')[-1]  # ์ด๋ฆ„์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„๋งŒ ํ‘œ์‹œ
                status = check_url_status(item["url"])
                
                # ์ƒํƒœ์— ๋”ฐ๋ฅธ ํ…์ŠคํŠธ ์ƒ‰์ƒ ์ง€์ •
                color = status_colors.get(status, "#000000")
                
                item_html = (
                    f'<a href="{item["url"]}" target="_blank" style="color: {color}; '
                    f'text-decoration: none; margin: 2px; display: inline-block; '
                    f'padding: 5px; border: 1px solid #E0E0E0; border-radius: 3px;">'
                    f'{item_name} ({status})</a>'
                )
                status_html += item_html
            status_html += "</div>"
        status_html += "</div>"

    return status_html

# ๋Œ€์‹œ๋ณด๋“œ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜
def update_dashboard():
    # HTML ๋ธ”๋ก ์ƒ์„ฑ
    html_content = generate_html(TARGETS)
    
    # ํ˜„์žฌ ์‹œ๊ฐ„ (์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„)
    current_time = datetime.datetime.now(KST).strftime('%Y.%m.%d %H:%M:%S')
    
    # ์ตœ์ข… HTML ์ƒ์„ฑ
    full_html = f"{html_content}<p style='color: #7A7A7A;'>์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„: {current_time}</p>"
    
    return full_html

# ์ž๋™ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์บ์‹œ ๋ณ€์ˆ˜๋“ค
dashboard_html_cache = ""
last_update_time = None

# ๋งค์ผ ์˜ค์ „ 7์‹œ์— ์‹คํ–‰๋˜๋Š” ์Šค์ผ€์ค„๋Ÿฌ ํ•จ์ˆ˜
def schedule_daily_check():
    global dashboard_html_cache, last_update_time
    while True:
        now = datetime.datetime.now(KST)
        if now.hour == 7 and now.minute == 0:
            logging.info("์ผ์ผ ์ƒํƒœ ์ฒดํฌ ์‹คํ–‰ ์ค‘...")
            # ์ž๋™ ์—…๋ฐ์ดํŠธ ๋กœ์ง
            dashboard_html_cache = generate_html(TARGETS)
            last_update_time = now
            logging.info(f"์ผ์ผ ์ƒํƒœ ์ฒดํฌ ์™„๋ฃŒ: {now.strftime('%Y.%m.%d %H:%M:%S')}")
            time.sleep(60)  # ์ค‘๋ณต ์‹คํ–‰ ๋ฐฉ์ง€
        time.sleep(30)  # 30์ดˆ๋งˆ๋‹ค ์‹œ๊ฐ„ ํ™•์ธ

# ๋Œ€์‹œ๋ณด๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ ํ•จ์ˆ˜
def get_dashboard():
    global dashboard_html_cache, last_update_time
    # ์บ์‹œ๊ฐ€ ๋น„์–ด์žˆ๊ฑฐ๋‚˜ ๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ ํ›„ 1์‹œ๊ฐ„์ด ์ง€๋‚ฌ์œผ๋ฉด ์ƒˆ๋กœ ์—…๋ฐ์ดํŠธ
    if dashboard_html_cache == "" or last_update_time is None or \
       (datetime.datetime.now(KST) - last_update_time).seconds > 3600:
        return update_dashboard()
    
    # ์บ์‹œ๋œ HTML์— ํ˜„์žฌ ์‹œ๊ฐ„ ์ถ”๊ฐ€
    current_time = datetime.datetime.now(KST).strftime('%Y.%m.%d %H:%M:%S')
    return f"{dashboard_html_cache}<p style='color: #7A7A7A;'>์—…๋ฐ์ดํŠธ ์‹œ๊ฐ„: {current_time} (์บ์‹œ๋จ)</p>"

# ์•ฑ ์ƒ์„ฑ ํ•จ์ˆ˜
def create_app():
    # CSS ์Šคํƒ€์ผ ์ •์˜ - ํ‘ธํ„ฐ ์ˆจ๊น€ ๋ฐ ์ถ”๊ฐ€ ์Šคํƒ€์ผ
    custom_css = """
    footer {visibility: hidden}
    .gradio-container {max-width: 1200px}
    .login-container {max-width: 500px; margin: 0 auto; padding: 20px;}
    """
    
    with gr.Blocks(css=custom_css) as app:
        # ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€
        with gr.Group(visible=True, elem_classes="login-container") as login_page:
            gr.Markdown("# ์„œ๋น„์Šค ๋Œ€์‹œ๋ณด๋“œ ๋กœ๊ทธ์ธ")
            gr.Markdown("ํ—ˆ๊น…ํŽ˜์ด์Šค ์„œ๋น„์Šค ๋Œ€์‹œ๋ณด๋“œ์— ์ ‘์†ํ•˜๋ ค๋ฉด ๋กœ๊ทธ์ธํ•˜์„ธ์š”.")
            username_input = gr.Textbox(label="์•„์ด๋””", placeholder="์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”")
            password_input = gr.Textbox(label="๋น„๋ฐ€๋ฒˆํ˜ธ", placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”", type="password")
            login_btn = gr.Button("๋กœ๊ทธ์ธ", variant="primary", scale=1)
            login_message = gr.Textbox(label="์ƒํƒœ", interactive=False, visible=False)

        # ๋ฉ”์ธ ๋Œ€์‹œ๋ณด๋“œ ํŽ˜์ด์ง€
        with gr.Group(visible=False) as dashboard_page:
            with gr.Row():
                gr.Markdown("# ํ—ˆ๊น…ํŽ˜์ด์Šค ์„œ๋น„์Šค ๋Œ€์‹œ๋ณด๋“œ")
            
            with gr.Row():
                refresh_button = gr.Button("์ƒํƒœ ์ƒˆ๋กœ๊ณ ์นจ", variant="primary")
                logout_button = gr.Button("๋กœ๊ทธ์•„์›ƒ", variant="secondary")
            
            status_html = gr.HTML()
        
        # ๋กœ๊ทธ์ธ ์ด๋ฒคํŠธ ์„ค์ •
        login_btn.click(
            fn=process_login,
            inputs=[username_input, password_input],
            outputs=[login_page, dashboard_page, login_message, status_html]
        )
        
        # ๋Œ€์‹œ๋ณด๋“œ ์ƒˆ๋กœ๊ณ ์นจ ์ด๋ฒคํŠธ ์„ค์ •
        refresh_button.click(
            fn=update_dashboard,
            outputs=status_html
        )
        
        # ๋กœ๊ทธ์•„์›ƒ ์ด๋ฒคํŠธ ์„ค์ •
        logout_button.click(
            fn=process_logout,
            outputs=[login_page, dashboard_page, login_message, status_html]
        )
        
        # ์Šค์ผ€์ค„๋Ÿฌ ์Šค๋ ˆ๋“œ ์‹คํ–‰
        threading.Thread(target=schedule_daily_check, daemon=True).start()

    return app

# ๋ฉ”์ธ ์‹คํ–‰ ์ฝ”๋“œ
if __name__ == "__main__":
    app = create_app()
    app.launch(share=False, server_name="0.0.0.0", server_port=7860)