admin commited on
Commit
751f3b1
·
1 Parent(s): 8fc3eaa
Files changed (9) hide show
  1. .gitattributes +13 -11
  2. .gitignore +4 -0
  3. README.md +6 -6
  4. activate.py +157 -0
  5. app.py +41 -17
  6. config.py +34 -0
  7. restart.py +23 -0
  8. smtp.py +44 -0
  9. times.py +21 -0
.gitattributes CHANGED
@@ -1,35 +1,37 @@
1
  *.7z filter=lfs diff=lfs merge=lfs -text
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
 
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
10
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
  *.model filter=lfs diff=lfs merge=lfs -text
13
  *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
  *.onnx filter=lfs diff=lfs merge=lfs -text
17
  *.ot filter=lfs diff=lfs merge=lfs -text
18
  *.parquet filter=lfs diff=lfs merge=lfs -text
19
  *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
  *.pt filter=lfs diff=lfs merge=lfs -text
23
  *.pth filter=lfs diff=lfs merge=lfs -text
24
  *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
  *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
  *.tflite filter=lfs diff=lfs merge=lfs -text
30
  *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
  *.xz filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
1
  *.7z filter=lfs diff=lfs merge=lfs -text
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bin.* filter=lfs diff=lfs merge=lfs -text
5
  *.bz2 filter=lfs diff=lfs merge=lfs -text
 
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
10
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
 
11
  *.model filter=lfs diff=lfs merge=lfs -text
12
  *.msgpack filter=lfs diff=lfs merge=lfs -text
 
 
13
  *.onnx filter=lfs diff=lfs merge=lfs -text
14
  *.ot filter=lfs diff=lfs merge=lfs -text
15
  *.parquet filter=lfs diff=lfs merge=lfs -text
16
  *.pb filter=lfs diff=lfs merge=lfs -text
 
 
17
  *.pt filter=lfs diff=lfs merge=lfs -text
18
  *.pth filter=lfs diff=lfs merge=lfs -text
19
  *.rar filter=lfs diff=lfs merge=lfs -text
 
20
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
21
  *.tar.* filter=lfs diff=lfs merge=lfs -text
 
22
  *.tflite filter=lfs diff=lfs merge=lfs -text
23
  *.tgz filter=lfs diff=lfs merge=lfs -text
 
24
  *.xz filter=lfs diff=lfs merge=lfs -text
25
  *.zip filter=lfs diff=lfs merge=lfs -text
26
+ *.zstandard filter=lfs diff=lfs merge=lfs -text
27
+ *.tfevents* filter=lfs diff=lfs merge=lfs -text
28
+ *.db* filter=lfs diff=lfs merge=lfs -text
29
+ *.ark* filter=lfs diff=lfs merge=lfs -text
30
+ **/*ckpt*data* filter=lfs diff=lfs merge=lfs -text
31
+ **/*ckpt*.meta filter=lfs diff=lfs merge=lfs -text
32
+ **/*ckpt*.index filter=lfs diff=lfs merge=lfs -text
33
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
34
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
35
+ *.gguf* filter=lfs diff=lfs merge=lfs -text
36
+ *.ggml filter=lfs diff=lfs merge=lfs -text
37
+ *.llamafile* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ test.*
2
+ rename.sh
3
+ *__pycache__*
4
+ *.txt
README.md CHANGED
@@ -1,12 +1,12 @@
1
  ---
2
- title: URL Shortner
3
- emoji: 🔗
4
- colorFrom: gray
5
- colorTo: green
6
  sdk: gradio
7
- sdk_version: 5.23.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
- short_description: Convert long urls into short, easy-to-share links
12
  ---
 
1
  ---
2
+ title: ksa
3
+ emoji: 󠁪󠀣󠀷󠀷󠀫󠀫📊
4
+ colorFrom: yellow
5
+ colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 5.22.0
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
+ short_description: --
12
  ---
activate.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import time
3
+ import requests
4
+ import threading
5
+ from tqdm import tqdm
6
+ from huggingface_hub import HfApi
7
+ from smtp import send_email
8
+ from config import *
9
+
10
+
11
+ def get_space_status(repo_id: str):
12
+ response: list = requests.get(
13
+ url=f"{HF_DOMAIN}/api/spaces/semantic-search",
14
+ params={"q": repo_id},
15
+ headers=HEADER,
16
+ timeout=TIMEOUT,
17
+ ).json()
18
+
19
+ if not (response and response[0]["id"] == repo_id):
20
+ return "SLEEPING" # 口袋罪
21
+
22
+ return response[0]["runtime"]["stage"]
23
+
24
+
25
+ def get_spaces(username: str):
26
+ sleepings, errors = [], []
27
+ try:
28
+ spaces = HfApi().list_spaces(author=username)
29
+ for space in spaces:
30
+ status = get_space_status(space.id)
31
+ if status == "SLEEPING":
32
+ space_id = space.id.replace("/", "-").replace("_", "-").lower()
33
+ if space.sdk == "gradio":
34
+ sleepings.append(f"https://{space_id}.hf.space")
35
+ else:
36
+ sleepings.append(f"https://{space_id}.static.hf.space")
37
+
38
+ elif "ERROR" in status:
39
+ errors.append(f"{HF_DOMAIN}/spaces/{space.id}")
40
+
41
+ return sleepings, errors
42
+
43
+ except Exception as e:
44
+ print(f"An error occurred in the request: {e}")
45
+
46
+ return [], []
47
+
48
+
49
+ def activate_space(url: str):
50
+ try:
51
+ response = requests.get(url, headers=HEADER, timeout=TIMEOUT)
52
+ response.raise_for_status()
53
+
54
+ except Exception as e:
55
+ print(e)
56
+
57
+
58
+ def get_studios(username: str):
59
+ try:
60
+ response = requests.put(
61
+ f"{MS_DOMAIN}/api/v1/studios/{username}/list",
62
+ data=json.dumps(
63
+ {
64
+ "PageNumber": 1,
65
+ "PageSize": 1000,
66
+ "Name": "",
67
+ "SortBy": "gmt_modified",
68
+ "Order": "desc",
69
+ }
70
+ ),
71
+ headers=HEADER,
72
+ timeout=TIMEOUT,
73
+ )
74
+ response.raise_for_status()
75
+ spaces: list = response.json()["Data"]["Studios"]
76
+ if spaces:
77
+ studios, errors = [], []
78
+ for space in spaces:
79
+ status = space["Status"]
80
+ if status == "Expired":
81
+ studios.append(f"{username}/{space['Name']}")
82
+ elif status == "Failed":
83
+ errors.append(f"{MS_DOMAIN}/studios/{username}/{space['Name']}")
84
+
85
+ return studios, errors
86
+
87
+ except requests.exceptions.Timeout as e:
88
+ print(f"Timeout: {e}, retrying...")
89
+ time.sleep(DELAY)
90
+ return get_studios(username)
91
+
92
+ except Exception as e:
93
+ print(f"Requesting error: {e}")
94
+
95
+ return [], []
96
+
97
+
98
+ def activate_studio(repo: str, holding_delay=5):
99
+ repo_page = f"{MS_DOMAIN}/studios/{repo}"
100
+ status_api = f"{MS_DOMAIN}/api/v1/studio/{repo}/status"
101
+ start_expired_api = f"{MS_DOMAIN}/api/v1/studio/{repo}/start_expired"
102
+ try:
103
+ response = requests.put(start_expired_api, headers=HEADER, timeout=TIMEOUT)
104
+ response.raise_for_status()
105
+ while (
106
+ requests.get(status_api, headers=HEADER, timeout=TIMEOUT).json()["Data"][
107
+ "Status"
108
+ ]
109
+ != "Running"
110
+ ):
111
+ requests.get(repo_page, headers=HEADER, timeout=TIMEOUT)
112
+ time.sleep(holding_delay)
113
+
114
+ except requests.exceptions.Timeout as e:
115
+ print(f"Failed to activate {repo}: {e}, retrying...")
116
+ activate_studio(repo)
117
+
118
+ except Exception as e:
119
+ print(e)
120
+
121
+
122
+ def trigger(users=USERS):
123
+ spaces, studios, failures = [], [], []
124
+ usernames = users.split(";")
125
+ for user in tqdm(usernames, desc="Collecting spaces"):
126
+ username = user.strip()
127
+ if username:
128
+ sleeps, errors = get_spaces(username)
129
+ spaces += sleeps
130
+ failures += errors
131
+ time.sleep(DELAY)
132
+
133
+ for space in tqdm(spaces, desc="Activating spaces"):
134
+ activate_space(space)
135
+ time.sleep(DELAY)
136
+
137
+ for user in tqdm(usernames, desc="Collecting studios"):
138
+ username = user.strip()
139
+ if username:
140
+ sleeps, errors = get_studios(username)
141
+ studios += sleeps
142
+ failures += errors
143
+ time.sleep(DELAY)
144
+
145
+ for studio in tqdm(studios, desc="Activating studios"):
146
+ threading.Thread(target=activate_studio, args=(studio,), daemon=True).start()
147
+ time.sleep(DELAY)
148
+
149
+ print("\n".join(spaces + studios) + "\nActivation complete!")
150
+ content = ""
151
+ for failure in failures:
152
+ errepo: str = failure
153
+ errepo = errepo.replace(HF_DOMAIN, "").replace(MS_DOMAIN, "")
154
+ content += f"<br><a href='{failure}'>{errepo[1:]}</a><br>"
155
+
156
+ if content:
157
+ send_email(content)
app.py CHANGED
@@ -1,27 +1,51 @@
1
- import subprocess
 
 
2
  import gradio as gr
 
 
 
 
3
 
4
 
5
- # 定义推理函数
6
- def infer(command):
7
- try:
8
- return subprocess.check_output(
9
- command,
10
- shell=True,
11
- stderr=subprocess.STDOUT,
12
- text=True,
13
- )
14
 
15
- except subprocess.CalledProcessError as e:
16
- return f"Error: {e.output}" # 返回错误信息
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  if __name__ == "__main__":
 
20
  gr.Interface(
21
- fn=infer, # 推理函数
22
- inputs=gr.Textbox(label="输入 Linux 命令", value="ls"),
23
- outputs=gr.TextArea(label="执行结果", show_copy_button=True),
24
- title="Linux 命令执行测试工具", # 接口标题
25
- description="输入一个 Linux 命令, 点击提交查看其执行结果",
26
  flagging_mode="never",
27
  ).launch()
 
1
+ import time
2
+ import schedule
3
+ import threading
4
  import gradio as gr
5
+ from activate import trigger
6
+ from restart import restart
7
+ from config import *
8
+ from times import *
9
 
10
 
11
+ def run_schedule():
12
+ global START_TIME
13
+ START_TIME = datetime.now()
14
+ trigger()
15
+ while True:
16
+ schedule.run_pending()
17
+ time.sleep(DELAY)
 
 
18
 
19
+
20
+ def monitor(period=PERIOD):
21
+ print(f"Monitor is on and triggered every {period}h...")
22
+ schedule.every(int(period)).hours.do(trigger)
23
+ threading.Thread(target=run_schedule, daemon=True).start()
24
+ schedule.every(47).hours.do(restart)
25
+
26
+
27
+ def tasklist():
28
+ running4 = f"Has been running for {time_diff(START_TIME, datetime.now())}"
29
+ print(running4)
30
+ outputs = ""
31
+ jobs = schedule.get_jobs()
32
+ for job in jobs:
33
+ last_run = fix_datetime(job.last_run)
34
+ if not last_run:
35
+ last_run = "never"
36
+
37
+ next_run = fix_datetime(job.next_run)
38
+ outputs += f"Every {job.interval}h do {job.job_func} (last run: {last_run}, next run: {next_run})\n\n"
39
+
40
+ return f"{outputs}{running4}"
41
 
42
 
43
  if __name__ == "__main__":
44
+ monitor()
45
  gr.Interface(
46
+ title="See current task status",
47
+ fn=tasklist,
48
+ inputs=None,
49
+ outputs=gr.TextArea(label="Current task details"),
 
50
  flagging_mode="never",
51
  ).launch()
config.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ PERIOD = os.getenv("period")
4
+ USERS = os.getenv("users")
5
+ API = os.getenv("api")
6
+ EMAIL = os.getenv("email")
7
+ SMTP = os.getenv("smtp")
8
+ COOKIE = os.getenv("cookie")
9
+ if not (PERIOD and USERS and API and EMAIL and SMTP and COOKIE):
10
+ print("Please check the environment variables!")
11
+ exit()
12
+ else:
13
+ PERIOD = int(PERIOD)
14
+
15
+ TAG = os.getenv("target")
16
+ if not TAG:
17
+ TAG = EMAIL
18
+
19
+ HOST = os.getenv("host")
20
+ PORT = os.getenv("port")
21
+ if not (HOST and PORT):
22
+ HOST = "smtp.qq.com"
23
+ PORT = 587
24
+ else:
25
+ PORT = int(PORT)
26
+
27
+ DELAY = 1
28
+ TIMEOUT = 15
29
+ START_TIME = None
30
+ HF_DOMAIN = "https://huggingface.co"
31
+ MS_DOMAIN = "https://www.modelscope.cn"
32
+ HEADER = {
33
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537"
34
+ }
restart.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from smtp import send_email
3
+ from config import *
4
+
5
+
6
+ def restart_private_space(repo: str, cookie: str):
7
+ try:
8
+ response = requests.post(
9
+ f"{HF_DOMAIN}/api/spaces/{repo}/restart",
10
+ headers={
11
+ "User-Agent": HEADER["User-Agent"],
12
+ "cookie": cookie,
13
+ },
14
+ timeout=TIMEOUT,
15
+ )
16
+ response.raise_for_status()
17
+
18
+ except Exception as e:
19
+ send_email(f"{e}", "Restart failure", f"Failed to restart {repo}")
20
+
21
+
22
+ def restart():
23
+ restart_private_space("kakamond/ksa", COOKIE)
smtp.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from config import *
3
+
4
+
5
+ def send_email(
6
+ content,
7
+ title="Runtime error detected",
8
+ header="Please fix following repo(s):",
9
+ email=EMAIL,
10
+ password=SMTP,
11
+ target=TAG,
12
+ host=HOST,
13
+ port=PORT,
14
+ ):
15
+ body = f"""
16
+ <html>
17
+ <body>
18
+ <h2>{header}</h2>
19
+ {content}
20
+ </body>
21
+ </html>
22
+ """
23
+ response = requests.get(
24
+ API,
25
+ params={
26
+ "host": host,
27
+ "Port": port,
28
+ "key": password, # apikey
29
+ "email": email, # from
30
+ "mail": target, # to
31
+ "title": title, # subject
32
+ "name": "ksa", # nickname
33
+ "text": body, # content
34
+ },
35
+ )
36
+ if response.status_code == 200:
37
+ result: dict = response.json()
38
+ if result.get("status") == "success":
39
+ print("Email sent successfully!")
40
+ else:
41
+ print(f"Failed to send email: {result.get('message')}")
42
+
43
+ else:
44
+ print(f"Request failed with status code: {response.status_code}")
times.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+ from zoneinfo import ZoneInfo
3
+ from tzlocal import get_localzone
4
+
5
+
6
+ def fix_datetime(naive_time: datetime, target_tz=ZoneInfo("Asia/Shanghai")):
7
+ if not naive_time:
8
+ return None
9
+
10
+ local_tz = get_localzone()
11
+ aware_local = naive_time.replace(tzinfo=local_tz)
12
+ return aware_local.astimezone(target_tz).strftime("%Y-%m-%d %H:%M:%S")
13
+
14
+
15
+ def time_diff(time1: datetime, time2: datetime):
16
+ t_diff = time2 - time1
17
+ days = t_diff.days
18
+ hours = t_diff.seconds // 3600
19
+ minutes = (t_diff.seconds % 3600) // 60
20
+ seconds = t_diff.seconds % 60
21
+ return f"{days} d {hours} h {minutes} m {seconds} s"