Skip to content

Commit 97122d2

Browse files
authored
Merge pull request #7 from TTB-Network/dev/config
🎨 重构部分代码
2 parents 7387ec4 + 21c7682 commit 97122d2

File tree

13 files changed

+102
-101
lines changed

13 files changed

+102
-101
lines changed

.gitignore

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
<<<<<<< HEAD
21
container/.ssl/
32
container/bmclapi/
43
container/cache/
54
container/config/
65
container/__pycache__/
76
.vscode/
8-
.lh/
9-
test/
10-
=======
117
config/config.properties
128
__pycache__
139
.venv
14-
>>>>>>> 1821e9a699e53437109088d3d8cf4bb4a1bf9a50
10+
logs
11+
config/config.yaml
12+
bmclapi
13+
bmclapi_dashboard
14+
cache

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ WORKDIR /python-openbmclapi
1010
ADD . .
1111

1212
RUN pip install -r requirements.txt --no-deps
13-
VOLUME /python-openbmclapi/cache
14-
ENV web_port=8080
13+
VOLUME /python-openbmclapi/bmclapi
14+
ENV web_port=8800
1515
EXPOSE $web_port
1616
CMD ["python", "./container/main.py"]

README.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
🎉 __*新增功能!*__基于 Echart 的 OpenBMCLAPI 仪表盘(Dashboard)。
2222

23+
🎉 __*新增功能!*__基于 loguru 的**日志器**
24+
25+
2326
</div>
2427

2528
# 简介
@@ -53,7 +56,7 @@
5356
python ./container/main.py
5457
```
5558

56-
4. 在 `config.properties` 中,填写你的 `cluster.id`(即 `CLUSTER_ID`)和 `cluster.secret`(即 `CLUSTER_SECRET`)。
59+
4. 在 `config.yaml` 中,填写你的 `cluster_id`(即 `CLUSTER_ID`)和 `cluster_secret`(即 `CLUSTER_SECRET`)。
5760

5861
5. 重新启动程序。
5962

@@ -69,8 +72,8 @@
6972

7073
```sh
7174
docker run -d \
72-
-v ${/data/python-openbmclapi}:/python-openbmclapi/container/cache \
73-
-v ${/path/to/your/config}:/python-openbmclapi/config/config.properties \
75+
-v ${/data/python-openbmclapi}:/python-openbmclapi/bmclapi \
76+
-v ${/path/to/your/config}:/python-openbmclapi/config/config.yaml \
7477
-p ${web.port}:${web.port} \
7578
--restart always \
7679
--name python-openbmclapi \
@@ -81,9 +84,23 @@
8184

8285
`web.port` - 对外开放的端口。
8386

84-
`/path/to/your/config` - 配置文件(你需要从此仓库中下载 `config/config.properties.example` 并重命名为 `config.properties` 来进行配置)的存放路径。
87+
`/path/to/your/config` - 配置文件(你需要从此仓库中下载 `config/config.yaml.example` 并重命名为 `config.yaml` 来进行配置)的存放路径。
88+
89+
`/data/python-openbmclapi` - `bmclapi` 文件夹(即缓存 `cache` 文件夹)挂载的路径。
90+
91+
# 配置文件
92+
93+
```yaml
94+
byoc: ''
95+
cluster_id: ''
96+
cluster_secret: ''
97+
download_threads: 64
98+
timeout: 30
99+
web_host: ''
100+
web_port: 8800
101+
web_publicport: 8800
85102
86-
`/data/python-openbmclapi` - `cache` 文件夹挂载的路径。
103+
```
87104

88105
# 鸣谢
89106

config/config.properties.example

Lines changed: 0 additions & 8 deletions
This file was deleted.

config/config.yaml.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
byoc: false
2+
cluster_id: ''
3+
cluster_secret: ''
4+
download_threads: 64
5+
timeout: 30
6+
web_host: ''
7+
web_port: 8800
8+
web_publicport: 8800

container/bmclapi_dashboard/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta http-equiv="X-UA-Compatible" content="IE=edge">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<meta charset="utf-8"/>
8-
<title>OPENBMCLAPI - TTB Network</title>
8+
<title>Python OpenBMCLAPI Dashboard</title>
99
</head>
1010
<body>
1111
</body>

container/bmclapi_dashboard/static/js/index.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const calc_more_bytes = (...values) => {
7777
".container .vcmp-status-bar:hover":"color: #8dcffc;",
7878
".container .vcmp-status-online":"width: 12px;height: 12px;border-radius: 50%;background-color: #0FC6C2;margin: 8px;",
7979
".container .vcmp-status-offline":"width: 12px;height: 12px;border-radius: 50%;background-color: rgba(0, 0, 0, 0.5);margin: 8px;margin-right: 0;",
80+
"h1, h2, h3":"font-family: Microsoft Yahei UI"
8081
}
8182
set_styles(default_styles)
8283
Extendi18nSets("zh_cn", {
@@ -266,10 +267,7 @@ const calc_more_bytes = (...values) => {
266267
ExtendFlex().append(
267268
ExtendFlex().css("domain", "extend-flex-auto").append(
268269
ExtendElement("span").append(
269-
ExtendElement("h2").text("Python OpenBMCLAPI Dashboard").valueOf(),
270-
ExtendElement("span").text("Built by ").append(
271-
ExtendElement("a").text("TTB Network").setAttr("href", "https://github.com/TTB-Network/python-openbmclapi/").valueOf()
272-
).id("dashboard-geo").valueOf()
270+
ExtendElement("h3").text("Python OpenBMCLAPI Dashboard").valueOf(),
273271
).valueOf(),
274272
).valueOf(),
275273
).css("header-bar").valueOf(),

container/cluster.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
from dataclasses import dataclass
3-
import glob
43
import hashlib
54
import hmac
65
import io
@@ -18,6 +17,8 @@
1817
import utils
1918
import stats
2019
import web
20+
from logger import logger
21+
from tqdm import tqdm
2122

2223
PY_VERSION = "1.0.0"
2324
VERSION = "1.9.7"
@@ -60,7 +61,7 @@ async def fetchToken(self):
6061
Timer.delay(self.fetchToken, delay=float(content['ttl']) / 1000.0 - 600)
6162

6263
except aiohttp.ClientError as e:
63-
print(f"Error fetching token: {e}")
64+
logger.error(f"Error fetching token: {e}.")
6465
async def getToken(self) -> str:
6566
if not self.token:
6667
await self.fetchToken()
@@ -120,29 +121,30 @@ async def download(self, session: aiohttp.ClientSession):
120121
self.download_bytes.add(-size)
121122
await self.files.put(file)
122123
async def check_file(self):
123-
print("Requesting files...")
124+
logger.info("Requesting filelist...")
124125
filelist = await self.get_file_list()
125126
filesize = sum((file.size for file in filelist))
126127
total = len(filelist)
127128
byte = 0
128129
miss = []
130+
pbar = tqdm(total=total, unit=' file(s)', unit_scale=True)
131+
pbar.set_description("Checking files")
129132
for i, file in enumerate(filelist):
130133
filepath = str(self.dir) + f"/{file.hash[:2]}/{file.hash}"
131134
if not os.path.exists(filepath) or os.path.getsize(filepath) != file.size:
132135
miss.append(file)
133136
...
134137
await asyncio.sleep(0)
135138
byte += file.size
136-
b = utils.calc_more_bytes(byte, filesize)
137-
print(f"<<<flush>>>Check file {i}/{total} ({b[0]}/{b[1]})")
139+
pbar.update(1)
138140
if not miss:
139-
print(f"<<<flush>>>Checked all files!")
141+
logger.info("Checked all files!")
140142
await self.start_service()
141143
return
142144
filelist = miss
143145
filesize = sum((file.size for file in filelist))
144146
total = len(filelist)
145-
print(f"<<<flush>>>Missing files: {total}({utils.calc_bytes(filesize)})")
147+
logger.info(f"Missing files: {total}({utils.calc_bytes(filesize)}).")
146148
for file in filelist:
147149
await self.files.put(file)
148150
self.download_bytes = utils.Progress(5, filesize)
@@ -154,16 +156,17 @@ async def check_file(self):
154156
"User-Agent": UA,
155157
"Authorization": f"Bearer {await token.getToken()}"
156158
}), )))
159+
pbar = tqdm(total=total, unit=' file(s)', unit_scale=True)
160+
pre = 0
157161
while any([not timer.called for timer in timers]):
158162
b = utils.calc_more_bytes(self.download_bytes.get_cur(), filesize)
159163
bits = self.download_bytes.get_cur_speeds() or [0]
160164
minbit = min(bits)
161165
bit = utils.calc_more_bit(minbit, bits[-1], max(bits))
162-
eta = self.download_bytes.get_eta()
163-
print(f"<<<flush>>>Downloading files... {self.download_files.get_cur()}/{total} {b[0]}/{b[1]}, eta: {utils.format_time(eta if eta != -1 else None)}, total: {utils.format_time(self.download_bytes.get_total())}, Min: {bit[0]}, Cur: {bit[2]}, Max: {bit[1]}, Files: {self.download_files.get_cur_speed()}/s")
166+
pbar.set_description(f"Downloading files | Curent speed: {bit[2]}")
164167
await asyncio.sleep(1)
165-
for timer in timers:
166-
del timer
168+
pbar.update(self.download_files.get_cur() - pre)
169+
pre = self.download_files.get_cur()
167170
await self.start_service()
168171
async def start_service(self):
169172
tokens = await token.getToken()
@@ -185,11 +188,11 @@ async def enable(self):
185188
if not web.get_ssl() and not (Path(".ssl/cert.pem").exists() and Path(".ssl/key.pem").exists()):
186189
await self.emit("request-cert")
187190
self.cur_counter = stats.Counters()
188-
print("Connected Main Server.")
191+
logger.info("Connected to the Main Server.")
189192
async def message(self, type, data):
190193
if type == "request-cert":
191194
cert = data[1]
192-
print("Requested cert!")
195+
logger.info("Requested cert!")
193196
cert_file = Path(".ssl/cert.pem")
194197
key_file = Path(".ssl/key.pem")
195198
for file in (cert_file, key_file):
@@ -206,9 +209,9 @@ async def message(self, type, data):
206209
self.keepalive.block()
207210
self.keepalive = Timer.delay(self.keepaliveTimer, (), 5)
208211
if len(data) == 2 and data[1] == True:
209-
print("Checked! Can service")
212+
logger.info("Checked! Starting the service")
210213
return
211-
print("Error:" + data[0]['message'])
214+
logger.error("Error:" + data[0]['message'])
212215
Timer.delay(self.enable)
213216
elif type == "keep-alive":
214217
COUNTER.hit -= self.cur_counter.hit
@@ -234,7 +237,7 @@ async def get_file_list(self):
234237
"cache": ""
235238
}) as req:
236239
req.raise_for_status()
237-
print("Requested files")
240+
logger.info("Requested filelist.")
238241

239242
parser = avro_io.DatumReader(schema.parse(
240243
'''

container/config.py

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,39 @@
11
from pathlib import Path
2+
import yaml
3+
from typing import Union
24

5+
class CFG:
6+
def __init__(self, path: str) -> None:
7+
self.file = Path(path)
8+
self.cfg = {}
9+
if self.file.exists():
10+
self.load()
311

4-
class Property:
5-
def __init__(self, config: str, exists_ok: bool = True) -> None:
6-
self.file = Path(config)
7-
self.properties = {}
8-
if self.file.exists():
9-
self.parse_file()
10-
self.exists_ok = exists_ok
11-
12-
def parse_file(self):
12+
def load(self):
1313
with open(self.file, "r", encoding="utf-8") as f:
14-
for line in f.readlines():
15-
line = line.strip()
16-
if not line or line.startswith('#'):
17-
continue
18-
key, value = line.split('=', 1)
19-
value = value.strip('"')
20-
self.properties[key] = value
21-
def set(self, key, value):
22-
self.properties[key] = str(value)
14+
self.cfg = yaml.load(f.read(), Loader=yaml.FullLoader)
2315

24-
def get(self, key, default=None):
25-
val = self.properties.get(key, None)
26-
if not self.exists_ok and val is None:
27-
self.set(key, default or "")
28-
self.save()
29-
return val or str(default)
30-
def getBoolean(self, key, def_: bool = False):
31-
val = self.get(key, def_)
32-
return val.lower() in ("true", "1", "t", "yes", "y")
33-
def getInteger(self, key, def_: int = 0):
34-
val = self.get(key, def_)
35-
return int(val) if val.isnumeric() else def_
36-
def __getitem__(self, key):
37-
return self.properties.get(key)
38-
def __setitem__(self, key, value):
39-
self.set(key, value)
40-
41-
def save(self):
42-
sorted_dict = sorted(self.properties.items())
43-
self.file.parent.mkdir(exist_ok=True, parents=True)
44-
with open(self.file, 'w', encoding="utf-8") as file:
45-
for key, value in sorted_dict:
46-
if "\n" in value:
47-
value = f'"{value}"'
48-
file.write(f"{key}={value}\n")
16+
def get(self, key, default_):
17+
value = self.cfg.get(key, default_)
18+
if value is None:
19+
self.write(key, default_)
20+
return value
4921

50-
Config: Property = Property("./config/config.properties", False)
22+
def write(self, key, value):
23+
self.cfg[key] = value
24+
with open(self.file, "w", encoding="utf-8") as f:
25+
yaml.dump(data=self.cfg, stream=f, allow_unicode=True)
5126

52-
CLUSTER_ID = Config.get("cluster.id", None) or ""
53-
CLUSTER_SECRET = Config.get("cluster.secret", None) or ""
54-
MAX_DOWNLOAD = Config.getInteger("download.threads", 64)
55-
PORT = Config.getInteger("web.port", 8800)
56-
PUBLICPORT = Config.getInteger("web.publicport", 8800)
57-
PUBLICHOST = Config.get("web.host", "")
58-
BYOC = False
59-
TIMEOUT = 30
27+
Config: CFG = CFG("./config/config.yaml")
28+
29+
CLUSTER_ID: str = Config.get("cluster_id", "")
30+
CLUSTER_SECRET: str = Config.get("cluster_secret", "")
31+
MAX_DOWNLOAD: int = Config.get("download_threads", 64)
32+
PORT: int = Config.get("web_port", 8800)
33+
PUBLICPORT: int = Config.get("web_publicport", 8800)
34+
PUBLICHOST: int = Config.get("web_host", "")
35+
BYOC: bool = Config.get("byoc", False)
36+
TIMEOUT: int = Config.get("timeout", 30)
6037
MIN_RATE_TIMESTAMP = 1000
6138
MIN_RATE = 500
6239
REQUEST_BUFFER = 1024 * 8

container/logger.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from loguru import logger
2+
from pathlib import Path
3+
4+
logger.add(Path("./logs/{time}.log"), rotation="3 hours")

container/timer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import inspect
33
import time
44
import traceback
5+
from logger import logger
56

67

78
class Task:
@@ -44,15 +45,15 @@ def block(self):
4445
self.blocked = True
4546
async def callback_error(self):
4647
if not self.error:
47-
print(traceback.format_exc())
48+
logger.debug(traceback.format_exc())
4849
return
4950
try:
5051
if inspect.iscoroutinefunction(self.error):
5152
await self.error()
5253
else:
5354
self.error()
5455
except:
55-
print(traceback.format_exc())
56+
logger.debug(traceback.format_exc())
5657
class TimerManager:
5758
def delay(self, target, args = (), delay: float = 0, callback = None):
5859
task = Task(target=target, args=args, delay=delay, back=callback)

0 commit comments

Comments
 (0)