ssboost commited on
Commit
3acbd6d
Β·
verified Β·
1 Parent(s): 57ad980

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +385 -2
app.py CHANGED
@@ -1,2 +1,385 @@
1
- import os
2
- exec(os.environ.get('APP'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import logging
4
+ import datetime
5
+ import threading
6
+ import time
7
+ from pytz import timezone
8
+ from collections import defaultdict
9
+
10
+ logging.basicConfig(level=logging.INFO)
11
+
12
+ # 둜그인 인증 정보
13
+ VALID_USERNAME = "ets2020"
14
+ VALID_PASSWORD = "1089"
15
+
16
+ # 둜그인 μƒνƒœ 관리
17
+ is_logged_in = False
18
+
19
+ # λ‘œκ·Έμ•„μ›ƒ 처리 ν•¨μˆ˜
20
+ def process_logout():
21
+ global is_logged_in
22
+ is_logged_in = False
23
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), None
24
+
25
+ # 아이디별 이메일 및 λΉ„λ°€λ²ˆν˜Έ 정보 (μ‹€μ œ 배포 μ‹œμ—λŠ” λ³΄μ•ˆμ„ μœ„ν•΄ λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€)
26
+ CREDENTIALS = {
27
+ "whispersound": ["*****", "*****"],
28
+ "happydoggg": ["*****", "*****"],
29
+ "magictreee": ["*****", "*****"],
30
+ "fastcarr": ["*****", "*****"],
31
+ "corpcorp1": ["*****", "*****"],
32
+ "rara527": ["*****", "*****"],
33
+ "bluskyyy": ["*****", "*****"],
34
+ "ssboost": ["*****", "*****"],
35
+ "ekdhstldhs": ["*****", "*****"],
36
+ }
37
+
38
+ # μ„œλΉ„μŠ€ λͺ©λ‘
39
+ TARGETS = [
40
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-일반+μƒν™œκ±΄κ°•", "url": "https://huggingface.co/spaces/whispersound/kmkm_1-1"},
41
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/whispersound/kmkm_2-1"},
42
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/whispersound/kmkm_3-1"},
43
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-핡심기λŠ₯", "url": "https://huggingface.co/spaces/whispersound/kmkm_4-1"},
44
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-λ°©λ¬Έν›„κΈ°", "url": "https://huggingface.co/spaces/whispersound/kmkm_5-1"},
45
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-일반", "url": "https://huggingface.co/spaces/whispersound/mmmha_1-1"},
46
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/whispersound/mmmha_2-1"},
47
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/whispersound/mmmha_3-1"},
48
+ {"name": "유튜브-μš”μ•½", "url": "https://huggingface.co/spaces/whispersound/ybyb-r-1"},
49
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(일반)", "url": "https://huggingface.co/spaces/whispersound/ybyb_1-1"},
50
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν™œκ±΄κ°•)", "url": "https://huggingface.co/spaces/whispersound/ybyb_1-2-1"},
51
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μ—¬ν–‰)", "url": "https://huggingface.co/spaces/whispersound/ybyb_2-1"},
52
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν’ˆλ¦¬λ·°)", "url": "https://huggingface.co/spaces/whispersound/ybyb_3-1"},
53
+ {"name": "이컀머슀-μΉ΄ν”ΌλΌμ΄νŒ…", "url": "https://huggingface.co/spaces/whispersound/LuLu_cp_1_R-1"},
54
+ {"name": "이컀머-μƒμ„ΈνŽ˜μ΄μ§€κΈ°νš", "url": "https://huggingface.co/spaces/whispersound/plpl_1-1"},
55
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-일반+μƒν™œκ±΄κ°•(제휴용)", "url": "https://huggingface.co/spaces/whispersound/kmkm_1-4"},
56
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°(제휴용)", "url": "https://huggingface.co/spaces/whispersound/kmkm_3-4"},
57
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-핡심기λŠ₯(제휴용)", "url": "https://huggingface.co/spaces/whispersound/kmkm_4-4"},
58
+
59
+ {"name": "컨트둀-μˆ˜λ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/fastcarr/ldleeer1-1"},
60
+ {"name": "컨트둀-μžλ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/fastcarr/lleryr1-1"},
61
+ {"name": "컨트둀-유튜브", "url": "https://huggingface.co/spaces/fastcarr/kketywe1-1"},
62
+ {"name": "컨트둀-카피상세", "url": "https://huggingface.co/spaces/fastcarr/euywe1-1"},
63
+ {"name": "κΈ°λŠ₯-리뷰뢄석", "url": "https://huggingface.co/spaces/fastcarr/vvvpppp_1-1"},
64
+ {"name": "κΈ°λŠ₯-λΈ”λ‘œκ·Έν¬λ‘€λŸ¬", "url": "https://huggingface.co/spaces/fastcarr/ttpp323-1"},
65
+ {"name": "κΈ°λŠ₯-μœ νŠœλΈŒλŒ€λ³ΈμΆ”μΆœκΈ°", "url": "https://huggingface.co/spaces/fastcarr/YT_Ts_R-1"},
66
+ {"name": "κΈ°λŠ₯-PDF생성기", "url": "https://huggingface.co/spaces/fastcarr/gaewate1-1"},
67
+ {"name": "κΈ°λŠ₯-λΈ”λ‘œκ·Έν¬λ‘€λŸ¬(제휴용)", "url": "https://huggingface.co/spaces/fastcarr/ttpp323-4"},
68
+ {"name": "κΈ°λŠ₯-μœ νŠœλΈŒλŒ€λ³ΈμΆ”μΆœκΈ°(제휴용)", "url": "https://huggingface.co/spaces/fastcarr/YT_Ts_R-4"},
69
+
70
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-일반+μƒν™œκ±΄κ°•", "url": "https://huggingface.co/spaces/happydoggg/kmkm_1-2"},
71
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/happydoggg/kmkm_2-2"},
72
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/happydoggg/kmkm_3-2"},
73
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-핡심기λŠ₯", "url": "https://huggingface.co/spaces/happydoggg/kmkm_4-2"},
74
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-λ°©λ¬Έν›„κΈ°", "url": "https://huggingface.co/spaces/happydoggg/kmkm_5-2"},
75
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-일반", "url": "https://huggingface.co/spaces/happydoggg/mmmha_1-2"},
76
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/happydoggg/mmmha_2-2"},
77
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/happydoggg/mmmha_3-2"},
78
+ {"name": "유튜브-μš”μ•½", "url": "https://huggingface.co/spaces/happydoggg/ybyb-r-2"},
79
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(일반)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_1-2"},
80
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν™œκ±΄κ°•)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_1-2-2"},
81
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μ—¬ν–‰)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_2-2"},
82
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν’ˆλ¦¬λ·°)", "url": "https://huggingface.co/spaces/happydoggg/ybyb_3-2"},
83
+ {"name": "이컀머슀-μΉ΄ν”ΌλΌμ΄νŒ…", "url": "https://huggingface.co/spaces/happydoggg/LuLu_cp_1_R-2"},
84
+ {"name": "이컀머슀-μƒμ„ΈνŽ˜μ΄μ§€κΈ°νš", "url": "https://huggingface.co/spaces/happydoggg/plpl_1-2"},
85
+
86
+ {"name": "컨트둀-μˆ˜λ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/corpcorp1/ldleeer1-2"},
87
+ {"name": "컨트둀-μžλ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/corpcorp1/lleryr1-2"},
88
+ {"name": "컨트둀-유튜브", "url": "https://huggingface.co/spaces/corpcorp1/kketywe1-2"},
89
+ {"name": "컨트둀-카피상세", "url": "https://huggingface.co/spaces/corpcorp1/euywe1-2"},
90
+ {"name": "κΈ°λŠ₯-리뷰뢄석", "url": "https://huggingface.co/spaces/corpcorp1/vvvpppp_1-2"},
91
+ {"name": "κΈ°λŠ₯-λΈ”λ‘œκ·Έν¬λ‘€λŸ¬", "url": "https://huggingface.co/spaces/corpcorp1/ttpp323-2"},
92
+ {"name": "κΈ°λŠ₯-μœ νŠœλΈŒλŒ€λ³ΈμΆ”μΆœκΈ°", "url": "https://huggingface.co/spaces/corpcorp1/YT_Ts_R-2"},
93
+ {"name": "κΈ°λŠ₯-PDF생성기", "url": "https://huggingface.co/spaces/corpcorp1/gaewate1-2"},
94
+
95
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-일반+μƒν™œκ±΄κ°•", "url": "https://huggingface.co/spaces/magictreee/kmkm_1-3"},
96
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/magictreee/kmkm_2-3"},
97
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/magictreee/kmkm_3-3"},
98
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-핡심기λŠ₯", "url": "https://huggingface.co/spaces/magictreee/kmkm_4-3"},
99
+ {"name": "μˆ˜λ™λΈ”λ‘œκ·Έ-λ°©λ¬Έν›„κΈ°", "url": "https://huggingface.co/spaces/magictreee/kmkm_5-3"},
100
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-일반", "url": "https://huggingface.co/spaces/magictreee/mmmha_1-3"},
101
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μ—¬ν–‰", "url": "https://huggingface.co/spaces/magictreee/mmmha_2-3"},
102
+ {"name": "μžλ™λΈ”λ‘œκ·Έ-μƒν’ˆλ¦¬λ·°", "url": "https://huggingface.co/spaces/magictreee/mmmha_3-3"},
103
+ {"name": "유튜브-μš”μ•½", "url": "https://huggingface.co/spaces/magictreee/ybyb-r-3"},
104
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(일반)", "url": "https://huggingface.co/spaces/magictreee/ybyb_1-3"},
105
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν™œκ±΄κ°•)", "url": "https://huggingface.co/spaces/magictreee/ybyb_1-2-3"},
106
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μ—¬ν–‰)", "url": "https://huggingface.co/spaces/magictreee/ybyb_2-3"},
107
+ {"name": "유튜브-λΈ”λ‘œκ·Έ(μƒν’ˆλ¦¬λ·°)", "url": "https://huggingface.co/spaces/magictreee/ybyb_3-3"},
108
+ {"name": "이컀머슀-μΉ΄ν”ΌλΌμ΄νŒ…", "url": "https://huggingface.co/spaces/magictreee/LuLu_cp_1_R-3"},
109
+ {"name": "이컀머슀-μƒμ„ΈνŽ˜μ΄μ§€κΈ°νš", "url": "https://huggingface.co/spaces/magictreee/plpl_1-3"},
110
+
111
+ {"name": "컨트둀-μˆ˜λ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/rara527/ldleeer1-3"},
112
+ {"name": "컨트둀-μžλ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/rara527/lleryr1-3"},
113
+ {"name": "컨트둀-유튜브", "url": "https://huggingface.co/spaces/rara527/kketywe1-3"},
114
+ {"name": "컨트둀-카피상세", "url": "https://huggingface.co/spaces/rara527/euywe1-3"},
115
+ {"name": "κΈ°λŠ₯-리뷰뢄석", "url": "https://huggingface.co/spaces/rara527/vvvpppp_1-3"},
116
+ {"name": "κΈ°λŠ₯-λΈ”λ‘œκ·Έν¬λ‘€λŸ¬", "url": "https://huggingface.co/spaces/rara527/ttpp323-3"},
117
+ {"name": "κΈ°λŠ₯-μœ νŠœλΈŒλŒ€λ³ΈμΆ”μΆœκΈ°", "url": "https://huggingface.co/spaces/rara527/YT_Ts_R-3"},
118
+ {"name": "κΈ°λŠ₯-PDF생성기", "url": "https://huggingface.co/spaces/rara527/gaewate1-3"},
119
+
120
+ {"name": "메인기λŠ₯-μƒν’ˆλ°°κ²½μ΄λ―Έμ§€", "url": "https://huggingface.co/spaces/bluskyyy/asvdqw3g234"},
121
+ {"name": "메인기λŠ₯-리뷰뢄석", "url": "https://huggingface.co/spaces/bluskyyy/4234g5hhs"},
122
+ {"name": "메인기λŠ₯-이미지생성기", "url": "https://huggingface.co/spaces/bluskyyy/asdfqwe"},
123
+ {"name": "메인기λŠ₯-λΈ”λ‘œκ·Έν¬μŠ€νŒ…", "url": "https://huggingface.co/spaces/bluskyyy/33f23f3f-3"},
124
+
125
+ {"name": "이미지-배경제거", "url": "https://huggingface.co/spaces/ssboost/B_G"},
126
+ {"name": "이미지-ν™”μ§ˆκ°œμ„ κΈ°", "url": "https://huggingface.co/spaces/ssboost/Up_G"},
127
+ {"name": "이미지-ModelSwap", "url": "https://huggingface.co/spaces/ssboost/ModelSwap-1"},
128
+ {"name": "이미지-ν•„ν„°", "url": "https://huggingface.co/spaces/ssboost/Image_Filter-1"},
129
+ {"name": "이미지-볡원", "url": "https://huggingface.co/spaces/ssboost/old_restoration-1"},
130
+ {"name": "이미지-이컀머슀AI이미지생성", "url": "https://huggingface.co/spaces/ssboost/6hjw3hs3"},
131
+ {"name": "이미지-배경생성기", "url": "https://huggingface.co/spaces/ssboost/g7yhw43gssdf"},
132
+ {"name": "이미��-배경생성기(μ˜ˆμ‹œ)", "url": "https://huggingface.co/spaces/ssboost/asdfewef"},
133
+ {"name": "이미지-배경생성기(유)", "url": "https://huggingface.co/spaces/ssboost/veegsd"},
134
+ {"name": "이미지-λΈ”λ‘œκ·Έμ΄λ―Έμ§€μƒ", "url": "https://huggingface.co/spaces/ssboost/dfq23d"},
135
+ {"name": "이미지-μ΄λ―Έμ§€νŽΈμ§‘", "url": "https://huggingface.co/spaces/ssboost/swq2f"},
136
+ {"name": "이컀머슀-리뷰뢄석", "url": "https://huggingface.co/spaces/ssboost/fe2fsd"},
137
+ {"name": "이컀머슀-λ„€μ΄λ²„μ‡Όν•‘μƒν’ˆλͺ…뢄석", "url": "https://huggingface.co/spaces/ssboost/d34feer"},
138
+ {"name": "μœ μš©ν•œνˆ΄-글닀듬", "url": "https://huggingface.co/spaces/ssboost/E2T4TWEWEWE"},
139
+ {"name": "μœ μš©ν•œνˆ΄-μ…€λŸ¬ μžλ™ λ²ˆμ—­κΈ°", "url": "https://huggingface.co/spaces/ssboost/G378DFE4AS"},
140
+ {"name": "μœ μš©ν•œνˆ΄-gif", "url": "https://huggingface.co/spaces/ssboost/gif-1"},
141
+ {"name": "μœ μš©ν•œνˆ΄-μœ μ‚¬λ°©μ§€μ΄λ―Έμ§€λ³€ν˜•κΈ°", "url": "https://huggingface.co/spaces/ssboost/N_I"},
142
+ {"name": "μœ μš©ν•œνˆ΄-λΈ”λ‘œκ·Έν˜•νƒœμ†ŒλΆ„μ„", "url": "https://huggingface.co/spaces/ssboost/ge3gsdgas"},
143
+ {"name": "κΈ€μ“°κΈ°-μˆ˜λ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/ssboost/EWV2DDWEE"},
144
+ {"name": "κΈ€μ“°κΈ°-μžλ™λΈ”λ‘œκ·Έ", "url": "https://huggingface.co/spaces/ssboost/G3YGSDE"},
145
+ {"name": "κΈ€μ“°κΈ°-유튜브", "url": "https://huggingface.co/spaces/ssboost/FVW3GSX3"},
146
+ {"name": "이컀머슀-μƒν’ˆλͺ…(λ©”μΈν‚€μ›Œλ“œ)", "url": "https://huggingface.co/spaces/ssboost/F23ASFGGD"},
147
+ {"name": "이컀머슀-μƒν’ˆλͺ…(μƒν’ˆλͺ…뢄석)", "url": "https://huggingface.co/spaces/ssboost/F23ASFGGD-2"},
148
+ {"name": "이컀머슀-μ†Œμ‹±λΆ„μ„κΈ°(풀버전)", "url": "https://huggingface.co/spaces/ssboost/3gghdf5"},
149
+ {"name": "이컀머슀-μ†Œμ‹±λΆ„μ„κΈ°(κ°„λž΅ν™”)", "url": "https://huggingface.co/spaces/ssboost/geo5g4gfj"},
150
+ {"name": "이미지-κΈ€μžμ§€μš°κΈ°", "url": "https://huggingface.co/spaces/ssboost/hkpdejhed"},
151
+ {"name": "이미지-이미지바꾸기", "url": "https://huggingface.co/spaces/ssboost/g94h4jd"},
152
+
153
+
154
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-리뷰뢄석", "url": "https://huggingface.co/spaces/ekdhstldhs/86f86f80yg"},
155
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-λΈ”λ‘œκ·Έμƒμ„±", "url": "https://huggingface.co/spaces/ekdhstldhs/f23fewde"},
156
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-μ†Œμ‹±λΆ„μ„κΈ°(풀버전)", "url": "https://huggingface.co/spaces/ekdhstldhs/f232fwe"},
157
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-μ†Œμ‹±λΆ„μ„κΈ°(κ°„λž΅ν™”)", "url": "https://huggingface.co/spaces/ekdhstldhs/df2wwewe"},
158
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-썸넀일배경바꾸기", "url": "https://huggingface.co/spaces/ekdhstldhs/fsqwgvdsd"},
159
+ {"name": "λ©”μΈνŽ˜μ΄μ§€-이미지생성", "url": "https://huggingface.co/spaces/ekdhstldhs/g34ysdv234g"},
160
+ {"name": "기타기λŠ₯-λ°°κ²½μ§€μš°κΈ°", "url": "https://huggingface.co/spaces/ekdhstldhs/df2wedds"},
161
+ {"name": "기타기λŠ₯-ν™”μ§ˆκ°œμ„ κΈ°", "url": "https://huggingface.co/spaces/ekdhstldhs/fef232fsdes"},
162
+ {"name": "보쑰기λŠ₯-λΈ”λ‘œκ·Έ(μƒν’ˆλ¦¬λ·°)", "url": "https://huggingface.co/spaces/ekdhstldhs/kkie2"},
163
+ {"name": "보쑰기λŠ₯-λΈ”λ‘œκ·Έ(핡심기λŠ₯)", "url": "https://huggingface.co/spaces/ekdhstldhs/kkie3"}
164
+
165
+ ]
166
+
167
+ KST = timezone('Asia/Seoul')
168
+
169
+ # 둜그인 처리 ν•¨μˆ˜
170
+ def process_login(username, password):
171
+ global is_logged_in
172
+ if username == VALID_USERNAME and password == VALID_PASSWORD:
173
+ is_logged_in = True
174
+ dashboard_html = update_dashboard() # λŒ€μ‹œλ³΄λ“œ 데이터 λ‘œλ“œ
175
+ return gr.update(visible=False), gr.update(visible=True), "둜그인 성곡! λŒ€μ‹œλ³΄λ“œλ‘œ μ΄λ™ν•©λ‹ˆλ‹€.", dashboard_html
176
+ else:
177
+ return gr.update(visible=True), gr.update(visible=False), "아이디 λ˜λŠ” λΉ„λ°€λ²ˆν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.", None
178
+
179
+ # URL μƒνƒœ 체크 ν•¨μˆ˜ - κ°œμ„ λœ 버전
180
+ def check_url_status(url):
181
+ try:
182
+ response = requests.get(url, timeout=5)
183
+ response_text = response.text.lower()
184
+
185
+ # νŽ˜μ΄μ§€κ°€ μΌμ‹œμ€‘μ§€λœ 경우의 λͺ…ν™•ν•œ ν‘œμ‹œ 확인
186
+ if "paused by its owner" in response_text or "this space has been paused" in response_text:
187
+ return "Paused"
188
+
189
+ # 응닡 μ½”λ“œ 확인
190
+ if response.status_code == 200:
191
+ # 200 OKμ΄μ§€λ§Œ λ‚΄μš©μ— 였λ₯˜ ν‚€μ›Œλ“œκ°€ μžˆλŠ”μ§€ 확인
192
+ error_keywords = ["runtime error", "no application file", "build error",
193
+ "configuration error", "error", "failed"]
194
+ for keyword in error_keywords:
195
+ if keyword in response_text:
196
+ return "였λ₯˜"
197
+
198
+ # λ‹€λ₯Έ μƒνƒœ ν‚€μ›Œλ“œλ„ 확인
199
+ if "paused" in response_text:
200
+ return "Paused"
201
+ elif "sleeping" in response_text or "asleep" in response_text:
202
+ return "Sleeping"
203
+ elif "building" in response_text:
204
+ return "Building"
205
+ elif "restarting" in response_text:
206
+ return "Restarting"
207
+ elif "starting" in response_text:
208
+ return "Starting"
209
+
210
+ # 정상 μ‹€ν–‰ 쀑
211
+ return "Running"
212
+
213
+ elif response.status_code == 503:
214
+ return "Sleeping" # 503은 일반적으둜 sleeping μƒνƒœ
215
+ elif response.status_code >= 400:
216
+ return "였λ₯˜" # 400λŒ€, 500λŒ€ μ½”λ“œλŠ” 였λ₯˜
217
+
218
+ # κΈ°λ³Έκ°’
219
+ return "μƒνƒœ 뢈λͺ…"
220
+
221
+ except requests.exceptions.Timeout:
222
+ return "νƒ€μž„μ•„μ›ƒ"
223
+ except requests.exceptions.ConnectionError:
224
+ return "μ—°κ²° 였λ₯˜"
225
+ except Exception as e:
226
+ logging.error(f"URL 체크 쀑 였λ₯˜ λ°œμƒ: {url}, {str(e)}")
227
+ return "기타 였λ₯˜"
228
+
229
+ # HTML 블둝 생성 ν•¨μˆ˜
230
+ def generate_html(targets):
231
+ grouped_by_id = defaultdict(lambda: defaultdict(list))
232
+ for target in targets:
233
+ user_id = target['url'].split('/')[4] # 아이디 μΆ”μΆœ
234
+ function = target['name'].split('-')[0] # κΈ°λŠ₯별 μΉ΄ν…Œκ³ λ¦¬ μΆ”μΆœ
235
+ grouped_by_id[user_id][function].append(target)
236
+
237
+ status_html = "<h2>아이디별 및 κΈ°λŠ₯별 ꡬ뢄</h2>"
238
+
239
+ # μƒνƒœλ³„ ν…μŠ€νŠΈ 색상 μ§€μ •
240
+ status_colors = {
241
+ "Running": "#4CAF50", # 녹색
242
+ "Sleeping": "#808080", # νšŒμƒ‰
243
+ "Paused": "#FFA500", # 주황색
244
+ "Building": "#2196F3", # νŒŒλž€μƒ‰
245
+ "Restarting": "#9C27B0", # 보라색
246
+ "Starting": "#03A9F4", # ν•˜λŠ˜μƒ‰
247
+ "였λ₯˜": "#FF0000", # 빨간색
248
+ "νƒ€μž„μ•„μ›ƒ": "#FF0000", # 빨간색
249
+ "μ—°κ²° 였λ₯˜": "#FF0000", # 빨간색
250
+ "기타 였λ₯˜": "#FF0000", # 빨간색
251
+ "μƒνƒœ 뢈λͺ…": "#000000" # 검은색
252
+ }
253
+
254
+ for user_id, functions in grouped_by_id.items():
255
+ email, password = CREDENTIALS.get(user_id, ["N/A", "N/A"]) # 아이디별 이메일 및 λΉ„λ°€λ²ˆν˜Έ
256
+ status_html += (
257
+ f"<div style='border: 2px solid #4CAF50; padding: 10px; margin: 10px 0; border-radius: 8px;'>"
258
+ f"<h3 style='font-size: 1.5em; font-weight: bold;'>아이디λͺ…: {user_id}</h3>"
259
+ f"<p><strong>이메일:</strong> {email}<br><strong>λΉ„λ°€λ²ˆν˜Έ:</strong> {password}</p>"
260
+ )
261
+ for function, items in functions.items():
262
+ status_html += (
263
+ f"<div style='padding: 8px; margin: 5px 0; background-color: #F9F9F9; border-radius: 5px;'>"
264
+ f"<strong style='font-size: 1.2em;'>{function}</strong><br>"
265
+ )
266
+ for item in items:
267
+ item_name = item["name"].split('-')[-1] # μ΄λ¦„μ˜ λ§ˆμ§€λ§‰ λΆ€λΆ„λ§Œ ν‘œμ‹œ
268
+ status = check_url_status(item["url"])
269
+
270
+ # μƒνƒœμ— λ”°λ₯Έ ν…μŠ€νŠΈ 색상 μ§€μ •
271
+ color = status_colors.get(status, "#000000")
272
+
273
+ item_html = (
274
+ f'<a href="{item["url"]}" target="_blank" style="color: {color}; '
275
+ f'text-decoration: none; margin: 2px; display: inline-block; '
276
+ f'padding: 5px; border: 1px solid #E0E0E0; border-radius: 3px;">'
277
+ f'{item_name} ({status})</a>'
278
+ )
279
+ status_html += item_html
280
+ status_html += "</div>"
281
+ status_html += "</div>"
282
+
283
+ return status_html
284
+
285
+ # λŒ€μ‹œλ³΄λ“œ μ—…λ°μ΄νŠΈ ν•¨μˆ˜
286
+ def update_dashboard():
287
+ # HTML 블둝 생성
288
+ html_content = generate_html(TARGETS)
289
+
290
+ # ν˜„μž¬ μ‹œκ°„ (μ—…λ°μ΄νŠΈ μ‹œκ°„)
291
+ current_time = datetime.datetime.now(KST).strftime('%Y.%m.%d %H:%M:%S')
292
+
293
+ # μ΅œμ’… HTML 생성
294
+ full_html = f"{html_content}<p style='color: #7A7A7A;'>μ—…λ°μ΄νŠΈ μ‹œκ°„: {current_time}</p>"
295
+
296
+ return full_html
297
+
298
+ # μžλ™ μ—…λ°μ΄νŠΈλ₯Ό μœ„ν•œ μΊμ‹œ λ³€μˆ˜λ“€
299
+ dashboard_html_cache = ""
300
+ last_update_time = None
301
+
302
+ # 맀일 μ˜€μ „ 7μ‹œμ— μ‹€ν–‰λ˜λŠ” μŠ€μΌ€μ€„λŸ¬ ν•¨μˆ˜
303
+ def schedule_daily_check():
304
+ global dashboard_html_cache, last_update_time
305
+ while True:
306
+ now = datetime.datetime.now(KST)
307
+ if now.hour == 7 and now.minute == 0:
308
+ logging.info("일일 μƒνƒœ 체크 μ‹€ν–‰ 쀑...")
309
+ # μžλ™ μ—…λ°μ΄νŠΈ 둜직
310
+ dashboard_html_cache = generate_html(TARGETS)
311
+ last_update_time = now
312
+ logging.info(f"일일 μƒνƒœ 체크 μ™„λ£Œ: {now.strftime('%Y.%m.%d %H:%M:%S')}")
313
+ time.sleep(60) # 쀑볡 μ‹€ν–‰ λ°©μ§€
314
+ time.sleep(30) # 30μ΄ˆλ§ˆλ‹€ μ‹œκ°„ 확인
315
+
316
+ # λŒ€μ‹œλ³΄λ“œ κ°€μ Έμ˜€κΈ° ν•¨μˆ˜
317
+ def get_dashboard():
318
+ global dashboard_html_cache, last_update_time
319
+ # μΊμ‹œκ°€ λΉ„μ–΄μžˆκ±°λ‚˜ λ§ˆμ§€λ§‰ μ—…λ°μ΄νŠΈ ν›„ 1μ‹œκ°„μ΄ μ§€λ‚¬μœΌλ©΄ μƒˆλ‘œ μ—…λ°μ΄νŠΈ
320
+ if dashboard_html_cache == "" or last_update_time is None or \
321
+ (datetime.datetime.now(KST) - last_update_time).seconds > 3600:
322
+ return update_dashboard()
323
+
324
+ # μΊμ‹œλœ HTML에 ν˜„μž¬ μ‹œκ°„ μΆ”κ°€
325
+ current_time = datetime.datetime.now(KST).strftime('%Y.%m.%d %H:%M:%S')
326
+ return f"{dashboard_html_cache}<p style='color: #7A7A7A;'>μ—…λ°μ΄νŠΈ μ‹œκ°„: {current_time} (μΊμ‹œλ¨)</p>"
327
+
328
+ # μ•± 생성 ν•¨μˆ˜
329
+ def create_app():
330
+ # CSS μŠ€νƒ€μΌ μ •μ˜ - ν‘Έν„° μˆ¨κΉ€ 및 μΆ”κ°€ μŠ€νƒ€μΌ
331
+ custom_css = """
332
+ footer {visibility: hidden}
333
+ .gradio-container {max-width: 1200px}
334
+ .login-container {max-width: 500px; margin: 0 auto; padding: 20px;}
335
+ """
336
+
337
+ with gr.Blocks(css=custom_css) as app:
338
+ # 둜그인 νŽ˜μ΄μ§€
339
+ with gr.Group(visible=True, elem_classes="login-container") as login_page:
340
+ gr.Markdown("# μ„œλΉ„μŠ€ λŒ€μ‹œλ³΄λ“œ 둜그인")
341
+ gr.Markdown("ν—ˆκΉ…νŽ˜μ΄μŠ€ μ„œλΉ„μŠ€ λŒ€μ‹œλ³΄λ“œμ— μ ‘μ†ν•˜λ €λ©΄ λ‘œκ·ΈμΈν•˜μ„Έμš”.")
342
+ username_input = gr.Textbox(label="아이디", placeholder="아이디λ₯Ό μž…λ ₯ν•˜μ„Έμš”")
343
+ password_input = gr.Textbox(label="λΉ„λ°€λ²ˆν˜Έ", placeholder="λΉ„λ°€λ²ˆν˜Έλ₯Ό μž…λ ₯ν•˜μ„Έμš”", type="password")
344
+ login_btn = gr.Button("둜그인", variant="primary", scale=1)
345
+ login_message = gr.Textbox(label="μƒνƒœ", interactive=False, visible=False)
346
+
347
+ # 메인 λŒ€μ‹œλ³΄λ“œ νŽ˜μ΄μ§€
348
+ with gr.Group(visible=False) as dashboard_page:
349
+ with gr.Row():
350
+ gr.Markdown("# ν—ˆκΉ…νŽ˜μ΄μŠ€ μ„œλΉ„μŠ€ λŒ€μ‹œλ³΄λ“œ")
351
+
352
+ with gr.Row():
353
+ refresh_button = gr.Button("μƒνƒœ μƒˆλ‘œκ³ μΉ¨", variant="primary")
354
+ logout_button = gr.Button("λ‘œκ·Έμ•„μ›ƒ", variant="secondary")
355
+
356
+ status_html = gr.HTML()
357
+
358
+ # 둜그인 이벀트 μ„€μ •
359
+ login_btn.click(
360
+ fn=process_login,
361
+ inputs=[username_input, password_input],
362
+ outputs=[login_page, dashboard_page, login_message, status_html]
363
+ )
364
+
365
+ # λŒ€μ‹œλ³΄λ“œ μƒˆλ‘œκ³ μΉ¨ 이벀트 μ„€μ •
366
+ refresh_button.click(
367
+ fn=update_dashboard,
368
+ outputs=status_html
369
+ )
370
+
371
+ # λ‘œκ·Έμ•„μ›ƒ 이벀트 μ„€μ •
372
+ logout_button.click(
373
+ fn=process_logout,
374
+ outputs=[login_page, dashboard_page, login_message, status_html]
375
+ )
376
+
377
+ # μŠ€μΌ€μ€„λŸ¬ μŠ€λ ˆλ“œ μ‹€ν–‰
378
+ threading.Thread(target=schedule_daily_check, daemon=True).start()
379
+
380
+ return app
381
+
382
+ # 메인 μ‹€ν–‰ μ½”λ“œ
383
+ if __name__ == "__main__":
384
+ app = create_app()
385
+ app.launch(share=False, server_name="0.0.0.0", server_port=7860)