Compare commits

...

70 Commits
v1.0.9 ... main

Author SHA1 Message Date
7ee3eb377e 修复macOS挂载点检查逻辑,确保正确处理系统和应用程序目录
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 21s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m43s
2024-12-10 13:14:10 +08:00
90b4952ea9 修复macOS挂载点检查逻辑,确保正确处理根挂载点
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 17s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m47s
2024-12-10 13:10:44 +08:00
0559212d03 修复macOS分区监控逻辑,确保正确处理挂载点
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 45s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m39s
2024-12-10 13:07:01 +08:00
e74324e21b 修复平台名称大小写问题,确保Linux和macOS的分区监控逻辑正确
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 21s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m54s
2024-12-09 00:30:34 +08:00
48ac46bbb3 增加客户端启动日志并优化线程启动逻辑
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 43s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m8s
2024-12-09 00:26:16 +08:00
b5ba568a66 支持macOS的磁盘分区监控,重构观察逻辑
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 1m0s
Compile / build (x64, ubuntu-latest) (push) Failing after 4m31s
2024-12-08 23:50:45 +08:00
b30b3429ad 新增排序功能
Some checks failed
Compile / build (x64, ubuntu-latest) (push) Failing after 1m27s
Compile / build (x64, windows-latest) (push) Has been cancelled
2024-10-11 01:15:39 +08:00
7cbca85a60 修复部分linux获取发行版错误的问题
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 10s
Compile / build (x64, ubuntu-latest) (push) Failing after 15s
2024-10-06 04:39:04 +08:00
ce3a07e350 修复部分linux获取发行版错误的问题 2024-10-06 04:36:54 +08:00
9160e7c4b4 修复部分linux获取发行版错误的问题 2024-10-06 04:35:07 +08:00
8e2c5c24b8 安装脚本添加本地化 2024-10-06 04:32:12 +08:00
c63d84106b 安装脚本添加本地化 2024-10-06 02:17:41 +08:00
0d7b7700de 修复脚本执行错误 2024-10-05 23:13:33 +08:00
b5bf2c1de6 修复脚本执行错误 2024-10-05 23:08:40 +08:00
87418edeea 修复脚本执行错误
Some checks failed
Compile / build (x64, ubuntu-latest) (push) Failing after 15s
Compile / build (x64, windows-latest) (push) Failing after 21s
2024-10-05 23:01:17 +08:00
5c089873ca 修复脚本执行错误
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 14s
Compile / build (x64, ubuntu-latest) (push) Failing after 1m35s
2024-10-05 22:56:04 +08:00
79242f9dd6 修复脚本执行错误 2024-10-05 22:54:33 +08:00
22feee38ee 修复脚本执行错误
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 13s
Compile / build (x64, ubuntu-latest) (push) Failing after 3m6s
2024-10-05 22:50:41 +08:00
e0aa6adbeb 修复脚本执行错误 2024-10-05 22:48:40 +08:00
87859a58f8 修复脚本执行错误 2024-10-05 22:46:31 +08:00
d1098cf735 Merge remote-tracking branch 'origin/main' 2024-10-05 22:25:32 +08:00
62096e5f4d 修复脚本执行错误 2024-10-05 22:25:17 +08:00
26db6fe7d0
Create LICENSE 2024-10-05 22:04:50 +08:00
3b09c0650d 修复脚本执行错误 2024-10-05 22:02:53 +08:00
fb7e3144d3 修复脚本执行错误 2024-10-05 21:57:48 +08:00
c271378c71 修复脚本执行错误
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 38s
Compile / build (x64, ubuntu-latest) (push) Failing after 3m7s
2024-10-05 21:52:39 +08:00
5834abcd33 修复脚本执行错误 2024-10-05 21:50:12 +08:00
67475ef499 修复脚本执行错误 2024-10-05 21:20:22 +08:00
42c4db6c01 修复脚本执行错误 2024-10-05 21:02:50 +08:00
4af3579d70 新增Linux安装脚本 2024-10-05 20:53:58 +08:00
cd56065e32 os字段新增版本和发行版
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 19s
Compile / build (x64, ubuntu-latest) (push) Failing after 35s
2024-10-05 05:34:26 +08:00
3c960896f4 修复运行时间错误的问题
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 36s
Compile / build (x64, ubuntu-latest) (push) Failing after 1m27s
2024-10-05 03:21:33 +08:00
c2a3966f37 修复运行时间错误的问题 2024-10-05 03:21:01 +08:00
3fa94f653d 修复运行时间错误的问题
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 39s
Compile / build (x64, ubuntu-latest) (push) Failing after 2m24s
2024-10-04 08:29:49 +08:00
4cb1fcdb21 添加系统启动时间 2024-10-04 07:46:00 +08:00
657cd1a80f 添加系统启动时间 2024-10-04 07:34:28 +08:00
3d14b5a18e 添加系统启动时间 2024-10-04 07:33:16 +08:00
2c3cda6e46 排除linux下无关分区
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 20s
Compile / build (x64, ubuntu-latest) (push) Failing after 35s
2024-10-03 18:49:28 +08:00
e03c99a9f6 排除linux下无关分区 2024-10-03 17:42:28 +08:00
db7aeabe7b 排除linux下无关分区
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 14s
Compile / build (x64, ubuntu-latest) (push) Failing after 12m41s
2024-10-03 17:38:10 +08:00
89d7fa3145 提升上报时间
Some checks failed
Compile / build (x64, windows-latest) (push) Failing after 1m54s
Compile / build (x64, ubuntu-latest) (push) Has been cancelled
2024-10-03 17:28:57 +08:00
833c96cbc5 修复CPU物理核心计算错误 2024-10-03 17:03:57 +08:00
2e4fd493c5 修复CPU物理核心计算错误 2024-10-03 17:03:15 +08:00
0360e58cc1 add source 2024-10-03 14:48:38 +08:00
7c74a40d45 remove dev dep 2024-10-03 14:46:27 +08:00
5c649089ff remove pdm.lock 2024-10-03 14:46:04 +08:00
331297691a remove pdm.lock 2024-10-03 14:46:01 +08:00
eb6a57d5a7 降低python版本依赖 2024-10-03 11:43:23 +08:00
b6f6eba1cf 降低python版本依赖 2024-10-03 02:31:08 +08:00
aca1074b12 降低python版本依赖 2024-10-03 02:29:00 +08:00
a859a975a2 降低python版本依赖 2024-10-03 02:28:07 +08:00
993cd3409a 降低python版本依赖 2024-10-03 02:26:22 +08:00
d86141e83d 降低python版本依赖 2024-10-03 02:26:14 +08:00
2dc156288b 降低python版本依赖 2024-10-03 02:24:09 +08:00
cd8fd6bb87 降低python版本依赖 2024-10-03 02:21:27 +08:00
1935faa1f2 降低python版本依赖 2024-10-03 02:19:40 +08:00
c97544cda3 降低python版本依赖 2024-10-03 02:18:47 +08:00
b57bb4ec10 降低python版本依赖 2024-10-03 02:16:45 +08:00
afbedc665c 降低python版本依赖 2024-10-03 02:15:21 +08:00
575203aedc 降低python版本依赖 2024-10-03 02:13:10 +08:00
dd596f0a93 降低python版本依赖 2024-10-03 02:12:07 +08:00
42d5795335 降低python版本依赖 2024-10-03 02:11:22 +08:00
4064f904d0 降低python版本依赖 2024-10-03 02:07:31 +08:00
521af9695c 降低python版本依赖 2024-10-03 02:07:25 +08:00
62903a6680 降低python版本依赖 2024-10-03 02:07:14 +08:00
5f33564d3f 降低python版本依赖 2024-10-03 01:54:21 +08:00
02af22862d 降低python版本依赖 2024-10-03 01:52:36 +08:00
9ccb98b1f8 降低python版本依赖 2024-10-03 01:52:07 +08:00
55ba28d98d 降低python版本依赖 2024-10-03 01:49:52 +08:00
0b60781f3a 降低python版本依赖 2024-10-03 01:48:41 +08:00
14 changed files with 545 additions and 280 deletions

View File

@ -1,16 +1,16 @@
name: Publish name: Compile
on: on:
push: push:
tags: branches:
- '*' - main
jobs: jobs:
build: build:
strategy: strategy:
matrix: matrix:
os: [macos-latest, ubuntu-latest, windows-latest] os: [ ubuntu-latest, windows-latest ]
arch: [amd64, arm64, arm, 386] arch: [ x64]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -21,12 +21,13 @@ jobs:
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: '3.10' # Version range or exact version of a Python version to use, using SemVer's version range syntax python-version: '3.11'
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified architecture: ${{ matrix.arch }}
cache: 'pip' cache: 'pip'
cache-dependency-path: | cache-dependency-path: |
**/requirements*.txt **/requirements*.txt
- name: Install Dependencies - name: Install Dependencies
run: | run: |
pip install pdm pip install pdm
@ -36,8 +37,10 @@ jobs:
uses: Nuitka/Nuitka-Action@main uses: Nuitka/Nuitka-Action@main
with: with:
nuitka-version: main nuitka-version: main
script-name: server_status.__main__ script-name: main.py
onefile: true onefile: true
standalone: true
follow-imports: true
- name: Upload Artifacts - name: Upload Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3

4
.gitignore vendored
View File

@ -121,6 +121,10 @@ celerybeat.pid
# SageMath parsed files # SageMath parsed files
*.sage.py *.sage.py
pdm.lock
start.cmd
start.sh
# Environments # Environments
.env .env
.venv .venv

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Snowykami
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,4 +1,3 @@
<div align="center"> <div align="center">
# server-status-client # server-status-client
@ -20,30 +19,49 @@ _✨ 服务器状态 - 客户端 ✨_
服务器状态的客户端命令行工具 服务器状态的客户端命令行工具
- 跨平台支持
- 自动上报服务器状态
- 支持自定义标签、地域、链接等信息
## 💿 安装 ## 💿 安装
- 先决条件:`curl` `python3` `pip` `venv` `git`
<details open> - Linux 可使用脚本安装,带自动部署和自启动
<summary>使用 pip 安装(确保包路径在环境变量下)</summary>
pip install server-status ```shell
sudo bash -c "$(curl -sSL https://raw.githubusercontent.com/snowykami/server-status-client/refs/heads/main/deploy.sh)"
```
如果位于中国大陆无法访问GitHub可使用中国版脚本
```shell
sudo bash -c "$(curl -sSL https://git.liteyuki.icu/snowykami/server-status-client/raw/branch/main/deploy-cn.sh)"
```
</details> - 或手动部署
Debian系请使用pipx安装 ```shell
# 克隆仓库
git clone https://github.com/snowykami/server-status-client
cd server-status-client
```bash # 配置环境
sudo apt install pipx python3 -m venv venv
sudo pipx install server-status source venv/bin/activate
``` # 安装依赖
pip install pdm
pdm install
# 如需自启动请自行添加到系统服务
```
## 🎉 使用 ## 🎉 使用
### 命令 ### 命令
- `server-status <server> <token> <id> run` - 运行客户端 - `python main.py <server> <token> <id> run` - 运行客户端
- `server-status <server> <token> <id> rm` - 从服务端移除主机 - `python.main.py <server> <token> <id> rm` - 从服务端移除主机
#### 可选项 #### 可选项
- `-n|--name` - 设置主机名称 - `-n|--name` - 设置主机名称
- `--labels` - 设置主机标签 - `--labels` - 设置主机标签
- `--interval` - 设置上报间隔 - `--interval` - 设置上报间隔
@ -51,36 +69,22 @@ sudo pipx install server-status
- `--link` - 设置前端点击跳转链接 - `--link` - 设置前端点击跳转链接
#### 示例 #### 示例
```shell ```shell
server_status https://status.liteyuki.icu 114514 myhost run -n "MyHost" --labels "标签1,标签2" --interval 5 --location "Chongqing" --link "https://example.com" python main.py https://status.liteyuki.icu 114514 myhost run -n "MyHost" --labels "标签1,标签2" --interval 5 --location "Chongqing" --link "https://example.com"
``` ```
## 📝 其他 ## 📝 其他
### 开机启动 ### 开机启动
执行以下命令
- 安装脚本已自动添加到系统服务
### 更新
```shell ```shell
sudo pipx ensurepath # 确保pipx路径在环境变量下 git pull
sudo systemctl restart server-status-client
sudo touch /etc/systemd/system/server-status-client.service
sudo bash -c 'cat <<EOF > /etc/systemd/system/server-status-client.service
[Unit]
Description=Server Status Client
After=network-online.target
[Service]
Type=simple
ExecStart=server-status <server> <token> <id> run # 请替换为实际参数
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
sudo systemctl enable server-status-client
sudo systemctl start server-status-client
``` ```
### 服务端 ### 服务端

96
deploy-cn.sh Executable file
View File

@ -0,0 +1,96 @@
#!/bin/bash
# 部署脚本中国大陆可用版本
# check if sudo is used
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# check install dir
install_dir="/opt"
echo -n "安装目录? (默认: $install_dir/server-status-client): " && read -r install_dir_input
if [ -n "$install_dir_input" ]; then
install_dir="$install_dir_input"
fi
# check server
echo -n "服务端地址? (必须): " && read -r server
if [ -z "$server" ]; then
echo "服务端地址是必须的"
exit 1
fi
# check token
echo -n "令牌? (必须或留空): " && read -r token
# check hostname
hostname=$(hostname)
echo -n "此主机名? (默认: $hostname): " && read -r hostname_input
if [ -n "$hostname_input" ]; then
hostname="$hostname_input"
fi
# labels
echo -n "标签们? (空格分隔): " && read -r labels_input
if [ -n "$labels_input" ]; then
labels="$labels_input"
fi
# location
echo -n "地理位置? (可选|自定义): " && read -r location_input
if [ -n "$location_input" ]; then
location="$location_input"
fi
repo2="https://git.liteyuki.icu/snowykami/server-status-client"
# try 1 if failed try 2
git clone "$repo2" "$install_dir/server-status-client"
cd "$install_dir/server-status-client" || { echo "克隆失败"; exit 1; }
# create venv
python3 -m venv venv
python_exe="./venv/bin/python"
# check if venv is created
if [ ! -f "$python_exe" ]; then
echo "创建虚拟环境失败"
exit 1
fi
echo "虚拟环境创建成功"
# install the required packages
echo "正在安装依赖包..."
$python_exe -m pip install pdm -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
$python_exe -m pdm install
# create the systemd service
echo "正在创建服务..."
# generate random id
# shellcheck disable=SC2002
id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
bash -c "cat <<EOF > /etc/systemd/system/server-status-client.service
[Unit]
Description=Server Status Client
After=network-online.target
[Service]
Type=simple
ExecStart=$install_dir/server-status-client/venv/bin/python main.py $server $token $id run -n $hostname --labels $labels --location $location
WorkingDirectory=$install_dir/server-status-client
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF"
# enable and start the service
systemctl enable server-status-client
systemctl start server-status-client
echo "安装完成,服务已启动"

0
deploy.cmd Normal file
View File

99
deploy.sh Executable file
View File

@ -0,0 +1,99 @@
#!/bin/bash
# check if sudo is used
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# check install dir
install_dir="/opt"
echo -n "Install directory? (default: $install_dir/server-status-client): " && read -r install_dir_input
if [ -n "$install_dir_input" ]; then
install_dir="$install_dir_input"
fi
# check server
echo -n "Server? (required): " && read -r server
if [ -z "$server" ]; then
echo "Server is required"
exit 1
fi
# check token
echo -n "Token? (required): " && read -r token
if [ -z "$token" ]; then
echo "Token is required"
exit 1
fi
# check hostname
hostname=$(hostname)
echo -n "Hostname? (default: $hostname): " && read -r hostname_input
if [ -n "$hostname_input" ]; then
hostname="$hostname_input"
fi
# labels
echo -n "Labels? (space separated): " && read -r labels_input
if [ -n "$labels_input" ]; then
labels="$labels_input"
fi
# location
echo -n "Location? (optional): " && read -r location_input
if [ -n "$location_input" ]; then
location="$location_input"
fi
# clone repo
repo1="https://github.com/snowykami/server-status-client"
repo2="https://git.liteyuki.icu/snowykami/server-status-client"
# try 1 if failed try 2
git clone "$repo1" "$install_dir/server-status-client" || git clone "$repo2" "$install_dir/server-status-client"
cd "$install_dir/server-status-client" || { echo "Failed to clone repo"; exit 1; }
# create venv
python3 -m venv venv
python_exe="./venv/bin/python"
# check if venv is created
if [ ! -f "$python_exe" ]; then
echo "Failed to create venv"
exit 1
fi
echo "venv created successfully"
# install the required packages
echo "Installing the required packages"
$python_exe -m pip install pdm
$python_exe -m pdm install
# create the systemd service
echo "Creating the systemd service"
# generate random id
# shellcheck disable=SC2002
id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
bash -c "cat <<EOF > /etc/systemd/system/server-status-client.service
[Unit]
Description=Server Status Client
After=network-online.target
[Service]
Type=simple
ExecStart=$install_dir/server-status-client/venv/bin/python main.py $server $token $id run -n $hostname --labels $labels --location $location
WorkingDirectory=$install_dir/server-status-client
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF"
# enable and start the service
systemctl enable server-status-client
systemctl start server-status-client
echo "server-status-client installed successfully"

7
main.py Normal file
View File

@ -0,0 +1,7 @@
import sys
from server_status.__main__ import main
if __name__ == "__main__":
print(sys.argv)
main()

193
pdm.lock generated
View File

@ -1,193 +0,0 @@
# This file is @generated by PDM.
# It is not intended for manual editing.
[metadata]
groups = ["default"]
strategy = ["inherit_metadata"]
lock_version = "4.5.0"
content_hash = "sha256:35d8de0fef9028880b4f2f9e77f90ea9296a7760777e2fc1851550bd188977b8"
[[metadata.targets]]
requires_python = ">=3.11"
[[package]]
name = "arclet-alconna"
version = "1.8.30"
requires_python = ">=3.8"
summary = "A High-performance, Generality, Humane Command Line Arguments Parser Library."
groups = ["default"]
dependencies = [
"nepattern<1.0.0,>=0.7.6",
"tarina>=0.5.8",
"typing-extensions>=4.5.0",
]
files = [
{file = "arclet_alconna-1.8.30-py3-none-any.whl", hash = "sha256:835bf4e8d5deeb78ced2687d49e958a28fe19e39d0fb0fc30d767143d3e41329"},
{file = "arclet_alconna-1.8.30.tar.gz", hash = "sha256:cdc064446c0db31285fd2cd4573d7fabe59b81e00e816b9f20f395f1c214b4ac"},
]
[[package]]
name = "certifi"
version = "2024.8.30"
requires_python = ">=3.6"
summary = "Python package for providing Mozilla's CA Bundle."
groups = ["default"]
files = [
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
]
[[package]]
name = "charset-normalizer"
version = "3.3.2"
requires_python = ">=3.7.0"
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
groups = ["default"]
files = [
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
{file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
{file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
{file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
{file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
]
[[package]]
name = "idna"
version = "3.10"
requires_python = ">=3.6"
summary = "Internationalized Domain Names in Applications (IDNA)"
groups = ["default"]
files = [
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
]
[[package]]
name = "nepattern"
version = "0.7.6"
requires_python = ">=3.8"
summary = "a complex pattern, support typing"
groups = ["default"]
dependencies = [
"tarina>=0.5.1",
"typing-extensions>=4.5.0",
]
files = [
{file = "nepattern-0.7.6-py3-none-any.whl", hash = "sha256:233d0befecc190f228ded3651a85faaf53f1308bba40ab8ddec379d0d3c88051"},
{file = "nepattern-0.7.6.tar.gz", hash = "sha256:07bd5b2f3b9b9739b703bf723ffd642ca93738a32df7b699d57d6f338d46bad0"},
]
[[package]]
name = "psutil"
version = "6.0.0"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
summary = "Cross-platform lib for process and system monitoring in Python."
groups = ["default"]
files = [
{file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"},
{file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"},
{file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"},
{file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"},
{file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"},
{file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"},
{file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"},
{file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"},
]
[[package]]
name = "requests"
version = "2.32.3"
requires_python = ">=3.8"
summary = "Python HTTP for Humans."
groups = ["default"]
dependencies = [
"certifi>=2017.4.17",
"charset-normalizer<4,>=2",
"idna<4,>=2.5",
"urllib3<3,>=1.21.1",
]
files = [
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[[package]]
name = "tarina"
version = "0.5.8"
requires_python = ">=3.8"
summary = "A collection of common utils for Arclet"
groups = ["default"]
dependencies = [
"typing-extensions>=4.4.0",
]
files = [
{file = "tarina-0.5.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9b730d605691c1afc074f684b77c12e921d8a0a278b80b5fc016ab2bf75ee081"},
{file = "tarina-0.5.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21dfdacf4ca5b46ecfbcd2ea92445abf9aced634aaef285fec8d914163261db8"},
{file = "tarina-0.5.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3162eace1e5193313f1523a943b5ae14464199782f235e87702da9ee3fb37a6"},
{file = "tarina-0.5.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:385882a2991046aa05f7b183f386ec2c949076aeacb4acad525ead63342d73f7"},
{file = "tarina-0.5.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76ee0f135cbe26549592fa12691cb057aa4464d4182c35d7d967361eba52ed95"},
{file = "tarina-0.5.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2c188c34143ae6bdcee13bac089845f1ca7d32169d85f172091550e0f34fda35"},
{file = "tarina-0.5.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a45e5f0fccd0267a15582b9d8cfa4b21fca5c1c690ced673f0f58869b98cb178"},
{file = "tarina-0.5.8-cp311-cp311-win32.whl", hash = "sha256:e554bd8e22a43ffc8f441d771585e81f90150de2f9e9d9a984c7b004bb613c10"},
{file = "tarina-0.5.8-cp311-cp311-win_amd64.whl", hash = "sha256:51c8b7ad1cc114efde36ab09687b5f93afde27ad082cd38721dc327c7f0d922d"},
{file = "tarina-0.5.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c95f227e7265cfce8c4fb5eebef2a148934b52b782527ded278a4e0926b90ceb"},
{file = "tarina-0.5.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a394bd75c92d39c0e4c1ee40404de24316f4263f10e296e8d4e19bd0a3c50e55"},
{file = "tarina-0.5.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9db70e6fb97ee8a87da52e9ced52ee6df7c468f75b72ef98af5a97929e12bc2d"},
{file = "tarina-0.5.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b713717dcafcd03a86f41509b6c9ebc2749419c9c8c6d559edd6fdfaca6f354"},
{file = "tarina-0.5.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccaf87a54e062a2d72a60d699198760684aca231c7de7de11d61c191d1e870bf"},
{file = "tarina-0.5.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a1dc7e8e84ab4e0d6bfb3e4e9c82c7d8a4c002794b7b44010658f0f81e8b5e52"},
{file = "tarina-0.5.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:dbc6e78e3ee9b24f9c0feb2c14c17d9696098abf6530ae63d6f4158ab7038c38"},
{file = "tarina-0.5.8-cp312-cp312-win32.whl", hash = "sha256:4e1a08f1c3d40f935cc8c9507b7ea669b002a53dc7334c9b0ede9f71cf9d1cba"},
{file = "tarina-0.5.8-cp312-cp312-win_amd64.whl", hash = "sha256:ab90fd830ec05d5f7cd001906fdd1a3e00d8c9fd221772d02bb87a7aec947925"},
{file = "tarina-0.5.8-py3-none-any.whl", hash = "sha256:90740760e9f516677962eff5242a722c616939b123c566a85d7e009ec9868eb3"},
{file = "tarina-0.5.8.tar.gz", hash = "sha256:ab5a8b901829242c64a8a0436c7753e894ccae36891ca20a9deda9de6210a0b3"},
]
[[package]]
name = "typing-extensions"
version = "4.12.2"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
groups = ["default"]
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]]
name = "urllib3"
version = "2.2.3"
requires_python = ">=3.8"
summary = "HTTP library with thread-safe connection pooling, file post, and more."
groups = ["default"]
files = [
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
]

View File

@ -9,6 +9,7 @@ dependencies = [
"requests>=2.32.3", "requests>=2.32.3",
"psutil>=6.0.0", "psutil>=6.0.0",
"arclet-alconna>=1.8.30", "arclet-alconna>=1.8.30",
"pytz>=2024.2",
] ]
requires-python = ">=3.10" requires-python = ">=3.10"
readme = "README.md" readme = "README.md"
@ -28,3 +29,7 @@ distribution = true
source = "scm" source = "scm"
tag_filter = "v*" tag_filter = "v*"
tag_regex = '^v(?:\D*)?(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|c|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$)$' tag_regex = '^v(?:\D*)?(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|c|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$)$'
[[tool.pdm.source]]
name = "pypi"
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"

View File

@ -6,6 +6,7 @@ from server_status.cmd_parser import server_status_alc
def main(): def main():
raw_msg = "server_status " + " ".join(sys.argv[1:]) raw_msg = "server_status " + " ".join(sys.argv[1:])
print(raw_msg)
arp = server_status_alc.parse(raw_msg) arp = server_status_alc.parse(raw_msg)
if arp.query("run"): if arp.query("run"):

View File

@ -6,6 +6,44 @@ from typing import Any
import psutil import psutil
import requests import requests
from server_status.timezone import get_timezone
excluded_partition_prefix = (
"/var",
"/boot",
"/run",
"/proc",
"/sys",
"/dev",
"/tmp",
"/snap",
"/System",
"/Applications",
"/private",
"/Library",
)
include_partition_prefix_mac = ("/Volumes")
os_name = "" # linux下为发行版名称windows下为Windows macOS下为Darwin
os_version = "" # linux下为发行版版本windows下为Windows版本
try:
# read /etc/os-release
with open("/etc/os-release") as f:
os_release = f.read()
# 找到NAME=和VERSION=的行
for line in os_release.split("\n"):
if line.startswith("NAME="):
os_name = line.split("=")[1].replace('"', "")
elif line.startswith("VERSION_ID="):
os_version = line.split("=")[1].replace('"', "")
except FileNotFoundError:
os_name = platform.system()
os_version = platform.release()
print("Current OS:", os_name, os_version)
def log(*args): def log(*args):
# 在输出前加上时间 # 在输出前加上时间
@ -25,6 +63,7 @@ def get_network_speed(interval) -> tuple[int, int]:
class Hardware: class Hardware:
os_release: str = ""
mem_total: int = psutil.virtual_memory().total mem_total: int = psutil.virtual_memory().total
mem_used: int = psutil.virtual_memory().used mem_used: int = psutil.virtual_memory().used
@ -37,6 +76,8 @@ class Hardware:
disks: dict[str, dict[str, int]] = {} disks: dict[str, dict[str, int]] = {}
timezone: str = get_timezone()
net_up: int = 0 net_up: int = 0
net_down: int = 0 net_down: int = 0
net_type: str = "ethernet" net_type: str = "ethernet"
@ -106,7 +147,9 @@ class Api:
""" """
self.headers.update(self.format(headers)) self.headers.update(self.format(headers))
def format(self, obj: str | list[str] | dict[str, Any]) -> str | list[str] | dict[str, Any]: def format(
self, obj: str | list[str] | dict[str, Any]
) -> str | list[str] | dict[str, Any]:
if isinstance(obj, str): if isinstance(obj, str):
obj = obj.format(**self.variables) obj = obj.format(**self.variables)
elif isinstance(obj, dict): elif isinstance(obj, dict):
@ -119,8 +162,17 @@ class Api:
class Client: class Client:
def __init__(self, addr: str, token: str, client_id: str, name: str = "", location: str = "", labels: list[str] = [], link: str = "", def __init__(
interval: int = 5): self,
addr: str,
token: str,
client_id: str,
name: str = "",
location: str = "",
labels: list[str] = [],
link: str = "",
interval: int = 2,
):
self.api = Api(addr, {"token": token, "id": client_id}) self.api = Api(addr, {"token": token, "id": client_id})
self.api = self.api.group("/client") self.api = self.api.group("/client")
self.api.add_headers(Authorization="{token}") self.api.add_headers(Authorization="{token}")
@ -134,15 +186,66 @@ class Client:
self.link = link self.link = link
self.interval = interval self.interval = interval
self.start_time: float = psutil.boot_time()
self.hardware = Hardware() self.hardware = Hardware()
log("Client initialized", log(
f"Name: {self.name}({self.client_id}), Location: {self.location}, Labels: {self.labels}") "Client initialized",
f"Name: {self.name}({self.client_id}), Location: {self.location}, Labels: {self.labels}",
)
def start(self): def start(self):
self.start_time = time.time() log("Starting client")
self.observe() threading.Thread(target=self._start_obs, daemon=True).start()
threading.Thread(target=self._start_post, daemon=True).start()
while True:
time.sleep(1)
def _start_obs(self):
"""启动监控记录线程"""
while True:
try:
self.hardware.mem_total = psutil.virtual_memory().total
self.hardware.mem_used = psutil.virtual_memory().used
self.hardware.swap_total = psutil.swap_memory().total
self.hardware.swap_used = psutil.swap_memory().used
self.hardware.cpu_cores = psutil.cpu_count(logical=False)
self.hardware.cpu_logics = psutil.cpu_count(logical=True)
for part in psutil.disk_partitions():
try:
usage = psutil.disk_usage(part.mountpoint)
if (
(
platform.system() in ("Linux", "Darwin")
and (
part.mountpoint.startswith(
excluded_partition_prefix
)
)
)
):
continue
self.hardware.disks[part.device] = {
"mountpoint": part.mountpoint,
"device": part.device,
"fstype": part.fstype,
"total": usage.total,
"used": usage.used,
}
except:
pass
self.hardware.cpu_percent = psutil.cpu_percent(1)
self.hardware.net_up, self.hardware.net_down = get_network_speed(1)
log("Observed")
except Exception as e:
log(f"Failed to observe: {e}")
def _start_post(self):
"""启动上报进程"""
while True: while True:
try: try:
resp = self.get_ping() resp = self.get_ping()
@ -150,9 +253,13 @@ class Client:
log(f"Connected to server {self.addr}") log(f"Connected to server {self.addr}")
break break
else: else:
log(f"Failed to connect to server {self.addr}, retrying in 5 seconds: {resp.text}") log(
f"Failed to connect to server {self.addr}, retrying in 5 seconds: {resp.text}"
)
except Exception as e: except Exception as e:
log(f"Failed to connect to server {self.addr}, retrying in 5 seconds: {e}") log(
f"Failed to connect to server {self.addr}, retrying in 5 seconds: {e}"
)
time.sleep(5) time.sleep(5)
while True: while True:
@ -179,14 +286,19 @@ class Client:
"id": self.client_id, "id": self.client_id,
"name": self.name, "name": self.name,
"os": { "os": {
"name": platform.system(), "name": platform.system(), # 系统类型 linux|windows|darwin
"version": platform.version(), "version": os_name + os_version,
# 系统版本复杂描述 #1 SMP PREEMPT_DYNAMIC Fri Sep 13 10:42:50 UTC 2024 (5c05eeb)
"machine": platform.machine(), # 机器类型 x86_64
"release": os_version, # 系统版本
}, },
"labels": self.labels, "labels": self.labels,
"location": self.location, "location": self.location,
"uptime": int(time.time() - self.start_time), "uptime": int(time.time() - self.start_time),
"start_time": int(self.start_time), # 系统启动的时间
"link": self.link, "link": self.link,
"observed_at": int(time.time()), "observed_at": int(time.time()),
"timezone": self.hardware.timezone,
}, },
"hardware": { "hardware": {
"mem": { "mem": {
@ -211,35 +323,5 @@ class Client:
}, },
} }
def observe(self):
"""
观察硬件状态并更新
Returns:
"""
def _observe():
while True:
self.hardware.mem_total = psutil.virtual_memory().total
self.hardware.mem_used = psutil.virtual_memory().used
self.hardware.swap_total = psutil.swap_memory().total
self.hardware.swap_used = psutil.swap_memory().used
self.hardware.cpu_cores = psutil.cpu_count()
self.hardware.cpu_logics = psutil.cpu_count(logical=True)
for part in psutil.disk_partitions():
try:
usage = psutil.disk_usage(part.mountpoint)
self.hardware.disks[part.device] = {
"total": usage.total,
"used": usage.used,
}
except:
pass
self.hardware.cpu_percent = psutil.cpu_percent(1)
self.hardware.net_up, self.hardware.net_down = get_network_speed(1)
log("Observed")
threading.Thread(target=_observe, daemon=True).start()
def remove(self, client_id) -> requests.Response: def remove(self, client_id) -> requests.Response:
return self.api.delete("/host", data={"id": client_id}) return self.api.delete("/host", data={"id": client_id})

View File

@ -3,7 +3,7 @@ import socket
from arclet.alconna import Alconna, Subcommand, Option, Args, MultiVar from arclet.alconna import Alconna, Subcommand, Option, Args, MultiVar
server_status_alc = Alconna( server_status_alc = Alconna( # type: ignore
"server_status", "server_status",
Args["server", str]["token", str]["id", str], Args["server", str]["token", str]["id", str],
Subcommand( Subcommand(

136
server_status/timezone.py Normal file
View File

@ -0,0 +1,136 @@
import os
import platform
from zoneinfo import ZoneInfo
windows_timezone_map = {
"Dateline Standard Time": "Etc/GMT+12",
"UTC-11": "Etc/GMT+11",
"Aleutian Standard Time": "America/Adak",
"Hawaiian Standard Time": "Pacific/Honolulu",
"Marquesas Standard Time": "Pacific/Marquesas",
"Alaskan Standard Time": "America/Anchorage",
"UTC-09": "Etc/GMT+9",
"Pacific Standard Time (Mexico)": "America/Tijuana",
"UTC-08": "Etc/GMT+8",
"Pacific Standard Time": "America/Los_Angeles",
"US Mountain Standard Time": "America/Phoenix",
"Mountain Standard Time (Mexico)": "America/Chihuahua",
"Mountain Standard Time": "America/Denver",
"Central America Standard Time": "America/Guatemala",
"Central Standard Time": "America/Chicago",
"Easter Island Standard Time": "Pacific/Easter",
"Central Standard Time (Mexico)": "America/Mexico_City",
"Canada Central Standard Time": "America/Regina",
"SA Pacific Standard Time": "America/Bogota",
"Eastern Standard Time (Mexico)": "America/Cancun",
"Eastern Standard Time": "America/New_York",
"Haiti Standard Time": "America/Port-au-Prince",
"Cuba Standard Time": "America/Havana",
"US Eastern Standard Time": "America/Indianapolis",
"Turks And Caicos Standard Time": "America/Grand_Turk",
"Paraguay Standard Time": "America/Asuncion",
"Atlantic Standard Time": "America/Halifax",
"Venezuela Standard Time": "America/Caracas",
"Central Brazilian Standard Time": "America/Cuiaba",
"SA Western Standard Time": "America/La_Paz",
"Pacific SA Standard Time": "America/Santiago",
"SA Eastern Standard Time": "America/Cayenne",
"Argentina Standard Time": "America/Buenos_Aires",
"Greenland Standard Time": "America/Godthab",
"Montevideo Standard Time": "America/Montevideo",
"Bahia Standard Time": "America/Bahia",
"UTC-02": "Etc/GMT+2",
"Azores Standard Time": "Atlantic/Azores",
"Cape Verde Standard Time": "Atlantic/Cape_Verde",
"UTC": "Etc/GMT",
"GMT Standard Time": "Europe/London",
"Greenwich Standard Time": "Atlantic/Reykjavik",
"W. Europe Standard Time": "Europe/Berlin",
"Central Europe Standard Time": "Europe/Budapest",
"Romance Standard Time": "Europe/Paris",
"Central European Standard Time": "Europe/Warsaw",
"W. Central Africa Standard Time": "Africa/Lagos",
"Namibia Standard Time": "Africa/Windhoek",
"GTB Standard Time": "Europe/Bucharest",
"Middle East Standard Time": "Asia/Beirut",
"Egypt Standard Time": "Africa/Cairo",
"Syria Standard Time": "Asia/Damascus",
"E. Europe Standard Time": "Europe/Chisinau",
"South Africa Standard Time": "Africa/Johannesburg",
"FLE Standard Time": "Europe/Kiev",
"Turkey Standard Time": "Europe/Istanbul",
"Israel Standard Time": "Asia/Jerusalem",
"Jordan Standard Time": "Asia/Amman",
"Arabic Standard Time": "Asia/Riyadh",
"Kaliningrad Standard Time": "Europe/Kaliningrad",
"Arab Standard Time": "Asia/Riyadh",
"E. Africa Standard Time": "Africa/Nairobi",
"Iran Standard Time": "Asia/Tehran",
"Arabian Standard Time": "Asia/Dubai",
"Astrakhan Standard Time": "Europe/Astrakhan",
"Russian Standard Time": "Europe/Moscow",
"E. Europe Standard Time": "Europe/Chisinau",
"W. Australia Standard Time": "Australia/Perth",
"Moscow Standard Time": "Europe/Moscow",
"Pakistan Standard Time": "Asia/Karachi",
"India Standard Time": "Asia/Kolkata",
"Sri Lanka Standard Time": "Asia/Colombo",
"Nepal Standard Time": "Asia/Kathmandu",
"Bangladesh Standard Time": "Asia/Dhaka",
"Afghanistan Standard Time": "Asia/Kabul",
"Myanmar Standard Time": "Asia/Yangon",
"SE Asia Standard Time": "Asia/Bangkok",
"North Asia Standard Time": "Asia/Krasnoyarsk",
"China Standard Time": "Asia/Shanghai",
"Singapore Standard Time": "Asia/Singapore",
"W. Australia Standard Time": "Australia/Perth",
"Taipei Standard Time": "Asia/Taipei",
"Ulaanbaatar Standard Time": "Asia/Ulaanbaatar",
"North Asia East Standard Time": "Asia/Irkutsk",
"Korea Standard Time": "Asia/Seoul",
"Tokyo Standard Time": "Asia/Tokyo",
"Yakutsk Standard Time": "Asia/Yakutsk",
"Cen. Australia Standard Time": "Australia/Adelaide",
"AUS Central Standard Time": "Australia/Darwin",
"E. Australia Standard Time": "Australia/Brisbane",
"AUS Eastern Standard Time": "Australia/Sydney",
"West Pacific Standard Time": "Pacific/Port_Moresby",
"Tasmania Standard Time": "Australia/Hobart",
"Magadan Standard Time": "Asia/Magadan",
"Vladivostok Standard Time": "Asia/Vladivostok",
"Russia Time Zone 10": "Asia/Srednekolymsk",
"Central Pacific Standard Time": "Pacific/Guadalcanal",
"Fiji Standard Time": "Pacific/Fiji",
"New Zealand Standard Time": "Pacific/Auckland",
"UTC+12": "Etc/GMT-12",
"Kamchatka Standard Time": "Asia/Kamchatka",
"Tonga Standard Time": "Pacific/Tongatapu",
"Samoa Standard Time": "Pacific/Apia",
"Line Islands Standard Time": "Pacific/Kiritimati",
}
def get_timezone() -> str:
try:
# 尝试获取系统的本地时区
if 'TZ' in os.environ:
return os.environ['TZ']
# 如果环境变量中没有TZ尝试获取系统时区
if platform.system() == "Linux":
# Linux:
with open("/etc/timezone", "r") as f:
return f.read().strip()
elif platform.system() == "Darwin":
# macOS:
return ZoneInfo.from_file(open("/etc/localtime")).key
elif platform.system() == "Windows":
# Windows:
import winreg
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation") as key:
tz = winreg.QueryValueEx(key, "TimeZoneKeyName")[0]
return windows_timezone_map.get(tz) or tz
else:
return "UTC"
except Exception as e:
return "UTC"